/*
 * Effect Manager, binds an effect to an element.
 * WIP:
 * Slide, Fade
 */
function ElementEffect(effect) {
	this.effect = effect;

	this.run = function(element) {
		this.effect.element = element;
		
		if (this.effect.element.computedStyle().display == 'none') method = 'show';
		else method = 'hide';
		
		this.effect[method]();
	}	
}

/*
 * Slide Effect (C) Redsky 2009 
 */
function Effect_Slide() {
	this.element;
	this.speed = 50;
	this.step = 6;
	
	
	this.show = function() {				
		this.element.style.display = 'block';
		this.element.style.height = '0px';
		this.element.style.overflow = 'hidden';
		
		var self = this;
		var height = 0;
		
		var slide = function() {
			height += self.step;
			self.element.style.height = height + 'px';
			self.element.scrollTop = self.element.scrollHeight;
			
			if (self.element.scrollTop > 0) setTimeout(slide, this.speed);
			else {
				self.element.style.height = 'auto';
			}
		
		}		
		slide();	
	}
		
	this.hide = function() {
		var self = this;
		var height = this.element.offsetHeight;
		this.element.style.overflow = 'hidden';
		
		var slide = function() {
			height -= self.step;
			
			if (height > 0) self.element.style.height = height + 'px';
			self.element.scrollTop = self.element.scrollHeight;
			
			if (height < 1) self.element.style.display = 'none';
			
			if (self.element.offsetHeight > 0) setTimeout(slide, this.speed);
		}		
		slide();
	}
}
 
function Effect_Fade() {
	this.element;
	this.speed = 30;
	this.step = 6;
	this.opacity = 0;
	this.oncomplete = function() {};
	
	this.show = function() {
		if (this.element.fading) return;

		this.opacity = 0;
		this.element.style.opacity = 0;
		var self = this;
		
		var fade = function() {
		
			self.element.fading = true;
			if (self.opacity < 100) {
				self.opacity += self.step;
				self.element.setOpacity(self.opacity/100);
				setTimeout(fade, self.speed);
				
			}
			else {
				self.element.fading = false;
				self.oncomplete();
			}
		}
		
		fade();
	}
	
	this.hide = function() {
		if (this.element.fading) return;
		
		this.opacity = 100;
		var self = this;
		var fade = function() {			
			self.element.fading = true;
			if (self.opacity > 0) {
				self.opacity -= self.step;
				self.element.style.opacity = (self.opacity/100);
				setTimeout(fade, self.speed)
			}
			else {
				self.element.fading = false;
				self.oncomplete();
			}
		}
		
		fade();		
	}
}

$.elementPrototype.fade = function(args) {
	if (!args) args = {};
	var effect = new Effect_Fade();
	effect.element = this;
	
	for (var i in args) {
		effect[i] = args[i];
	}
	
	if (!args.type) args.type = 'show';
	
	if (args.type == 'show') effect.show();
	else if (args.type == 'hide') effect.hide();
	
}

function Effect_FadeCycle(elements) {
	this.index = 0;
	this.interval = 10000;
	
	this.elements = elements;
	this.elements.item(0).style.display = 'block';	

	this.run = function() {
		var self = this;
		this.elements.item(this.index).fade({type: 'hide', speed: 25, step: 1, oncomplete: function(){ self.next(); } });
	}
	
	this.start = function() {
		var self = this;
		setTimeout(function() { self.run(); }, this.interval);
	}
	
	this.next = function() {
		this.elements.item(this.index).style.display = 'none';
		this.index++
		if (!this.elements.item(this.index)) this.index = 0;
		
		
		this.elements.item(this.index).fade({type: 'show', speed: 25, step: 1});
		this.elements.item(this.index).style.display = 'block';
		var self = this;
		setTimeout(function() { self.run(); }, this.interval);
	}
}


function Effect_Move(element) {
	this.element = element;
	this.step = 5;
	this.speed = 20;
	
	this.slide = function(direction, amount) {
		
		
		var origMargin = parseInt(this.element.style.marginLeft.split('px')[0]);
		if (isNaN(origMargin)) origMargin = 0;
		
		if (direction == -1 && origMargin == 0) return;
		var pos = this.element.position();
		
		//console.log((Math.abs(origMargin) + direction )+ ' ' + (pos.width - amount))
		if ((Math.abs(origMargin) + direction) >= (pos.width - amount)) return;
		
		var self = this;
		var slide = function() {
			if (Math.abs(self.element.style.marginLeft.split('px')[0]) != Math.abs(Math.abs(origMargin) + (direction*amount))) {
				self.element.style.marginLeft = (self.element.style.marginLeft.split('px')[0] - (direction*self.step)) + 'px';
				//console.log(self.element.style.marginLeft);
				setTimeout(slide, self.speed);				
			}
		}
		
		slide();		
	}
	
	this.translate = function(x, y, timeout) {
		
	}
}

