// Based on jquery.jcarousellite.js
// http://www.gmarwaha.com/jquery/jcarousellite/index.php
// Adapted by Jonathan Puckey for bootStrap -  2007

Carousel = Base.extend({
	initialize: function(container, param){
		this.param = {
			btnPrev:	param.btnPrev || null,
			btnNext:	param.btnNext || null,
			btnGo:		param.btnGo || null,
//			mouseWheel:	param.mouseWheel || false,
			auto:		param.auto || null,
			speed:		param.speed || 200,
			vertical:	param.vertical || false,
			circular:	param.circular == null ? true : param.circular,
			visible:	param.visible || 3,
			start:		param.start,
			scroll:		param.scroll || 1,
			onStart:	param.onStart || null,
			onEnd:		param.onEnd || null,
			transition:	param.transition || Fx.Transitions.Expo,
			liWidth: param.liWidth || null,
			liHeight: param.liHeight || null
		};
		
		this.posStyle = this.param.vertical ? "top" : "left";
		this.sizeStyle = this.param.vertical ? "height" : "width";
		this.list = $("ul", container);
		this.listItems = $$("li", this.list);
		this.listLength = this.listItems.length;
		this.visible = this.param.visible;
		this.running = false;
		
		if(this.param.start == null || this.param.start == "first"){
			this.param.start = 0;
		}else if(this.param.start=="last"){
			this.param.start=this.listLength-this.visible;
		}
		
		if(this.param.circular) {
			var toPrepend = this.listItems.slice(this.listLength-this.visible-1,this.listLength);
			for(var i=toPrepend.length-1; i>0; i--){
				toPrepend[i].clone(true).insertFirst(this.list)
			}
			
			var toAppend = this.listItems.slice(0,this.visible);
			for(var i=0; i<toAppend.length; i++){
				toAppend[i].clone(true).insertInside(this.list)
			}
			
			this.param.start += this.visible;
		}
		
		var li = $$("li", this.list);
		this.listLength = li.length;
		this.currentIndex = this.param.start;

		container.setStyle("visibility", "visible");
		li.addClass("carousel-item")
		this.list.addClass("carousel-list")
		container.addClass("carousel-clip")
		// Full li size (incl margin) - Used for animation
		this.listSize = this.param.vertical ? this.param.liHeight || this.getFullHeight(li[0]) : this.param.liWidth || this.getFullWidth(li[0]);

		var ulSize = this.listSize * this.listLength;						// size of full ul(total length, not just for the visible items)
		var containerSize = this.listSize * this.visible;					// size of entire div(total length for just the visible items)

		li.setStyle("width", li[0].getSize().width)							// inner li width. this is the box model width
			.setStyle("height", li[0].getSize().height);					// inner li height. this is the box model height

		this.list.setStyle(this.sizeStyle, ulSize+"px")						// Width of the UL is the full length for all the images
			.setStyle(this.posStyle, -(this.currentIndex*this.listSize));	// Set the starting item

		container.setStyle(this.sizeStyle, containerSize+"px");				// Width of the DIV. length of visible images
		
		if(this.param.btnPrev)				 
			$(this.param.btnPrev).addEvent('click', function() {
				return this.goToPrevious(); 
			}.bind(this));

		if(this.param.btnNext)
			$(this.param.btnNext).addEvent('click', function() {
				return this.goToNext(); 
			}.bind(this));

		if(this.param.btnGo)
			$.each(this.param.btnGo, function(i, val) {
				$(val).click(function() {
					return this.go(this.param.circular ? this.param.visible+i : i);
				});
			});
		
		this.checkButtons();
		this.list.removeClass("carousel-hidden");
		if(this.param.auto){
			this.goToNext.bind(this).periodic(this.param.auto+this.param.speed);
		}
	},
	
	goToNext: function(){
		this.go(this.currentIndex+this.param.scroll);
	},
	
	goToPrevious: function(){
		this.go(this.currentIndex-this.param.scroll);
	},
	
	go: function(to) {
		if(!this.running) {
			if(this.param.onStart){
				this.param.onStart();
			}
			
			// If circular we are in first or last, then goto the other end
			// (this circular code is shocking and deserves to be fixed)
			if(this.param.circular) {
				// If first, then goto last
				if(to<=this.param.start-this.visible-1) {
					this.list.setStyle(this.posStyle, -((this.listLength-(this.visible*2))*this.listSize)+"px");  
					// If "scroll" > 1, then the "to" might not be equal to the condition; it can be lesser depending on the number of elements.
					if(to==this.param.start-this.visible-1){
						this.currentIndex = this.listLength-(this.visible*2)-1;
					}else{
						this.currentIndex = this.listLength-(this.visible*2)-this.param.scroll;
					}
				// If last, then goto first
				} else if(to>=this.listLength-this.visible+1) {
					this.list.setStyle(this.posStyle, -( (this.visible) * this.listSize ) + "px" );
					// If "scroll" > 1, then the "to" might not be equal to the condition; it can be greater depending on the number of elements.
					if(to==this.listLength-this.visible+1){
						this.currentIndex = this.visible+1;
					}else{
						this.currentIndex = this.visible+this.param.scroll;
					}
				} else this.currentIndex = to;
			} else {
				// If non-circular
				if(to<0){
					this.currentIndex=0;
				}else if(to>this.listLength-this.visible){
					this.currentIndex=this.listLength-this.visible;
				} else{
					this.currentIndex = to;
				}
			}	// If neither overrides it, the curr will still be "to" and we can proceed.

			this.running = true;

			var start = this.list.getStyle("left").toInt();

			var myEffect = this.list.effect(this.posStyle, {duration: this.param.speed, transition: this.param.transition});
			var from = this.posStyle == "left" ? this.list.getStyle("left") : this.list.getStyle("top");
			myEffect.start(from,-(this.currentIndex*this.listSize));
			myEffect.addEvent("complete", function(){
				this.running=false;
				if(this.param.onEnd){
					this.param.onEnd();
				}
			}.bind(this));
			
			// Disable buttons when the carousel reaches the last/first, and enable when not
			this.checkButtons();

		}
		return false;
	},
	
	//tofix: somehow el.getStyle doesn't work on Safari _all_ the time - no idea why..
	getFullWidth: function(el) {
		return  el.$.offsetWidth + el.getStyle('marginLeft').toInt() + el.getStyle('marginRight').toInt();
	},
	
	getFullHeight: function(el) {
		return el.$.offsetHeight + el.getStyle('marginTop').toInt() + el.getStyle('marginBottom').toInt();
	},
	
	checkButtons: function(){
		if(!this.param.circular) {
			if(this.param.btnPrev){
				this.param.btnPrev.removeClass("carousel-disabled");
				if(this.currentIndex==0){
					this.param.btnPrev.addClass("carousel-disabled");
				};
			};
			
			if(this.param.btnNext){
				this.param.btnNext.removeClass("carousel-disabled");
				if(this.currentIndex+this.param.scroll > this.listLength-1){
					this.param.btnNext.addClass("carousel-disabled");
				}
			}
		}
	}
})
