/*
Class: Slideshow
	Class for creating a slideshow of imags with linked boxes
	Can be extended using the onChange function

TODO v1.0
	- integrate imageloader class
	- include styles?
*/
var Slideshow = new Class({
	version:'0.63',
	
	options: {
		initial          : 0, //index or 'random'
		timer            : false,
		startTimer       : true,
		duration         : 3000,
		dimensions       : { 'width' : 'auto', 'height' : 'auto' }, // must include unit (ie: 'px')
		thumbClass       : 'thumb',
		thumbClassActive : 'active',
		onChange         : Class.Empty,
		onLoad           : Class.Empty
	},
	
	initialize: function(slideshow, sources, options){
		this.setOptions(options);
		this.idle       = true;
		this.id         = slideshow; //if its a string, use that.  if its an element, use the elements id if set. otherwise use 'slideshow'
		this.slideshow  = $(slideshow).setOpacity(0);
		this.timer      = false;
		this.image      = new Element('img');
		this.images     = {
			index    : this.options.initial == 'random' ? parseInt(Math.random()*sources.length) : this.options.initial,
			thumbs   : [],
			sources  : sources,
			total    : sources.length
		};
		
		this.initializeComponents();
		this.initializeEffects();
		
		this.imageLoader = new ImageLoader(sources, {
			loadingDiv : this.loadingDiv,
			onComplete : this.show.bind(this)
		});

		this.image.src = this.images.sources[this.images.index];
	},
	
	initializeComponents: function() {
		this.imageDiv = new Element('div', {
			'id' : this.id + '-image'
		}).injectInside(this.slideshow);
		
		this.image
			.setStyles({
				'width'  : this.options.dimensions.width,
				'height' : this.options.dimensions.height
			})
			.addEvent('load', function(){ this.show(); })
			.injectInside(this.imageDiv);
		
		this.thumbs = new Element('div', {
			'id' : this.id + '-thumbs'
		}).injectInside(this.slideshow);
		
		if(this.options.timer) {
			this.controls    = new Element('div', { 'id' : this.id + '-control' }).injectInside(this.slideshow);
			this.playButton  = new Element('span', { 'events' : { 'mousedown' : this.play.bind(this) } }).injectInside(this.controls).setHTML('play');
			this.pauseButton = new Element('span', { 'events' : { 'mousedown' : this.pause.bind(this) } }).injectInside(this.controls).setHTML('pause');
		}
		
		for(var i = 0; i < this.images.total; i++) this.images.thumbs[i] = new Element('span');
		this.images.thumbs.each(function(e,i){
			e.addEvent('mousedown', function(){ this.getImage(i); this.pause(); }.bind(this))
			.addClass(this.options.thumbClass)
			.injectInside(this.thumbs);
		}, this);
		
		this.loadingDiv = $('loading');
		
		this.images.thumbs[this.images.index].addClass(this.options.thumbClassActive);
		if(this.options.timer) this.options.startTimer ? this.play() : this.pause();
	},
	
	initializeEffects: function() {
		this.fadeImage = this.image.effect('opacity', { wait:false, duration:500, onComplete: function(){
			this.idle = true;
			this.image.src = this.images.sources[this.images.index];
		}.bind(this) });		
	},
	
	show: function() {
		/*
		this.imageDiv.setStyle('height', this.image.getSize().size.y);
		this.slideshow.setStyles({
			'width'  : this.options.dimensions.width   == 'auto' ? this.image.getSize().size.x : this.options.dimensions.width,
			'height' : this.options.dimensions.height  == 'auto' ? 'auto' : this.options.dimensions.height
		});
		*/
		
		new Fx.Elements([this.slideshow, this.loadingDiv]).start({
			'0' : { 'opacity' : 1 },
			'1' : { 'opacity' : 0 }
		});
		this.fireEvent('onLoad', this.images.index);
	},
	
	getNext: function() {
		this.getImage(this.images.index == this.images.total - 1 ? 0 : this.images.index + 1);
	},
	
	getPrev: function() {
		this.getImage(this.images.index == 0 ? this.images.total - 1 : this.images.index - 1);
	},
	
	getImage: function(i) {
		if(this.images.index != i && this.idle) {
			this.idle = false;
			this.images.thumbs[this.images.index].removeClass(this.options.thumbClassActive);
			this.images.thumbs[i].addClass(this.options.thumbClassActive);
			this.images.index = i;
			
			this.fireEvent('onChange', this.images.index);
			this.imageDiv.setStyle('background-image', 'url('+this.images.sources[this.images.index]+')');
			
			this.fadeImage.start(1,0);
		}
	},

	play: function() {
		if(this.options.timer) { this.playButton.hide(); this.pauseButton.show(); }
		this.timer = this.getNext.periodical(this.options.duration, this);
	},
	
	pause: function() {
		if(this.options.timer) { this.playButton.show(); this.pauseButton.hide(); }
		$clear(this.timer);
	}
	
});

Slideshow.implement(new Events);
Slideshow.implement(new Options);
