// gallery.js

var Gallery = Class.create({
	
	callback: function(pe) {
		if (this.skipping)
			this.skipping = false		
		else if (this.playing)
			this.next();
	},
	
	changeView: function(newIndex) {
		if (/MSIE [23456]/.exec(navigator.userAgent))
			this.changeViewWithoutEffects(newIndex);			
		else	
			this.changeViewWithEffects(newIndex);		
		
		this.currentIndex = newIndex;
	},
	
	changeViewWithEffects: function(newIndex) {		
		var curId = this.views[curIndex = this.currentIndex].id;
		var newId = this.views[newIndex].id;		
		
		new Effect.Parallel([
			new Effect.Fade(curId, {
				afterFinish: function() {				             
					             this.views[curIndex].removeClassName('selected');					             				 	             
				             }.bind(this),
				beforeStart: function() {
					             this.thumbnails[curIndex].removeClassName('selected');
				             }.bind(this),
				sync: true
			}),
			new Effect.Appear(newId, {
				afterFinish: function() {
					             this.thumbnails[newIndex].addClassName('selected');
				             }.bind(this),
				beforeStart: function() {
				               this.views[newIndex].addClassName('selected').setStyle({ display: 'none' });				               				
				             }.bind(this),
				sync: true 
			})
		], { duration: 1.5 });			
	},
	
	changeViewWithoutEffects: function(newIndex) {		
		this.thumbnails[this.currentIndex].removeClassName('selected');
		this.views[newIndex].addClassName('selected');
		this.views[this.currentIndex].removeClassName('selected');
		this.thumbnails[newIndex].addClassName('selected');		
	},
	
	first: function(e) {
		this.changeView(0);
		this.skip();
	},		
	
	initialize: function(properties) {
				
		$H(properties).each(function(property) {					
			switch(property.key) {
				
				case 'first':
					this.clickToFirst = $(property.value);
					break;
					
				case 'last':
					this.clickToLast = $(property.value);
					break;
				
				case 'next':
					this.clickToNext = $(property.value);
					break;
					
				case 'pause':
					this.clickToPause = $(property.value);
					break;
					
				case 'play':
					this.clickToPlay = $(property.value);
					break;
					
				case 'previous':
					this.clickToPrevious = $(property.value);
					break;
					
				case 'thumbnails':						
					this.thumbnails = property.value.map(function(id) { return $(id);	});
					break;
					
				case 'views':						
					this.views = property.value.map(function(id) { return $(id); });
					break;
								
			}			
		}.bind(this));
		
		// Validate properties
		
		if (Object.isUndefined(this.views))
			alert("You must initialize your gallery with views.");
			
		else if ((! Object.isUndefined(this.thumbnails)) && (this.thumbnails.length != this.views.length)) // Think about changing != to !==
			alert("You must have the same number of thumbnails as you do views in your gallery.");
			
		// Setup event handlers for thumbnail elements
		
		this.clickToFirst.observe('click', this.first.bind(this));
		
		this.clickToLast.observe('click', this.last.bind(this));
		
		this.clickToNext.observe('click', this.next.bind(this));
		
		this.clickToPause.observe('click', this.pause.bind(this));
		
		this.clickToPlay.observe('click', this.play.bind(this));
		
		this.clickToPrevious.observe('click', this.previous.bind(this));
		
		this.thumbnails.each(function(thumbnail) {
			thumbnail.observe('click', this.select.bindAsEventListener(this, $(thumbnail)));
		}.bind(this));		
		
		// Initialize
		
		for (index = 0; index < this.views.length; ++index)
			this.views[index].setStyle({ zIndex: this.views.length - index - 1 });
		
		this.clickToPlay.addClassName('selected');
		this.thumbnails[0].addClassName('selected');
		this.views[0].addClassName('selected');
		
		this.currentIndex = 0;	
		this.playing = true;
		this.skipping = false;
		
		new PeriodicalExecuter(this.callback.bind(this), 4);				
	},
	
	last: function(e) {
		this.changeView(this.views.length - 1);
		this.skip();
	},
	
	next: function(e) {		
		this.changeView((this.currentIndex + 1) % this.views.length);
		this.skip();
	},
	
	pause: function(e) {
		this.clickToPause.addClassName('selected');
		this.clickToPlay.removeClassName('selected');
		
		this.playing = false;		
	},
	
	play: function(e) {
		this.clickToPause.removeClassName('selected');
		this.clickToPlay.addClassName('selected');
		
		this.playing = true;
	},
	
	previous: function(e) {		
		this.changeView((this.currentIndex + this.views.length - 1) % this.views.length);	
		this.skip();	
	},
	
	select: function(event, element) {		
		this.changeView(this.thumbnails.indexOf($(element.id)));		
		this.skip();	
	},
	
	skip: function() {
		if (this.playing)
			this.skipping = true;
	}
	
});
