/**
 * @author 					Dave Shepard
 * @version					0.5
 * @updated_at 				May 14, 2009
 * @required libraries:		Prototype 1.6 or later, Scriptaculous 1.8 or later
 * 
 * Cycler Class to cycle through thumbnail elements and display full version
 * elements in another DIV. Useful for galleries of elements.
 *
 * Implementation:
 * ===============
 * After the object is available in the DOM (recommended using the
 * document.observe('dom:loaded') command for best results), instantiate
 * the Cycler Class:
 * 
 *     var myCycler = new Cycler('elements_container_id','thumbnails_container_id',options);
 * 
 * Parameters:
 * ---------------------------------------------------------------
 * elements_container_id	[string] 	(required) The ID of the element containing the
 * 										"full size" versions of the cycled elements.
 * thumbnails_container_id	[string] 	(required) The ID of the element containing the 
 * 										"thumbnails" of the cycled elements.
 * options					[object] 	(optional) Pass options to the Class instance to modify the default
 * 										parameters. Utilizes the values below:
 * 		cycle				[boolean]	(default:false) Cycle the elements automatically
 * 		duration			[float]		(default:0.5) Duration of cross-fade for displaying an element in seconds
 * 		delay				[float]		(default:5) Delay between automatic cross-fades
 *
 */

var Cycler = Class.create({
	current: "",
	currentIndex: 0,
	thumbnailsContainerID: "",
	elementsContainerID: "",
	thumbnails: [],
	elements: [],
	options: {
		cycle: true,
		duration: 0.5,
		delay: 5
	},
	show: function(elem){
		var t = this;	// Import Parent Object
		this.updateCurrent(elem);
		this.elements.each(function(e,ind){
			if(ind > t.currentIndex){
				var options = {
					duration: t.options.duration,
					delay: t.options.cycle == true ? t.options.delay : 0
				}
				if(t.options.cycle == true && t.currentIndex != 0){
					options['queue'] = {
						position: 'front',
						scope: 'cycler'
					}
				} else {
					if(t.options.cycle == true){
						t.elements.findAll(function(s){
							return s != t.elements.last();
						}).invoke('hide');
					}
				}
				new Effect.Fade(e,options);
			}
		});
		
		var showDelay = this.options.cycle == true ? this.options.delay : 0;
		window.setTimeout(function(){
			t.thumbnails.invoke('removeClassName','active');
			t.thumbnails[t.currentIndex].addClassName('active');
		}, showDelay * 1000);

		var options = {
			duration: this.options.duration,
			delay: this.options.cycle == true ? this.options.delay : 0,
			afterFinish: function(){
				t.elements.each(function(e,ind){
					if(ind > t.currentIndex) {
						e.hide();
					}
				});

				if(t.options.cycle == true) {
					t.show(t.elements[t.getNextIndex()]);
				}
			}
		}
		if(this.options.cycle == true){
			options['queue'] = {
				position: 'front',
				scope: 'cycler'
			}
		}
		new Effect.Appear(this.elements[this.currentIndex],options);
	},
	updateCurrent: function(elem){
		var t = this;	// Import Parent Object
		this.current = elem.id.split('_').first();
		this.elements.each(function(e,ind){
			if(e.id.match(t.current+'_testimonial')) {
				t.currentIndex = ind;
			}
		})
	},
	getNextIndex: function(){
		if(this.currentIndex == (this.elements.length - 1)) {
			return 0;
		} else {
			return this.currentIndex + 1;
		}
	},
	assign: function(){
		var t = this;	// Import Parent Object
		this.thumbnails.each(function(e){
			e.select('a').first().observe('click', function(event){
				Event.stop(event);
				if(t.options.cycle == true){
					t.options.cycle = false;
					Effect.Queues.get('cycler').each(function(effect){ effect.cancel(); });
				}
				t.show(this);
			});
		 });
	},
	init: function(){
		this.thumbnails = $(this.thumbnailsContainerID).childElements();
		this.elements = $(this.elementsContainerID).childElements();
		
		this.updateCurrent(this.elements.first());
		this.assign();
		
		if(this.options.cycle == true){
			this.show(this.elements[this.getNextIndex()]);
		}
	},
	initialize: function(elemID,thumbID,options){
		if(!Object.isUndefined(options)) {
			var optionKeys = Object.keys(options);
			var optionVals = Object.values(options);
			for(i=0 ; i < optionKeys.length ; i++){
				this.options[optionKeys[i]] = optionVals[i];
			}
		}
		this.thumbnailsContainerID = thumbID;
		this.elementsContainerID = elemID;
		this.init();
	}
});