$.elementPrototype.move = function(args) {
	var effect = new Effect_Move(this);
	effect.slide(args.direction, args.amount);
}

$.elementPrototype.setOpacity = function(num) {
	this.style.opacity = num;
	this.style.filter = 'alpha(opacity=' + (num*100) + ')';
}

var Effect_CrossFade2_backup = function(elements) {
	this.front = new $e('div');
	this.back = new $e('div');
	this.interval = 10000;
	
	this.random = true;
	
	this.elements = elements;
	
	this.front.style.width = elements.item(0).position().width + 'px';
	this.front.style.height = elements.item(0).position().height + 'px';
	
	this.back.style.width = elements.item(0).position().width + 'px';
	this.back.style.height = elements.item(0).position().height + 'px';
	
	
	
	elements.item(0).parentNode.insertBefore(this.back, elements.item(0));
	
	
	
	this.pool = new $e('div');
	
	
	
	for (var i = 0; i < elements.count(); i++) {
		this.pool.appendChild(elements.item(i));
	}
	
	//and put back item0
	//this.back.appendChild(elements.item(0));
	
	//Move front over back
	
	this.front.style.position = 'absolute';
	this.front.style.top = this.back.position().top + 'px';
	this.front.style.left = this.back.position().left + 'px';
	

	this.start = function() { 
		document.body.appendChild(this.front);
		
		//if it's random, put a random one on top in the pool
		var self = this;
		//setTimeout(function() {self.fade();}, this.interval);
		this.fade();
		self.front.appendChild(self.elements.item(self.getNextImage()));
	}
	
	
	this.fade = function() {
		var self = this;
		//var next = this.getNextImage();
		this.front.style.display = 'block';
		this.front.fade({type: 'show',
			oncomplete: function() {
				//self.backgroundDiv.style.backgroundImage = 'url(' + self.elements.item(next).src + ')';
				//
				
				//move back to pool
				for (var i = 0; i < self.back.childNodes.length; i++) self.pool.appendChild(self.back.childNodes[i]);
				
				
				//move front to back
				for (var i = 0; i < self.front.childNodes.length; i++) self.back.appendChild(self.front.childNodes[i]);
				
							
				
				//load a new image in front
				self.front.appendChild(self.elements.item(self.getNextImage()));
				
			
				self.front.style.display = 'none';
				//self.elements.item(next).style.display = 'none';	
				//
			}
		});
		
		
		setTimeout(function() {self.fade();}, 5000);
	
	}
	
	
	
	this.getNextImage = function() {
		if (this.random) {
			var i = 0;
			var rand = Math.round(Math.random()*(this.elements.count()-1));
			while (i < 100 && this.currentImage == rand ) {
				//dont get same image twice
				rand = Math.ceil(Math.random()*this.elements.count()-1);
				i++; //safetey precaution
			}
			
			this.currentImage = rand;
			return this.currentImage;
		}
		else {
			if (this.currentImage = this.elements.count()-1 || this.currentImage == null) this.currentImage = 0;
			else this.currentImage++;			
			return this.currentImage;
		}
	}
	
}

