/* Carousel Created by Kevin Dibble
Useage: 
	Add a class of animate to the div area
	insert the elements inside the area to animate with a class of "anime"
	To have images pre-load insert a div tage with a class of "anime" and "image" and use the rel tag to point to the image path
Example:
<div class="animate" rel="{effect: 'slide', delay : 5000, effectTime : 'long', pauseButton : 'pause', nextButton : 'next', backButton : 'last'}">
 <img src="../js/quotes/quote1_03.png" width="443" height="310" alt="quote" class="anime"/>
            <p class="anime image" rel="css/images/icons/arrow_up.png">Image</p>
            <p class="anime image" rel="css/images/icons/bullet_delete.png">image</p>
            <p class="anime image" rel="css/images/icons/error.png">image</p>
            <p class="anime image" rel="css/images/icons/page_excel.png">image</p>
            <p class="anime image" rel="css/images/icons/page_word.png">image</p>
            <p class="anime ajax"  rel="index.php">some text</p>

*/

ImageScale = new Class({
	Implements 	: [Options],
	Binds		: ['scale'],
	options : {
		autoCenter 	: true,
		scaleWidth  : true,
		scaleHeight : true,
		apply		: true,
		width		: 100,
		height		: 100,
		path		: 'auto',
		container	: null
	},
	newWidth		: 100,
	newHeight		: 100,
	topMargin		: 0,
	leftMargin		: 0,
	percentage		: 1,
	initialize: function(obj,options){
		this.setOptions(options);
		this.options.path = (this.options.path!='auto')?this.options.path : $(obj).get("rel");
		if($(obj).get("tag").contains("img")){
			this.object = $(obj);
			this.scale();
		}else{
			$(obj).empty();
			this.object = new Asset.image(this.options.path,{onload: this.scale});
			$(this.object).inject($(obj),"top");
		}
	},
	scale: function(){
		if(this.options.scaleWidth){
			if ($(this.object).getSize().x > this.options.width){
				this.percentage = (this.options.width / $(this.object).getSize().x);
			}
		}
		if(this.options.scaleHeight){
			if (($(this.object).getSize().y * this.percentage) > this.options.height){
				this.percentage = (this.options.height / $(this.object).getSize().y);
			}
		}
		this.newWidth  = $(this.object).getSize().x  * this.percentage;
		this.newHeight = $(this.object).getSize().y  * this.percentage;
		if(this.options.autoCenter){
			this.center();	
		}
		if(this.options.apply){
			this.apply();	
		}
	},
	center:function(){
		this.leftMargin = (this.options.width-this.newWidth)   / 2;
		this.topMargin  = (this.options.height-this.newHeight) / 2;
	},
	apply: function(){
		$(this.object).setStyles({"width" : this.newWidth, "height":this.newHeight, "margin-left" : this.leftMargin, "margin-top" : this.topMargin});
	}
});
	
	
Animator = new Class({
	Implements 	: [Options],
	objects 	: [],
	images		: [],
	options: {
		className   : 'animate',
		subClass    : 'anime',
		effect		: 'fade',   // [fade | slide | up | nothing ]
		pauseButton : null,
		nextButton  : null,
		backButton  : null,
		autoStart	: true,
		delay		: 4000,
		effectTime  : 'short',
		autoCenter	: true,
		scaleWidth  : true,
		scaleHeight : true,
		playText	: '&gt;',
		pauseText	: '||',
		playOnce	: false,
		directBtn 	: false		// Set this to a class to create direct buttons for the animation effect
	},
	initialize: function(obj,options){
		this.setOptions(options);
		this.object = obj;
		this.width 	 = $(this.object).getSize().x;
		this.height  = $(this.object).getSize().y;
		this.left    = $(this.object).getPosition($(this.object).getParent()).x;
		this.top   	 = $(this.object).getPosition($(this.object).getParent()).y;
		var position = ($(this.object).getStyle("position") != "absolute")? 'relative' : "absolute";
		$(this.object).setStyles({
			'overflow':"hidden",
			'position' : position
		});
		this.objects = $(this.object).getElements("."+this.options.subClass);
		this.aniLeft = $(this.object).getStyle("padding-left").toInt();
		this.aniTop  = $(this.object).getStyle("padding-top").toInt();
		this.width	 = this.width - ($(this.object).getStyle("padding-left").toInt() + $(this.object).getStyle("padding-right").toInt());
		this.height	 = this.height - ($(this.object).getStyle("padding-top").toInt() + $(this.object).getStyle("padding-bottom").toInt());
		if($(this.object).get("rel")){
			if($(this.object).get("rel") && $(this.object).get("rel").contains('{') && $(this.object).get("rel").contains('}')){
				try{
					eval("this.setOptions("+($(this.object).get("rel").substring($(this.object).get("rel").indexOf('{'),$(this.object).get("rel").lastIndexOf('}')+1))+")");
				}catch(e){};
			}
		}
		if($(this.object).get("title")){
			if($(this.object).get("title") && $(this.object).get("title").contains('{') && $(this.object).get("title").contains('}')){
				try{
					eval("this.setOptions("+($(this.object).get("title").substring($(this.object).get("title").indexOf('{'),$(this.object).get("title").lastIndexOf('}')+1))+")");
				}catch(e){};
				$(this.object).set("title","");
			}
		}
		if(this.options.directBtn != false){
			var jumpToImage = this.jumpToImage.bind(this);
			$$(this.options.directBtn).each(function(item){
				//$(item).set("rel",$(item).get("title"));
				//$(item).set("title","");
				item.addEvent("click",function(){
					jumpToImage(this.get("rel"));							   
				});
			},this);
		}
		this.timer  = null;
		this.current = 0;
		this.setUpObjects();
		if($(this.options.pauseButton)){
			var pause = this.pause.bind(this);	
			$(this.options.pauseButton).addEvent("click",pause);
			this.options.playText = ($(this.options.pauseButton).get("html").clean() != "")?$(this.options.pauseButton).get("html")  : this.options.playText;
		}
		if($(this.options.nextButton)){
			var next = this.next.bind(this);	
			$(this.options.nextButton).addEvent("click",next);
		}
		if($(this.options.backButton)){
			var last = this.last.bind(this);	
			$(this.options.backButton).addEvent("click",last);
		}
		if(this.options.autoStart){
			this.play();
		}
	},
	jumpToImage : function(num){
		$clear(this.timer);
		if(this.object){
			this.doEffect(this.objects[this.current],"out");
			this.current = parseInt(num);
			if(this.current > this.objects.length -1){
				this.current = 0;
			}
			this.doEffect(this.objects[this.current],"in");
		}else{
			this.remove();	
		}
		this.updateIcons();
	},
	updateIcons:function(){
		// Get all icons
		$$('.directButtons').each(function(item,index){
			if(this.current == 0 || this.current == item.get("rel").toInt()){
				item.removeClass("fade");
				item.addClass("current");
			}else{
				item.removeClass("current");
				item.addClass("fade");
			}
		},this);
	},
	remove : function(){
		$clear(this.timer);
	},
	setUpObjects: function(){
		this.objects.each(function(item,index){
			var opaque = (index==0)? 1 : 0;
			item.removeClass("hide");
			var tmpWidth   = this.width - (item.getStyle("padding-left").toInt() + item.getStyle("padding-right").toInt() + item.getStyle("margin-left").toInt() + item.getStyle("margin-right").toInt());
			var tmpHeight  = this.height - (item.getStyle("padding-top").toInt() + item.getStyle("padding-bottom").toInt() + item.getStyle("margin-top").toInt() + item.getStyle("margin-bottom").toInt());
			item.set("morph",{duration: this.options.effectTime});
			if(item.get("tag").contains("img")){
				new ImageScale(item,{
					height:		(tmpHeight - this.aniTop),
					width:		(tmpWidth - this.aniLeft),
					autoCenter: this.options.autoCenter,
					scaleWidth: this.options.scaleWidth,
					scaleHeight: this.options.scaleHeight
				});
				item.setStyles({
					position 	:'absolute',
					opacity		: opaque,
					top			: this.aniTop,
					left		: this.aniLeft,
					overflow	: "hidden"
				});
			}else{
				if(item.hasClass("image")){
					new ImageScale(item,{
						height:		(tmpHeight - this.aniTop),
						width:		(tmpWidth - this.aniLeft),
						autoCenter: this.options.autoCenter,
						scaleWidth: this.options.scaleWidth,
						scaleHeight: this.options.scaleHeight
					});	
				}
				item.setStyles({
					position 	:'absolute',
					opacity		: opaque,
					top			: this.aniTop,
					left		: this.aniLeft,
					width		: tmpWidth,
					height		: tmpHeight,
					overflow	: "hidden"
				});
			}
			if(item.hasClass("ajax")){
				var me = item;
				var rm = this.removeLoader.bind(item);
				item.set("load",{'url':item.get("rel"),"method": "post",data:{"ajax" : "yes"},onComplete:rm});
			}
		},this);
	},
	removeLoader: function(){
		this.removeClass("loader");
	},
	doNext: function(){
		if(this.object){
			this.doEffect(this.objects[this.current],"out");
			this.current++;
			if(this.current > this.objects.length -1){
				this.current = 0;
				if(this.options.playOnce == true){
					$clear(this.timer);
				}
			}
			this.doEffect(this.objects[this.current],"in");
		}else{
			this.remove();	
		}
		this.updateIcons();
	},
	next: function(){
		this.navPause();
		this.doNext();
	},
	last: function(){
		this.navPause();
		this.doReverse(this.objects[this.current],"in");
		this.current--;
		if(this.current < 0){
			this.current = (this.objects.length -1);
		}
		this.doReverse(this.objects[this.current],"out");
	},
	loadAjax: function(object){
		$(object).set("html","");
		$(object).addClass("loader");
		$(object).load($(object).get("rel"));	
		$(object).removeClass("ajax");
	},
	doEffect: function(object,direction){
		var dir		= direction || "in";
		if(dir=="in" && $(object).hasClass("ajax")){
			this.loadAjax(object);
		}
		var width 	= $(object).getSize().y;
		var height 	= $(object).getSize().x;
		switch(this.options.effect){
			case "slideLeft":
			case "slide":
			case "left":
			case "horizontal":
				if(dir == "in"){
					object.morph({"left" : [(this.width + this.left), this.aniLeft],"opacity" :1});
				}else{
					object.morph({"left" : [this.aniLeft, -(this.left + width)],"opacity" : 0});	
				}
			break;
			case "vertical":
			case "up":
			case "down":
				if(dir == "in"){
					object.morph({"top" : [this.top - height, this.aniTop],"opacity" :1});
				}else{
					object.morph({"top" : [this.aniTop,+(this.top + this.height)],"opacity" : 0});	
				}
			break;
			case "nothing":
				if(dir == "in"){
					object.set("opacity",1);	
				}else{
					object.set("opacity",0);
				}
				break;
			case "fade":
			default:
				var opacity = (dir=="in")? 1 : 0;
				object.morph({"opacity" : opacity, "z-index": opacity});
			break;
		}	
	},
	doReverse: function(object,direction){
		var dir		= direction || "out";
		if(dir=="out" && $(object).hasClass("ajax")){
			this.loadAjax(object);
		}
		var width 	= $(object).getSize().y;
		var height 	= $(object).getSize().x;
		switch(this.options.effect){
			case "slideLeft":
			case "slide":
			case "left":
			case "horizontal":
				if(dir == "in"){
					object.morph({"left" : [this.aniLeft, (this.left + this.width)],"opacity" : 0});
				}else{
					object.morph({"left" : [-(this.left + width),this.aniLeft],"opacity" :1});
				}
			break;
			case "vertical":
			case "up":
			case "down":
				if(dir == "in"){
					object.morph({"top" : [this.aniTop,-(this.top + height)],"opacity" : 0});	
				}else{
					object.morph({"top" : [(this.top + this.height), this.aniTop],"opacity" :1});	
				}
			break;
			case "nothing":
				if(dir == "in"){
					object.set("opacity",0);	
				}else{
					object.set("opacity",1);
				}
				break;
			case "fade":
			default:
				var opacity = (dir=="in")? 0 : 1;
				object.morph({"opacity" : opacity});
			break;
		}	 
	},
	navPause: function(){
		$clear(this.timer);
		this.timer = null;
		if($(this.options.pauseButton)){
			$(this.options.pauseButton).removeClass('ani-play');
			$(this.options.pauseButton).addClass('ani-pause');
			$(this.options.pauseButton).set("html",this.options.playText);
		}
	},
	pause: function(){
		if(this.timer){
			this.navPause();
		}else{
			this.doNext();
			this.play();
		}
	},
	play : function(){
		this.timer = this.doNext.periodical(this.options.delay,this);
		if($(this.options.pauseButton)){
			$(this.options.pauseButton).addClass('ani-play');
			$(this.options.pauseButton).removeClass('ani-pause');
			$(this.options.pauseButton).set("html",this.options.pauseText);
		}
	}
});
var AnimatorControl = {
	animations : [],
	init: function(){
		$$('.animate').each(function(item,index){
			AnimatorControl.animations.push(new Animator(item));						 
		});
	},
	remove: function(){
		AnimatorControl.animations.each(function(item,index){
			item.remove();
		});	
	}
}
window.addEvent("load",AnimatorControl.init);