
var Jp_AttractMode = new Class({
	Implements: [Options, Events],
	trigger: null,
	block: null,
	parent: null,
	hFx: null,
	oFx: null,
	active: true,
	triggerCopy: null,
	blockBottomMargin: 0,
	originalHeight: 0,
	options: {
		closeLabel: 'Close',
		openLabel: 'Open',
		startClosed: false,
		duration: 150,
		cookieName: 'jpBannerState',
		classToHide: 'data'
	},
	initialize: function(options) {
		this.addOptions(options);
		this.checkState();
	},
	addOptions: function(options) {
		this.setOptions(options);
	},
	start: function(trigger, block) {
		this.block = $(block);
		if (this.block) {
			this.parent = this.block.getParent();
		}
		if (!trigger) {
			this.createCloseButton();
		}
		else {
			this.trigger = $(trigger);
		}
		if (!this.trigger || !this.block) {
			return;
		}
		
		var isClosed = false;
		if (this.block.getStyle('display') == 'none') {
			this.block.setStyle('display', 'block');
			isClosed = true;
		}
		
		this.triggerCopy = this.trigger.get('html');
		this.blockBottomMargin = this.block.getStyle('margin-bottom');
		this.originalHeight = this.block.getSize().y;
		
		if (isClosed) {
			this.block.setStyle('height', '0');
			if (!/MSIE\s6/.test(navigator.userAgent)) {
				this.block.setStyle('opacity', '0');
			}
		}
		
		this.trigger.setStyles({
			outline: 'none'
		});
		
		this.setEvents();
		
//		if (this.options.startClosed) {
		if (this.getInitialState() == 0) {
			this.fireEvent('hide');
		}
		else {
			this.fireEvent('open');
		}
	},
	createCloseButton: function() {
		if (this.parent) {
			var p = new Element('p', {'class': 'toggle'});
			var a = new Element('a', {href: 'Javascript:;', html: this.options.closeLabel});
			a.inject(p);
			p.inject(this.parent, 'top');
			this.trigger = a;
		}
	},
	setEvents: function() {
		this.addEvent('onHide', function(evt) {this.hide();}.bindWithEvent(this));
		this.addEvent('onOpen', function(evt) {this.open();}.bindWithEvent(this));
		
		this.trigger.addEvent('click', function(evt) {
			evt.stop();
			this.toggle();
		}.bindWithEvent(this));
	},
	toggle: function() {
		if (this.hFx) this.hFx.cancel();
		if (this.oFx) this.oFx.cancel();
		
		if (!this.active) { //reveal
			this.fireEvent('open');
		}
		else { //hide
			this.fireEvent('hide');
		}
	},
	open: function() {
		this.active = true;
		var currentHeigth = parseInt(this.block.getStyle('height'));
		var currentOpacity = this.block.getStyle('opacity');
		
		if (!/MSIE\s6/.test(navigator.userAgent)) {
			var options = this.options;
			options.property = 'opacity';
			this.oFx = new Fx.Tween(this.block, options).start(currentOpacity, 1);
		}
		var options = this.options;
		options.property = 'height';
		this.hFx = new Fx.Tween(this.block, options).start(currentHeigth, this.originalHeight);
		
		this.trigger.set('html', this.options.closeLabel);
		this.parent.removeClass('closed');
		this.block.setStyle('margin-bottom', this.blockBottomMargin);
		
		this.saveState(1);
	},
	hide: function() {
		this.active = false;
		var currentHeigth = parseInt(this.block.getStyle('height'));
		var currentOpacity = this.block.getStyle('opacity');
		
		if (!/MSIE\s6/.test(navigator.userAgent)) {
			var options = this.options;
			options.property = 'opacity';
			this.oFx = new Fx.Tween(this.block, options).start(currentOpacity, 0);
		}
		var options = this.options;
		options.property = 'height';
		this.hFx = new Fx.Tween(this.block, options).start(currentHeigth, 0);
		
		this.trigger.set('html', this.options.openLabel);
		this.parent.addClass('closed');
		this.block.setStyle('margin-bottom', 0);
		
		this.saveState(0);
	},
	saveState: function(value) {
		//0 is closed, 1 is open
		var state = this.retrieveState();
		state.set('currentState', value);
		state.set(this.getCurrentStateKey(), value);
		var updatedByClient = state.get('updatedByClient');
		if (updatedByClient == null) {
			state.set('updatedByClient', 0);
		}
		else if (updatedByClient == 0) {
			state.set('updatedByClient', 1);
		}
		Cookie.write(this.options.cookieName, this.serialize(state), {path: '/'});
//		Cookie.write(this.options.cookieName, value, {path: '/'});
	},
	getCurrentState: function() {
		var state = this.retrieveState();
		var currentState = state.get('currentState');
		return currentState != null ? state.currentState : (this.options.startClosed ? 0 : 1);
//		return Cookie.read(this.options.cookieName);
	},
	//state to start with
	getInitialState: function() {
		var state = this.retrieveState();
		var key = this.getCurrentStateKey();
//		return state.get(key) != null ? state.get(key) : (this.options.startClosed ? 0 : 1);
		//if the client has already visited the page, return the client's last state.
		//Otherwise, return default state.
//		return state.get(key) != null ? state.get('currentState') : (this.options.startClosed ? 0 : 1);
		var updatedByClient = state.get('updatedByClient');
		return updatedByClient != null  && updatedByClient != 0 ? state.get('currentState') : (this.options.startClosed ? 0 : 1);
	},
	retrieveState: function() {
		//read cookie and parse it into a Hash
		state = Cookie.read(this.options.cookieName);
		return this.unserialize(state);
	},
	//serialize a h (pair of key/attributes only): 'key1:attribute1,key2:attribute2'
	serialize: function(h) {
		var serialized = '';
		h.each(function(value, key) {
			serialized += key + ':' + value + ',';
		}, this);
		serialized = serialized.substr(0, serialized.length - 1);
		return serialized;
	},
	unserialize: function(s) {
		var unserialized = new Hash();
		if (typeof s == 'string') {
			var attributes = s.split(',');
			for (var i = 0; i < attributes.length; i++) {
				var keyAndValue = attributes[i].split(':');
				if (keyAndValue.length == 2) {
					unserialized.set(keyAndValue[0], keyAndValue[1]);
				}
			}
		}
		return unserialized;
	},
	getCurrentStateKey: function() {
		var key = window.location.toString().split('?')[0].split('#')[0];
		key = key.replace(/[^a-z0-9\-_]/ig, '');
		key = key.replace(/index(html|php)$/, '');
		return key;
	},
	checkState: function() {
		if (this.getCurrentState() == 0) {
			//will start closed
			document.write('<style type="text/css">.' + this.options.classToHide + ' {display: none;}</style>');
		}
	}
});