var Effect_CrossFade2 = function(elements) {
	this.front = new $e('div');
	this.back = new $e('div');
	this.interval = 10000;
	this.currentImage = null;
	this.random = false;
	
	this.elements = elements;
	
	this.front.style.width = elements.item(0).position().width + 'px';
	
	this.front.style.height = elements.item(0).position().height + 'px';
	this.front.style.position = 'absolute';
	
	this.back.style.width = elements.item(0).position().width + 'px';
	this.back.style.height = elements.item(0).position().height + 'px';
	
	
	elements.item(0).parentNode.insertBefore(this.front, elements.item(0));
	elements.item(0).parentNode.insertBefore(this.back, elements.item(0));
	
	
	
	
	this.pool = new $e('div');
	
	
	
	for (var i = 0; i < elements.count(); i++) {
		this.pool.appendChild(elements.item(i));
	}
	
	//and put back item0
	//this.back.appendChild(elements.item(0));
	
	//Move front over back
	
//	this.front.style.position = 'absolute';
	//this.front.style.top = this.back.position().top + 'px';
	//this.front.style.left = this.back.position().left + 'px';
	


	this.start = function() { 
		//document.body.appendChild(this.front);
		
		//if it's random, put a random one on top in the pool
		var self = this;
		//setTimeout(function() {self.fade();}, this.interval);
		this.fade();
		self.front.appendChild(self.elements.item(self.getNextImage()));
	}
	
	
	this.fade = function() {
		var self = this;
		//var next = this.getNextImage();
		this.front.style.display = 'block';
		this.front.fade({type: 'show',
			oncomplete: function() {
				//self.backgroundDiv.style.backgroundImage = 'url(' + self.elements.item(next).src + ')';
				//
				
				//move back to pool
				for (var i = 0; i < self.back.childNodes.length; i++) self.pool.appendChild(self.back.childNodes[i]);
				
				
				//move front to back
				for (var i = 0; i < self.front.childNodes.length; i++) self.back.appendChild(self.front.childNodes[i]);
				
							
				
				//load a new image in front
				self.front.appendChild(self.elements.item(self.getNextImage()));
				
			
				self.front.style.display = 'none';
				//self.elements.item(next).style.display = 'none';	
				//
			}
		});
		
		
		setTimeout(function() {self.fade();}, 5000);
	
	}
	
	
	
	this.getNextImage = function() {
		if (this.random) {
			var i = 0;
			var rand = Math.round(Math.random()*(this.elements.count()-1));
			while (i < 100 && this.currentImage == rand ) {
				//dont get same image twice
				rand = Math.ceil(Math.random()*this.elements.count()-1);
				i++; //safetey precaution
			}
			
			this.currentImage = rand;
			return this.currentImage;
		}
		else {
			if (this.currentImage == this.elements.count()-1 || this.currentImage == null) this.currentImage = 0;
			else this.currentImage++;			
			return this.currentImage;
		}
	}
	
}

var Effect_CrossFade = function(elements) {
	this.interval = 1000;
	this.backgroundDiv = new $e('div');	
	
	this.backgroundDiv.style.width = elements.item(0).position().width + 'px';
	this.backgroundDiv.style.height = elements.item(0).position().height + 'px';
 

	this.elements = elements;
	elements.item(0).parentNode.insertBefore(this.backgroundDiv, elements.item(0));
	
	for (var i = 0; i < elements.count(); i++) {
		this.backgroundDiv.appendChild(elements.item(i));
	}
	
	
	elements.apply(function() { this.style.display = 'none'; });
	
	this.random = false;
	this.currentImage = null;
	
	this.getNextImage = function() {
		if (this.random) {
			var i = 0;
			var rand = Math.round(Math.random()*(this.elements.count()-1));
			while (i < 100 && this.currentImage == rand ) {
				//dont get same image twice
				rand = Math.ceil(Math.random()*this.elements.count()-1);
				i++; //safetey precaution
			}
			
			this.currentImage = rand;
			return this.currentImage;
		}
		else {
			if (this.currentImage = this.elements.count()-1 || this.currentImage == null) this.currentImage = 0;
			else this.currentImage++;			
			return this.currentImage;
		}
	}
	
	this.start = function() {
		var img = this.getNextImage();
		this.backgroundDiv.style.backgroundImage = 'url(' + this.elements.item(img).src + ')';
		for (var s in img.style) {
			try {
				if (s != 'display') this.backgroundDiv.style[s] = img.style[s];
			}
			catch (e) {
				
			}
		}
		var self = this;
		setTimeout(function() {self.fade();}, this.interval);
	}
	
	this.fade = function() {
		var self = this;
		var next = this.getNextImage();
		this.elements.item(next).fade({type: 'show',
			oncomplete: function() {
				self.backgroundDiv.style.backgroundImage = 'url(' + self.elements.item(next).src + ')';
				
				var img = self.elements.item(next);
				//this.backgroundDiv.style.backgroundImage = 'url(' + self.elements.item(next).src + ')';
				for (var s in img.style) {
					try {
						//if (s != 'display') self.backgroundDiv.style[s] = img.style[s];
					}
					catch (e) {
					}
				}
				
				self.elements.item(next).style.display = 'none';	
				setTimeout(function() {self.fade();}, self.interval);
			}
		});
		
		
		
	}
}

