/**
 * PresentationsManager.js (Presentation classes)
 *
 * @version: 1.0
 * @author: WGU Team (www.web-go-up.com)
 *
 * @TODO: Redesign without Mootools
 * @TODO: more robust testing!!!
 */

var PresentationsManager = new Class({
	Implements: [Options, Events],

	options: {
		'selector':				'presentation',
		'autoStartRotation':	true,
		'rotationSpeed':		3000
	},

	initialize: function(options) {
		this.setOptions(options);

		this.presentations	= [];

		this.attachDefaultPresentations();
	},

	attach: function(options) {
		if (options.container) {
			options	= $merge(this.options, options);
			delete options.selector;

			this.presentations.push(new PresentationsManager.Presentation(options));
		}

		return this;
	},

	detach: function(container) {
		if (container) {
			var p	= $(container).retrieve('presentation');

			if (p) {
				this.presentations.splice(this.presentations.indexOf(p), 1);

				p.destroy();

				p	= null;
			}
		}

		return this;
	},

	start: function() {
		var pres = null, i = 0;
		while (pres = this.presentations[i]) {
			pres.start();
			++i;
		}
	},

	stop: function() {
		var pres = null, i = 0;
		while (pres = this.presentations[i]) {
			pres.stop();
			++i;
		}
	},

	getPresentationByContainer: function(container) {
		return $(container).retrieve('presentation');
	},

	attachDefaultPresentations: function() {
		$$('.' + this.options.selector).each(function(el) {
			if (!el.retrieve('presentation')) {
				this.attach($merge(this.parseParametersFromTitle(el), { 'container': el }));
			}
		}, this);

		return this;
	},

	getSelector: function() {
		return this.options.selector;
	},

	setSelector: function(value) {
		this.options.selector = value;

		return this;
	},

	getAutoStartRotation: function() {
		return this.options.autoStartRotation;
	},

	setAutoStartRotation: function(value) {
		this.options.autoStartRotation	= value;

		var pres = null, i = 0;
		while (pres = this.presentations[i]) {
			pres.setAutoStartRotation(value);
			++i;
		}

		return this;
	},

	getRotationSpeed: function() {
		return this.options.rotationSpeed;
	},

	setRotationSpeed: function(value) {
		this.options.rotationSpeed	= value;

		var pres = null, i = 0;
		while (pres = this.presentations[i]) {
			pres.setRotationSpeed(value);
			++i;
		}

		return this;
	},

	/**
	 * Private function!
	 */
	parseParametersFromTitle: function(el) {
		var title, start, end, params;

		if (title = el.get('title')) {
			if ((start = title.indexOf('::')) != -1) {
				end = title.lastIndexOf('::');
				params = title.substring(start + 2, end);
				el.set('title', title.substring(0, start));
				params = JSON.decode("{" + params.replace(/'/g, '"') + "}");

				return params;
			}
			return null;
		}
		return null;
	}
});

PresentationsManager.Presentation = new Class({
	Implements: [Options, Events],

	options: {
		'container':			null,
		'autoStartRotation':	true,
		'rotationSpeed':		3000
	},

	initialize: function(options) {
		this.setOptions(options);

		this.options.container					= $(this.options.container);

		this.options.container.store('presentation', this);

		// private properties

		this.itemsHolder						= null;
		this.thumbsHolder						= null;
		this.items								= [];
		this.thumbs								= [];
		this.currentItem						= 0;
		this.currentLeftThumb					= 0;
		this.nextItem							= 0;
		this.nextThumb							= 0;
		this.rotationTimer						= null;
		this.thumbsScrollPrev					= null;
		this.thumbsScrollNext					= null;
		this.thumbsScrollPrevPressed			= false;
		this.thumbsScrollNextPressed			= false;
		this.rotateToNextItemBound				= this.rotateToNextItem.bind(this);
		this.onThumbsScrollEffectStartBound		= this.onThumbsScrollEffectStart.bind(this);
		this.onThumbsScrollEffectCompleteBound	= this.onThumbsScrollEffectComplete.bind(this);
		this.onThumbClickBound					= this.onThumbClick.bind(this);
		this.onThumbMouseOverBound				= this.onThumbMouseOver.bind(this);
		this.onThumbMouseOutBound				= this.onThumbMouseOut.bind(this);
		this.onThumbsScrollPrevMouseDownBound	= this.onThumbsScrollPrevMouseDown.bind(this);
		this.onThumbsScrollPrevMouseUpBound		= this.onThumbsScrollPrevMouseUp.bind(this);
		this.onThumbsScrollPrevMouseOutBound	= this.onThumbsScrollPrevMouseOut.bind(this);
		this.onThumbsScrollNextMouseDownBound	= this.onThumbsScrollNextMouseDown.bind(this);
		this.onThumbsScrollNextMouseUpBound		= this.onThumbsScrollNextMouseUp.bind(this);
		this.onThumbsScrollNextMouseOutBound	= this.onThumbsScrollNextMouseOut.bind(this);

		// visual components

		this.initElements();

		this.initEvents();

		this.itemsScrollEffect					= new Fx.Scroll(this.itemsHolder, {
			'link':			'cancel',
			'transition':	'linear'
		});
		this.thumbsScrollEffect					= new Fx.Scroll(this.thumbsHolder, {
			'link':			'cancel',
			'transition':	'linear',
			'onStart':		this.onThumbsScrollEffectStartBound,
			'onComplete':	this.onThumbsScrollEffectCompleteBound
		});

		if (this.options.autoStartRotation) {
			this.start();
		}
	},

	destroy: function() {
		this.stop();

		this.items.each(function(el) {
			el.removeEvents();
			el.destroy();
		});
		this.items.empty();

		this.thumbs.each(function(el) {
			el.removeEvents();
			el.destroy();
		});
		this.thumbs.empty();

		this.options.container.store('presentation', null);
		this.options.container.destroy();

		this.itemsHolder						=
		this.thumbsHolder						=
		this.items								=
		this.thumbs								=
		this.rotationTimer						=
		this.thumbsScrollPrev					=
		this.thumbsScrollNext					=
		this.rotateToNextItemBound				=
		this.onThumbsScrollEffectCompleteBound	=
		this.onItemsScrollEffectCompleteBound	=
		this.onThumbClickBound					=
		this.onThumbMouseOverBound				=
		this.onThumbMouseOutBound				=
		this.onThumbsScrollPrevMouseDownBound	=
		this.onThumbsScrollPrevMouseUpBound		=
		this.onThumbsScrollPrevMouseOutBound	=
		this.onThumbsScrollNextMouseDownBound	=
		this.onThumbsScrollNextMouseUpBound		=
		this.onThumbsScrollNextMouseOutBound	=
		this.itemsScrollEffect					=
		this.thumbsScrollEffect					= null;

		return this;
	},

	start: function() {
		this.rotationTimer	= this.rotateToNextItemBound.periodical(this.options.rotationSpeed);

		return this;
	},

	stop: function() {
		this.rotationTimer	= $clear(this.rotationTimer);

		return this;
	},

	showItem: function(item) {
		if ($type(item) != 'number') {
			item	= (this.items.indexOf(item) != -1) ? this.items.indexOf(item) : 0;
		}

		if ((item >= 0) && (item < this.items.length)) {
			//this.itemsScrollEffect.toElement(this.items[item]);
			this.itemsScrollEffect.start(this.items[item].getPosition(this.itemsHolder.getFirst()).x, 0);
			this.showThumb(item, true);

			this.currentItem	= item;
		}
	},

	showThumb: function(thumb, select) {
		if ($type(thumb) != 'number') {
			thumb	= (this.thumbs.indexOf(thumb) != -1) ? this.thumbs.indexOf(thumb) : 0;
		}
		if (typeof(select) == 'undefined') {
			select	= false;
		}

		if ((thumb >= 0) && (thumb < this.thumbs.length)) {
			if ((thumb < this.currentLeftThumb) || (thumb > this.currentLeftThumb + 3)) {
				this.nextThumb	= thumb;
				//this.thumbsScrollEffect.toElement(this.thumbs[thumb]);
				this.thumbsScrollEffect.start(this.thumbs[thumb].getPosition(this.thumbsHolder.getFirst()).x, 0);
			}

			if (select) {
				this.thumbs[thumb].removeEvents();
				this.thumbs[thumb].set('class', 'thumb_active').setStyle('background-position', 'left bottom');

				this.thumbs[this.currentItem].set('class', 'thumb').setStyle('background-position', 'left top');
				this.thumbs[this.currentItem].addEvents({
					'click':		this.onThumbClickBound,
					'mouseenter':	this.onThumbMouseOverBound,
					'mouseleave':	this.onThumbMouseOutBound
				});
			}
		}
	},

	/**
	 * Private function!
	 */
	initElements: function() {
		var cssPrefix			= this.options.container.get('class').split(' ')[0];

		this.itemsHolder		= this.options.container.getElement('.' + cssPrefix + '_items');
		this.items				= this.itemsHolder.getElements('a');
		var itemsCount			= this.items.length;
		//this.itemsHolder.getFirst().setStyle('width', (this.items[itemsCount-1].getPosition().x + this.items[itemsCount-1].getSize().x) + 'px');
		this.itemsHolder.getFirst().setStyle('width', (itemsCount * 600) + 'px');

		this.thumbsHolder		= this.options.container.getElement('.controls .thumbs');
		this.thumbsScrollPrev	= this.thumbsHolder.getPrevious();
		this.thumbsScrollNext	= this.thumbsHolder.getNext();

		this.thumbsHolder.grab(new Element('div', {'class': 'thumbs_wrap'}));

		var clearer				= new Element('div', { 'class': 'clear' });
		this.thumbsHolder.getFirst().grab(clearer);
		this.thumbsHolder.getFirst().setStyle('width', '0px');

		var newThumb			= null;
		for (var i = 0; i < itemsCount; ++i) {
			newThumb			= new Element('div', {
				'class': ((i == 0) ? 'thumb_active' : 'thumb')
			}).set('text', i+1);

			newThumb.inject(clearer, 'before');

			this.thumbs.push(newThumb);

			//this.thumbsHolder.getFirst().setStyle('width', (this.thumbsHolder.getFirst().getSize().x + newThumb.getSize().x + newThumb.getStyle('margin-left').toFloat() + newThumb.getStyle('margin-right').toFloat()) + 'px');
			this.thumbsHolder.getFirst().setStyle('width', (this.thumbsHolder.getFirst().getStyle('width').toFloat() + newThumb.getStyle('width').toFloat() + newThumb.getStyle('padding-left').toFloat() + newThumb.getStyle('padding-right').toFloat() + newThumb.getStyle('margin-left').toFloat() + newThumb.getStyle('margin-right').toFloat()) + 'px');
		}
		this.thumbsHolder.getFirst().setStyle('width', (this.thumbsHolder.getFirst().getStyle('width').toFloat() - newThumb.getStyle('margin-right').toFloat()) + 'px');
		newThumb.setStyle('margin-right', '0px');

		this.thumbsScrollPrev.setStyle('visibility', 'hidden');

		if (itemsCount < 5) {
			this.thumbsScrollNext.setStyle('visibility', 'hidden');
		}

		var sound				= null;
		if ((sound = this.options.container.getElement('.' + cssPrefix + '_sound')) && (typeof(swfobject) != 'undefined')) {
			swfobject.embedSWF(
				'images/flash/PresentationSound.swf',
				sound.get('id'),
				'50',
				'25',
				'9.0.0',
				null,
				{
					'soundURL':				sound.get('title')
				},
				{
					'allowScriptAccess':	'sameDomain',
					'scale':				'noscale',
					'salign':				'tl',
					'bgcolor':				'#FFFFFF'
				},
				{
					'id':					sound.get('id'),
					'name':					sound.get('id'),
					'align':				'middle',
					'class':				sound.get('class')
				}
			);
		}

		sound					= null;
		cssPrefix				= null;
		newThumb				= null;
		clearer					= null;

		return this;
	},

	/**
	 * Private function!
	 */
	initEvents: function() {
		var thumbsCount	= this.thumbs.length;
		for (var i = 1; i < thumbsCount; ++i) {
			this.thumbs[i].addEvents({
				'click':		this.onThumbClickBound,
				'mouseenter':	this.onThumbMouseOverBound,
				'mouseleave':	this.onThumbMouseOutBound
			});
		}

		this.thumbsScrollPrev.addEvents({
			'mousedown':	this.onThumbsScrollPrevMouseDownBound,
			'mouseup':		this.onThumbsScrollPrevMouseUpBound,
			'mouseleave':	this.onThumbsScrollPrevMouseOutBound
		});

		this.thumbsScrollNext.addEvents({
			'mousedown':	this.onThumbsScrollNextMouseDownBound,
			'mouseup':		this.onThumbsScrollNextMouseUpBound,
			'mouseleave':	this.onThumbsScrollNextMouseOutBound
		});

		return this;
	},

	/**
	 * Private function!
	 */
	rotateToNextItem: function() {
		this.nextItem	= (this.nextItem < this.items.length - 1) ? this.nextItem + 1 : 0;
//		if (this.nextItem == 0) {
//			this.stop();
//			return true;
//		}
		this.showItem(this.nextItem);
	},

	/**
	 * Private function!
	 */
	onThumbsScrollEffectStart: function() {
		if (this.thumbs.length > 4) {
			if (this.nextThumb + 4 < this.thumbs.length) {
				this.thumbsScrollNext.setStyle('visibility', 'visible');
			} else {
				this.thumbsScrollNext.setStyle('visibility', 'hidden');
			}

			if (this.nextThumb > 0) {
				this.thumbsScrollPrev.setStyle('visibility', 'visible');
			} else {
				this.thumbsScrollPrev.setStyle('visibility', 'hidden');
			}
		}
	},

	/**
	 * Private function!
	 */
	onThumbsScrollEffectComplete: function() {
		this.currentLeftThumb	= this.thumbsHolder.getScroll().x / (this.thumbs[0].getSize().x + this.thumbs[0].getStyle('margin-left').toInt() + this.thumbs[0].getStyle('margin-right').toInt());

		if (this.thumbsScrollPrevPressed) {
			this.nextThumb		= this.currentLeftThumb - 1;
			//this.thumbsScrollEffect.toElement(this.thumbs[this.nextThumb]);
			this.thumbsScrollEffect.start(this.thumbs[this.nextThumb].getPosition(this.thumbsHolder.getFirst()).x, 0);
		} else if (this.thumbsScrollNextPressed) {
			this.nextThumb		= this.currentLeftThumb + 1;
			//this.thumbsScrollEffect.toElement(this.thumbs[this.nextThumb]);
			this.thumbsScrollEffect.start(this.thumbs[this.nextThumb].getPosition(this.thumbsHolder.getFirst()).x, 0);
		}
	},

	/**
	 * Private function!
	 */
	onThumbClick: function(evt) {
		this.showItem(this.thumbs.indexOf(evt.target));
		this.stop();
	},

	/**
	 * Private function!
	 */
	onThumbMouseOver: function(evt) {
		if (Browser.Engine.trident) {
			evt.target.setStyle('background-position-y', 'bottom');
		} else {
			evt.target.setStyle('background-position', evt.target.getStyle('background-position').split(' ')[0] + ' bottom');
		}
	},

	/**
	 * Private function!
	 */
	onThumbMouseOut: function(evt) {
		if (Browser.Engine.trident) {
			evt.target.setStyle('background-position-y', 'top');
		} else {
			evt.target.setStyle('background-position', evt.target.getStyle('background-position').split(' ')[0] + ' top');
		}
	},

	/**
	 * Private function!
	 */
	onThumbsScrollPrevMouseDown: function() {
		this.thumbsScrollPrevPressed	= true;
		this.nextThumb					= this.currentLeftThumb - 1;
		//this.thumbsScrollEffect.toElement(this.thumbs[this.nextThumb]);
		this.thumbsScrollEffect.start(this.thumbs[this.nextThumb].getPosition(this.thumbsHolder.getFirst()).x, 0);
	},

	/**
	 * Private function!
	 */
	onThumbsScrollPrevMouseUp: function() {
		this.thumbsScrollPrevPressed	= false;
	},

	/**
	 * Private function!
	 */
	onThumbsScrollPrevMouseOut: function() {
		this.thumbsScrollPrevPressed	= false;
	},

	/**
	 * Private function!
	 */
	onThumbsScrollNextMouseDown: function() {
		this.thumbsScrollNextPressed	= true;
		this.nextThumb					= this.currentLeftThumb + 1;
		//this.thumbsScrollEffect.toElement(this.thumbs[this.nextThumb]);
		this.thumbsScrollEffect.start(this.thumbs[this.nextThumb].getPosition(this.thumbsHolder.getFirst()).x, 0);
	},

	/**
	 * Private function!
	 */
	onThumbsScrollNextMouseUp: function() {
		this.thumbsScrollNextPressed	= false;
	},

	/**
	 * Private function!
	 */
	onThumbsScrollNextMouseOut: function() {
		this.thumbsScrollNextPressed	= false;
	}
});

window.addEvent('domready', function() {
	window.Presentations = new PresentationsManager();
});

