/*
version 2.2
Jamil Ahmed
http://jadewits.com

20101104 - start auto play on hover after pause (fixed)

*jQuery and its effects core ui must loaded before to work
*elements can be supplied by jQuery selector

waitTime = number of seconds to wait before each transition
fadeTime = number of seconds for the transition
isRandom = (true/false) is randomly choose selected / active item [default:false]
transition = (slide/fade) transition effects [default:fade]
container = the container holds the slides
slide = each slide class / tag inside the container
paginContainer = container that holds the slide indexes
paginElem = elements / each index of slides
topBottom = (true/false) is the transition direction top to bottom [default:false]
diagonal = (true/false) is the transition moves diagonally ( prototype, special effect ) [default:false]
noAutoSlide = (true/false) automatic transition on/off [default:false]
hideController = (true/false) automatically hide controller if there is only one slide [default:true]

next = element that triggers next
previous = element that triggers previous
pauseToggle = element that toggle auto transition [ pause class when paused, play class while playing ]

//event handler
onPause = callback function on pause
onPlay = callback function on play
onChange = callback function on change must recieve an argument as index number of the current item
onNext = callback function on next
onPrevious = callback function on previous

example: new fadeAppear({
	container:'#jContainer',
	slide:'.slide',
	paginContainer:'#paging',
	paginElem:'li',
	fadeTime:0.5,
	waitTime:5.0,
	next:'#next',
	previous:'#prev',
	isRandom:true,
	transition:'slide',
	onChange:function(index){alert(index);}
	});
*/
var fadeAppear = function(o){
	var ths = new Object;
	ths.container = o.container;
	ths.slide = o.slide;
	ths.paginContainer = o.paginContainer;
	ths.paginElem = o.paginElem;
	ths.waitTime = (o.waitTime?o.waitTime:5.0)*1000;
	ths.fadeTime = (o.fadeTime?o.fadeTime:0.5)*1000;
	ths.isRandom = o.isRandom?o.isRandom:false;
	ths.transition = o.transition?o.transition:'fade';
	ths.topBottom = o.topBottom?o.topBottom:false;
	ths.diagonal = o.diagonal?o.diagonal:false;
	ths.noAutoSlide = o.noAutoSlide?o.noAutoSlide:false;
	ths.hideController = o.hideController?o.hideController:true;
	
	ths.nextId = o.next?o.next:'';
	ths.previousId = o.previous?o.previous:'';
	ths.pauseToggle = o.pauseToggle?o.pauseToggle:'';
	//event handler
	ths.onPause = o.onPause?o.onPause:function(){};
	ths.onPlay = o.onPlay?o.onPlay:function(){};
	ths.onChange = o.onChange?o.onChange:function(index){};
	ths.onNext = o.onNext?o.onNext:function(){};
	ths.onPrevious = o.onPrevious?o.onPrevious:function(){};
	
	//initialize
	ths.init = function(){
		ths.elems = $(ths.container + ' ' + ths.slide);
		ths.paging = $(ths.paginContainer + ' ' + ths.paginElem);
		$(ths.paginContainer + ' a').attr('href','javascript:');
		if( ths.transition == 'slide' ){
			ths.eachWidth = $(ths.container).width();
			ths.eachHeight = $(ths.container).height();
			}
		if( ths.isRandom ) ths.hide = Math.round(Math.random() * (ths.elems.length-1));
		else ths.hide = ths.elems.length-1;
		ths.show = ths.hide+1;
		if( ths.show > ths.elems.length-1 ) ths.show = 0;
		if( ths.hide > ths.elems.length-1 ) ths.hide = 0;
		ths.interval = null;
		ths.isPrev = false;
		ths.transitionInterval = null;
		
		//pre process and initialize if there is more than one slide
		if( ths.elems.length > 1 ){
			//initialize controllers
			if( ths.nextId ) $(ths.nextId).click(ths.next).attr('href','javascript:');
			if( ths.previousId ) $(ths.previousId).click(ths.prev).attr('href','javascript:');
			if( ths.pauseToggle ) $(ths.pauseToggle).toggle(
				function(){
					$(ths.pauseToggle).addClass('pause').removeClass('play');
					ths.pause();
					},
				function(){
					$(ths.pauseToggle).addClass('play').removeClass('pause');
					ths.play();
					}).attr('href','javascript:');
			for( i = 0; i < ths.elems.length; i++ ){
				e = ths.elems[i];
				$(e).mouseover(ths.pause2).mouseout(ths.play2);
				if(ths.paging.length) $(ths.paging[i]).click(ths.directGo);
				if( ths.transition == 'slide' ){
					if( ths.topBottom ) $(e).css({height:ths.eachHeight+'px'});
					else $(e).css({width:ths.eachWidth+'px'});
					}
				if( ths.hide != i ){
					if( ths.transition == 'fade' ) $(e).fadeOut(20);
					else if( ths.topBottom ) $(e).css({top:'-'+ths.eachHeight+'px'});
					else $(e).css({left:'-'+ths.eachWidth+'px'});
					}
				}
			$(ths.paging[ths.hide]).addClass('active');
			ths.fade();
			}
		else if( ths.hideController ){
			//hide controllers
			$(ths.paging).css({visibility:'hidden'});
			$(ths.nextId).css({visibility:'hidden'});
			$(ths.previousId).css({visibility:'hidden'});
			$(ths.pauseToggle).css({visibility:'hidden'});
			}
		}
	
	//easy swap function
	ths.swap = function(){
		ths.tmp = ths.hide;
		ths.hide = ths.show;
		ths.show = ths.tmp;
		}
		
	//main effect function
	ths.fade = function(){
		if( ths.interval )
			clearInterval(ths.interval);
		if( ths.isPrev && !ths.goingDirect ){
			if( ths.transition == 'fade' ) ths.swap();
			else if( ths.transition == 'slide' ) ths.show-=2;
			}
		if( ths.show > ths.elems.length-1 ) ths.show = 0;
		else if( ths.show < 0 ) ths.show = ths.elems.length-1;
		if( ths.hide > ths.elems.length-1 ) ths.hide = 0;
		else if( ths.hide < 0 ) ths.hide = ths.elems.length-1;
		ths.onChange(ths.show);
		if( ths.transition == 'fade' ){
			$(ths.elems[ths.hide]).fadeOut(ths.fadeTime);
			$(ths.elems[ths.show]).fadeIn(ths.fadeTime);
			}
		else{
			if( ths.topBottom ){
				if( ths.isPrev ){
					$(ths.elems[ths.show]).css({top:'-'+ths.eachHeight+'px'});
					$(ths.elems[ths.hide]).css({top:'0px'});
					$(ths.elems[ths.hide]).animate({top:'+'+ths.eachHeight+'px'},ths.fadeTime);
					$(ths.elems[ths.show]).animate({top:'0px'},ths.fadeTime);
					}
				else{
					$(ths.elems[ths.show]).css({top:'+'+ths.eachHeight+'px'});
					$(ths.elems[ths.hide]).css({top:'0px'});
					$(ths.elems[ths.hide]).animate({top:'-'+(ths.eachHeight+1)+'px'},ths.fadeTime);
					$(ths.elems[ths.show]).animate({top:'0px'},ths.fadeTime);
					}
				}
			else if( ths.diagonal ){
				if( ths.isPrev ){
					$(ths.elems[ths.show]).css({left:'+'+ths.eachWidth+'px',top:'-'+ths.eachHeight+'px'});
					$(ths.elems[ths.hide]).css({left:'0px',top:'0px'});
					$(ths.elems[ths.hide]).animate({left:'-'+ths.eachWidth+'px',top:'-'+ths.eachHeight+'px'},ths.fadeTime);
					$(ths.elems[ths.show]).animate({left:'0px',top:'0px'},ths.fadeTime);
					}
				else{
					$(ths.elems[ths.show]).css({left:'+'+ths.eachWidth+'px',top:'-'+ths.eachHeight+'px'});
					$(ths.elems[ths.hide]).css({left:'0px',top:'0px'});
					$(ths.elems[ths.hide]).animate({left:'-'+(ths.eachWidth+1)+'px',top:'-'+ths.eachHeight+'px'},ths.fadeTime);
					$(ths.elems[ths.show]).animate({left:'0px',top:'0px'},ths.fadeTime);
					}
				}
			else{
				if( ths.isPrev ){
					$(ths.elems[ths.show]).css({left:'-'+ths.eachWidth+'px'});
					$(ths.elems[ths.hide]).css({left:'0px'});
					$(ths.elems[ths.hide]).animate({left:'+'+ths.eachWidth+'px'},ths.fadeTime);
					$(ths.elems[ths.show]).animate({left:'0px'},ths.fadeTime);
					}
				else{
					$(ths.elems[ths.show]).css({left:'+'+ths.eachWidth+'px'});
					$(ths.elems[ths.hide]).css({left:'0px'});
					$(ths.elems[ths.hide]).animate({left:'-'+(ths.eachWidth+1)+'px'},ths.fadeTime);
					$(ths.elems[ths.show]).animate({left:'0px'},ths.fadeTime);
					}
				}
			}
		
		$(ths.paging[ths.hide]).removeClass('active');
		$(ths.paging[ths.show]).addClass('active');
		
		if( ths.isPrev && !ths.goingDirect ){
			if( ths.transition == 'slide' ){
				ths.show++;
				ths.hide = ths.show-1;
				}
			else{
				ths.swap();
				ths.show = ths.hide--;
				}
			}
		else{
			ths.hide = ths.show++;
			}
		ths.isPrev = false;
		ths.goingDirect = false;
		if( !ths.noAutoSlide ) ths.interval = setInterval(ths.fade,ths.waitTime);
		}
	//pause
	ths.pause = function(){
		clearInterval(ths.interval);
		ths.noAutoSlide = true;
		ths.onPause();
		}
	//for mouseover
	ths.pause2 = function(){
		clearInterval(ths.interval);
		ths.onPause();
		}
	//play
	ths.play = function(){
		clearInterval(ths.interval);
		ths.noAutoSlide = false;
		if( !ths.noAutoSlide ) ths.interval = setInterval(ths.fade,ths.waitTime);
		ths.onPlay();
		}
	//for mouseout
	ths.play2 = function(){
		clearInterval(ths.interval);
		if( !ths.noAutoSlide ) ths.interval = setInterval(ths.fade,ths.waitTime);
		ths.onPlay();
		}
	//next
	ths.next = function(){
		if( ths.transitionInterval ) return;
		ths.transitionInterval = setInterval(ths.clearTransition,ths.fadeTime);
		clearInterval(ths.interval);
		ths.fade();
		ths.onNext();
		}
	ths.prev = function(){
		if( ths.transitionInterval ) return;
		ths.transitionInterval = setInterval(ths.clearTransition,ths.fadeTime);
		clearInterval(ths.interval);
		ths.isPrev = true;
		ths.fade();
		ths.onPrevious();
		}
	//reset / clear transition
	ths.clearTransition = function(){
		clearInterval(ths.transitionInterval);
		ths.transitionInterval = null;
		}
	//external callback to go to specific index
	this.directGo2 = function(index){
		if( ths.transitionInterval ) return;
		ths.havToGo = index;
		if( ths.havToGo == ths.hide ) return; // same slide don't need to go
		ths.goingDirect = true;
		if( ths.havToGo < ths.show ) ths.isPrev = true;
		ths.show = ths.havToGo;
		ths.transitionInterval = setInterval(ths.clearTransition,ths.fadeTime);
		ths.fade();
		}
	//callback to go to index on click of paginator
	ths.directGo = function(){
		if( ths.transitionInterval ) return;
		for( i=0; i<ths.paging.length;i++)
			if( ths.paging[i] == this ) ths.havToGo = i;
		//ths.havToGo = $(this.tagName,$(this).parent()).index(this,$(this).parent());
		if( ths.havToGo == ths.hide ) return; // same slide don't need to go
		ths.goingDirect = true;
		if( ths.havToGo < ths.show ) ths.isPrev = true;
		ths.show = ths.havToGo;
		ths.transitionInterval = setInterval(ths.clearTransition,ths.fadeTime);
		ths.fade();
		}
	
	ths.init();
	
	this.stopAutoSliding = function(){
		clearInterval(ths.interval);
		ths.noAutoSlide = true;
		}
	this.startAutoSliding = function(){
		ths.noAutoSlide = false;
		clearInterval(ths.interval);
		$(ths.container).html($(ths.container).html());
		ths.init();
		}
	
	this.reInitialize = function(){
		clearInterval(ths.interval);
		$(ths.container).html($(ths.container).html());
		ths.init();
		}
	}
