/*this in particular handles our transition effects*/
var SlideEffects =function(elm,options){
	this.transition=null;
	this.playing = false;
	this.elms = [];//will store secondary elements to apply animation to, if elm is an array or collection
	
	if(typeof elm == 'object') {
		for(var i = 0; i < elm.length; i++) {
			this.elms.push(elm[i]);
		}
		this.elm = this.elms.shift();
	}else{
		this.elm = elm;
	}
	
	options.fps = (1000/(options.fps||35));
	this.options = options || {};
	this.onComplete = this.options.onComplete || function(){};
};

/*opacity utilities*/
SlideEffects.setOpacity=function(elm,amount){
	if(!elm) {
		return false;
	}
	if(amount <= 0){
		elm.style.visibility = 'hidden';
	}else{
		elm.style.visibility = '';
	}
	if(Slideshow.isIE()!==false){
		elm.style.filter = 'progid:DXImageTransform.Microsoft.Alpha(opacity = '+Math.round(amount*100)+')';
		elm.style.zoom = '1';
	}else{
		elm.style.opacity = amount;
	}
};
SlideEffects.getOpacity=function(elm){
	var opacity = Number(elm.style.opacity)
	if(!isNaN(opacity)){
		return opacity;
	}
	if(elm.style.filter!=''){
		var matches = elm.style.filter.match(/opacity\s?=\s?(\d+)/i);
		return matches.length > 1 ? Number(matches[1])/100 : false;
	}
	return false;
};

/*SlideEffects methods*/
SlideEffects.prototype.fadeIn = function(){
	this.fade({direction:'in'});
};
SlideEffects.prototype.fadeOut = function(){
		this.fade({direction:'out'});
};
SlideEffects.prototype.stopTransition=function(triggerComplete){
	clearInterval(this.transition);
	this.transition = null;
	
	if(triggerComplete === true) {
		this.playing=false;
		this.onComplete();
	}
};
SlideEffects.prototype.setAllOpacity = function(opacity){
	SlideEffects.setOpacity(this.elm,opacity);
	if(this.elms.length > 0) {
		this.elms.forEach(function(item){
			SlideEffects.setOpacity(item,opacity);
		},this);
	}
};
SlideEffects.prototype.frame=function(){
		if(this.amount>0 && this.currentOpacity >=1 || this.amount<1 && this.currentOpacity<=0){
		
			var endOpacity = 0;
			if(this.amount>0 && this.currentOpacity>1){
				endOpacity = 1;
			};
			
			this.setAllOpacity(endOpacity);
			
			this.stopTransition(true);
			return;
		}
		this.currentOpacity+=(this.amount/100);
		this.setAllOpacity(this.currentOpacity);
	};
SlideEffects.prototype.fade=function(parts){
	this.amount = (parts.direction || 'out') == 'in' ? 7 : -7;//amount to increase or decrease opacity
	var wait = this.options.wait || false;//wait  until the animation is finished before moving onto the next
	
	//this will define our end result for opacity
	this.currentOpacity = SlideEffects.getOpacity(this.elm) || 0.00;
	if(this.amount < 0){
		this.currentOpacity = SlideEffects.getOpacity(this.elm) || 1.00;
	}		
			
	if(this.playing&&!wait){
		this.stopTransition();
	}
	
	this.playing=true;
	
	var self = this;
	this.transition = setInterval(function(){return self.frame.apply(self);},this.options.fps);
};


/*actual slideshow code*/
var Slideshow = function(options){
	this.imageElement = options.imageContainer || null;
	this.textElement = options.textContainer || null;
	this.images = options.images || [];
	this.current = 0;
	this.status = Slideshow.STOPPED;
	this.ticker = null;
	this.duration = options.duration || 5000;
	
	if(this.imageElement) {
		this.imageItems = this.imageElement.getElementsByTagName('img');
	}
	if(this.textElement) {
		this.imageItems = this.textElement.getElementsByTagName('div');
	}
	
	this.effects = [];
	
	/*callbacks*/
	this.onTransition = options.onTransition || function(){};
	this.onStatusChange = options.onStatusChange || function(){};
		
	var self = this;
	
	/*set each slide except the first to a opacity level of 0,
	 and apply effects and callbacks*/
	for(var i = 0;i<this.imageItems.length;i++){
		if(i>0){
			(['imageItems','textItems']).forEach(function(item){
				if(typeof this[item] == 'object' && typeof this[item][i] != 'undefined'){
					SlideEffects.setOpacity(this[item][i],0);
				}
			},self);
		}

		var items=[];
		(['imageItems','textItems']).forEach(function(item){
			if(typeof this[item] == 'object' || typeof this[item] == 'function' && typeof this[item][i] != 'undefined'){
				items.push(this[item][i]);
			}
		},self);

		this.effects.push(
			new SlideEffects(items,{
				onComplete:function(){ 
					if(self.status==Slideshow.PLAYING){
						self.start.apply(self);
					}
				}
			})
		);
	}
			
};
//status constants
Slideshow.STOPPED = 0;
Slideshow.PLAYING = 1;
Slideshow.isIE=function(){
	if(window.ActiveXObject){
		return (window.JSON) ? 8 : (window.XMLHttpRequest) ? 7 : 6;
	}
	return false;
};
Slideshow.prototype={
	start:function(){
		if(this.imageItems.length < 2){this.changeStatus(Slideshow.STOPPED);return;}
		this.changeStatus(Slideshow.PLAYING);
		clearTimeout(this.ticker);
		var self = this;
		this.ticker = setTimeout(function(){
			self.next.apply(self);
		},this.duration);
	},
	pause:function(){
		this.changeStatus(Slideshow.STOPPED);
		clearTimeout(this.ticker);
	},
	next:function(){
		var current = this.current;
		if(++current == this.imageItems.length){
			current =  0;
		}
		this.goTo(current);
	},
	back:function(){
		var current = this.current;
		if(--current < 0){
			current =  (this.imageItems.length-1);
		}
		this.goTo(current);
	},
	goTo:function(which){
		if(typeof which != 'number' || which<0 || typeof this.imageItems[which] =='undefined' || this.current == which){
			return false;
		}
		
		clearTimeout(this.ticker);
		
		this.onTransition.call(null,which);//fire off our callback
		
		this.effects[this.current].fadeOut();
		this.imageItems[this.current].style.zIndex='1';

		this.current = which;
		this.imageItems[this.current].style.zIndex='1000';
		
		this.effects[this.current].fadeIn();
	},
	changeStatus:function(status){
		this.status = status;
		this.onStatusChange.call(this,status);//fire the onstatuschange callback
	}
};
