/**
 *
 *	Requires W.Dom
 *	Requires W.Tween
 *	usages: var fader	= new W.Fader();
 *
 */
W.Fader = function(param)
{
	this.init(param);
}


W.Fader.prototype = {


	photos		: null,			// array of photos - images are stored starting at 1, index 0 is not used
	index		: 1,			// photo this is currently visible
	prev_index	: 1,			// photo this is currently fading out
	tween		: null,			// reference to object running the opacity animation
	timer		: null,			// reference to timer for the next fade
	duration	: 7,			// how long the fade lasts
	_pause		: 3000,			// amount of time before photo fades out
	loop		: true,			// loop to the beginning after last photo?
	auto		: true,			// auto advance to the next photo?
	nav			: null,			// use a nav for photos?
	crossfade	: false,			// fade out and in at the same time?
	

	init : function(param)
	{
		// set param
		if (param) {
			if (param.duration != undefined) this.duration = param.duration;
			if (param.pause != undefined) this._pause = param.pause;
			if (param.loop != undefined) this.loop = param.loop;
			if (param.auto != undefined) this.auto = param.auto;
			if (param.nav != undefined) this.nav = W.$(param.nav);
		}
	
		this.photos = [];
		this.tween	= {};
		
		//if (this.nav) this.init_nav();
	},
	
	
	
	add : function(img, index)
	{
		this.photos[index] = img;
		
		this.activate_jump(index);
		
		if (index == 1) {
			this.fade_in();
			this.select();
		}
	},
	
	
	
	init_nav : function(count)
	{
		this.add_jump('previous', 'previous');
		
		for (var i = 1; i <= count; ++i) {
			this.add_jump(i);
		}
		
		this.add_jump('next', 'next');
		
		return this;
	},
	
	
	
	add_jump : function(index, className)
	{
		var li = document.createElement('li');
		
		var a	= document.createElement('a');
		if (className) a.className = className;
		a.onclick	= this.jump.bind(this, index);
		//a.href		= '#';
		a.innerHTML	= '<span>Photo ' + index + '</span>';
		
		li.appendChild(a)
		this.nav.appendChild(li);
	},
	
	
	
	jump : function(e, index)
	{
		W.Event.cancelClick(e);

		//if (index == 'next') return this.next();
		//if (index == 'previous') return this.previous();
		
		//if (!this.photos[index]) return false;
		
		for (tween in this.tween) {
			this.tween[tween].stop();
		}
		
		//this.set_opacity_in(100);
		if (this.index != this.prev_index) this.set_opacity_out(0);
		
		clearTimeout(this.timer);
		
		this.fade_out();
		
		//this.index	= index;
		if (index == 'next') {
			this.next();
		} else if (index == 'previous') {
			this.previous();
		} else {
			this.index = index;
			if (this.crossfade) this.fade_in();
		}
		
		this.select();
		this.activate_previous_next();
		this.auto	= false;
	},
	
	
	
	activate_jump : function(index)
	{
		if (!this.nav) return;
		
		var lis = this.nav.getElementsByTagName('li');
		var li	= lis[index];
		if (li) { W.Dom.addClassname(li, 'ready'); }
		
		if (this.photos.length == (lis.length - 1)) this.activate_next(true);	// activate next button once all photos are loaded
	},
	
	
	
	activate_previous : function(state)
	{
		if (!this.nav) return;
		
		var li	= this.nav.getElementsByTagName('li')[0];
		if (li) {
			state? W.Dom.addClassname(li, 'ready') : W.Dom.removeClassname(li, 'ready');
		}
	},
	
	
	
	activate_next : function(state)
	{
		if (!this.nav) return;
		
		var lis = this.nav.getElementsByTagName('li');
		var li	= lis[lis.length - 1];
		if (li) { 
			state? W.Dom.addClassname(li, 'ready') : W.Dom.removeClassname(li, 'ready');
		}
	},
	
	
	
	activate_previous_next : function()
	{
		if (this.index > 1) this.activate_previous(true); else this.activate_previous(false);
		if (this.index < (this.photos.length - 1)) this.activate_next(true); else this.activate_next(false);
	},
	
	
	
	select : function()
	{
		if (!this.nav) return;
		
		var lis		= this.nav.getElementsByTagName('li');
		var index	= this.index;
		
		for (var i = 0, max = lis.length; i < max; ++i ) {
			if (i == index) W.Dom.addClassname(lis[i], 'selected'); else W.Dom.removeClassname(lis[i], 'selected');
		}
	},
	
	
	
	fade_in : function()
	{
		start	= 0;
		change	= 100;
		
		delete this.tween.fade_out;

		this.tween.fade_in	= new W.Tween({start: start, change: change, duration: this.duration, obj: this, bind: 'set_opacity_in', method: 'linear', callback: 'finish'});
	},
	
	
	
	fade_out : function()
	{
		start 			= 100;
		change			= -100;
		this.prev_index	= this.index;
		
		delete this.tween.fade_in;
		
		var cb	= 'fade_in';
		if (this.crossfade) cb = false;
		this.tween.fade_out	= new W.Tween({start: start, change: change, duration: this.duration, obj: this, bind: 'set_opacity_out', method: 'linear', callback: cb});
	},
	
	
	
	set_opacity_in : function(num)
	{
		var div = this.find_container(this.index);
		div.style.display	= 'block';
		
		this.set_opacity(div, num);
	},
	
	
	
	set_opacity_out : function(num)
	{
		var div	= this.find_container(this.prev_index);
		
		this.set_opacity(div, num);
	},
	
	
	
	find_container : function(index)
	{
		var elem	= this.photos[index];
		
		while (elem.className != 'photo' && elem.tagName.toLowerCase != 'body') {
			elem	= elem.parentNode;
		}
		
		return elem;
	},
	
	
	
	set_opacity : function(elem, num)
	{
		elem.style.opacity	= num / 100;
		elem.style.filter	= 'alpha(opacity=' + num + ')';
		if (num <= 0) elem.style.display = 'none';
	},
	
	
	
	next : function()
	{
		if (this.index < (this.photos.length - 1) || this.loop) this.fade_out();
		
		++this.index;
		if (this.index == this.photos.length) {
			if (!this.loop) {
				this.prev_index	= this.index - 1;
				this.index = 1;
				return;
			}
			this.index = 1;
		}
		
		if (this.crossfade) this.fade_in();
		this.select();
		this.activate_previous_next();
	},
	
	
	
	previous : function()
	{
		this.fade_out();
		
		--this.index;
		if (this.index == 0) { this.index = this.photos.length - 1; }
		
		if (this.crossfade) this.fade_in();
		this.select();
		this.activate_previous_next();
	},
	
	
	
	pause : function()
	{
		for (tween in this.tween) {
			this.tween[tween].pause();
		}
		
		clearTimeout(this.timer);
	},
	
	
	
	resume : function()
	{
		for (tween in this.tween) {
			this.tween[tween].resume();
		}
	},
	
	
	
	finish : function()
	{
		var obj		= this;
		
		if (this.auto) this.timer	= setTimeout(function() { obj.next(); }, this._pause);
	}
	
}