//  K3VerticalCarousel 1.1.0
//  by Nicolas Janik - http://www.k3media.com
//  and Danny Turcotte - http://www.k3media.com
//  2008-09-24
//
//  Licensed under the Creative Commons Attribution 3.0 License
//  http://creativecommons.org/licenses/by/3.0/
//            

          
var k3VerticalCarousel = Class.create();  
k3VerticalCarousel.prototype = {
 
 
	initialize: function(ul, options) {
		
		this.ul = $(ul);
		this.lis = this.ul.select("li");
		
		this.optionsDefault = $H({

			class_previous_button:'previous_button',
			class_previous_button_disabled:'previous_button_disabled',
			class_next_button:'next_button',
			next_button_content:'Next',
			previous_button_content:'Previous',
			class_next_button_disabled:'next_button_disabled',
			class_container_number_link:'number_link_container',
			withBtn:true,
			scrollbar:false,
			numberLink:false,
			showOnlyOne:false,
			step:50,
			slider:false,
			ulH:0,
			time:500 //ms
		});          
		
		
		this.options=this.optionsDefault.merge(options);  
		


		
		if(this.options.get("numberLink")==true){
	
			var containerLink = new Element('div',{'className':this.options.get("class_container_number_link")});
			this.lis.each(function(li,index){
				//console.debug(li);
				var btn = new Element('a',{href:'#'});
				btn.update(index+1);
				btn.onclick=function(){
					this.scrollToElement(this.lis[index]);
					return false;	
				}.bind(this);
				containerLink.appendChild(btn);
				
			}.bind(this));
			Element.insert(this.ul, {before:containerLink});
		

		}		
		
		
		
		
		if(this.options.get("withBtn")==true){
	
			var btnprev = new Element('div',{'className':this.options.get("class_previous_button"),style:'cursor:hand;cursor:pointer;'});
			btnprev.onclick =function(){this.scrollToPreviousElement()}.bind(this);
			btnprev.update(this.options.get("previous_button_content"));
		
			Element.insert(this.ul, {before:btnprev});
			
			var btnnext = new Element('div',{'className':this.options.get("class_next_button"),style:'cursor:hand;cursor:pointer;'});
			btnnext.onclick =function(){this.scrollToNextElement()}.bind(this);
			btnnext.update(this.options.get("next_button_content"));
		
			Element.insert(this.ul, {after:btnnext});
		}
		



		
		this.ulH =parseInt(this.options.get("ulH")?this.options.get("ulH"):this.ul.getHeight());
		Element.setStyle(this.ul,{height:this.ulH+"px"});


		if(this.options.get("slider")==true){
		
			var container = new Element('div',{style:"position:relative;width:"+this.ul.getStyle("width")});
			Element.insert(this.ul, {after:container});
			
			this.ul.parentNode.removeChild(this.ul);
			container.appendChild(this.ul);
			var ulHeight = this.ulH;
			if(navigator.appVersion.indexOf('MSIE 6') !=-1){
				ulHeight =parseInt(Element.getStyle(this.ul,'height'));
			}

			var track = new Element('div',{id:this.ul.id+"_track", style:'background-color:#efefef;width:10px;height:'+ ulHeight +'px;position:absolute;right:0;top:0'});
			container.appendChild(track);
			
			var handle = new Element('div',{id:this.ul.id+"_handle", style:'background-color:gray;width:10px;height:16px;position:relative;'});
			track.appendChild(handle);
			
			var sliderWidth = 16;
			var newUlWidth = parseInt(this.ul.getStyle("width"))-sliderWidth + "px";

			Element.setStyle(this.ul,{width:newUlWidth});

			
			
			this.slider = new Control.Slider(this.ul.id+"_handle", this.ul.id+"_track", {
				axis: 'vertical',
				onSlide: function(v) { this.ul.scrollTop = Math.round(v/this.slider.maximum*(this.ul.scrollHeight-this.ul.offsetHeight)) }.bind(this),
				onChange: function(v) {this.ul.scrollTop = Math.round(v/this.slider.maximum*(this.ul.scrollHeight-this.ul.offsetHeight)) }.bind(this)
			});
		}		
		
		
		
		if(this.options.get("scrollbar")==true){
			Element.setStyle(this.ul,{overflow:'auto'});
		}else{
			Element.setStyle(this.ul,{overflow:'hidden'});
		}
		
		

		this.firstLi = this.lis[0];
		this.lastLi = this.lis[this.lis.length-1];
		if(this.options.get("showOnlyOne")==true){
			this.maximizeLis();
		}
	},
	
	
	
	_updateScroll: function(){

		if(this.options.get("slider")==true){
			var v = this.ul.scrollTop;

			if (v == '') return;
			if (isNaN(v)){
				this.slider.setValue(0);
			}else{
				this.slider.setValue(v/(this.ul.scrollHeight-this.ul.offsetHeight));
			}
		}	
	},
	
	
	
	
	scrollToElement: function(id){

		var li = $(id);
		this.currentElement = li;
		var y = li.y ? li.y : li.offsetTop;
		this._finalScrollPosition = (y-(document.all?0:this.ul.offsetTop)-this.ul.scrollTop);		
		this._incr =  this._finalScrollPosition/ this.options.get("step");
		this._scrollTop = this.ul.scrollTop;
		this._i = 0;
		this._scroll();

	},
	

	_scroll: function(){
		this._updateScroll();
		//Put in a var in order to keep the decimal
		this._i++;
		this._scrollTop += this._incr;
		this.ul.scrollTop=this._scrollTop;
		if(this._i <= this.options.get("step")){
			setTimeout(function(){this._scroll()}.bind(this),Math.round(this.options.get("time")/this.options.get("step")));
		}

	},	
	
	scrollToPreviousElement: function(){
		var withMargin = false;
		var el = this.getPreviousElement(withMargin);
		if(el){
			return this.scrollToElement(el);
		}
		return false;
	},	
	
	scrollToNextElement: function(){
		var withMargin = false;
		var el = this.getNextElement(withMargin);
		if(el){
			return this.scrollToElement(el);
		}
		return false;
	},
	
	
	getNextElement:function(withMargin){
		var nothingToScroll = false;

		this.currentElement = null;
		this.lis.each(
			function(li){

				if(this.currentElement==null){
					switch(this.getVisibleState(li,withMargin,0)){
						case "top":

							this.currentElement = li.next('li');
							if(this.currentElement == null){
								nothingToScroll=true;
							}

						break;
						
						case "bottom":
							if(this.getLiPositionTop(li,withMargin)==this.getScroll()){
								this.currentElement = li.next('li');
							}else{
								this.currentElement = li;
							}
						break;
						case "both":

							this.currentElement = li.next('li');
							if(this.currentElement == null){
									nothingToScroll=true;
							}

						break;
						default:

					}
				}
			}.bind(this)
		
		);
		if(this.currentElement==null && !nothingToScroll){
			if(this.lis.length>1){
				this.currentElement = this.getFirstLiHiddenTop(withMargin).next('li');
			}
		}
		return this.currentElement;
	},
	
	
	getPreviousElement:function(withMargin){
		var nothingToScroll = false;
		this.currentElement = null;
		this.lis.each(

			function(li){
				if(this.currentElement==null){
					switch(this.getVisibleState(li,withMargin,-0)){
						case "top":

							this.currentElement = li;
						break;
						case "bottom":

							this.currentElement = li.previous('li');
							if(this.currentElement == null){
								nothingToScroll=true;
							}							
						break;

						case "both":



							if(this.isLibiggerThanUl(li,withMargin) && this.getLiPositionTop(li,withMargin)<this.getScroll() && this.getLiPositionBottom(li,withMargin)>this.getScroll()+this.ulH && this.getScroll()- this.getLiPositionTop(li,withMargin)>10){

								this.currentElement = li;
							}else{
								this.currentElement = li.previous('li');
								if(this.currentElement == null){
									nothingToScroll=true;
								}								
							}
						break;
					}
				}
			}.bind(this)
		
		);
		if(this.currentElement==null && !nothingToScroll){
			this.currentElement = this.getFirstLiHiddenTop(withMargin);
		}
		return this.currentElement;
	},
	
	
	getScroll:function(){
		return this.ul.scrollTop;
	},
	
	getLiPositionTop: function(li,withMargin){
		var tmp = 0;
		if(withMargin){
			tmp =parseInt(li.getStyle("margin-top"))+Math.ceil(parseFloat(li.getStyle("border-top-width")));
		}
		return (li.y ? li.y : li.offsetTop)-(document.all?0:this.ul.offsetTop)-tmp;
	},
	
	
	getLiPositionBottom: function(li,withMargin){
		var tmp = 0;
		if(withMargin){
			tmp =parseInt(li.getStyle("margin-bottom"))+Math.ceil(parseFloat(li.getStyle("border-bottom-width")));
		}
		return this.getLiPositionTop(li,false)+li.getHeight()+tmp;
	},
	
	
	isLibiggerThanUl: function(li,withMargin){
		if(!withMargin){
			return (li.getHeight()>this.ulH);
		}else{
			return (li.getHeight()+li.getStyle("margin-top")+li.getStyle("margin-bottom")+Math.ceil(parseFloat(li.getStyle("border-top-width")))+Math.ceil(parseFloat(li.getStyle("border-bottom-width")))>this.ulH);
		}
	},
	
	isLiCompletlyVisible: function(li,withMargin){
		return (this.isLiTopVisible(li,withMargin) && this.isLiBottomVisible(li,withMargin));
	},
	
	isLiTopVisible: function (li,withMargin){
		var liPosition =  this.getLiPositionTop(li,withMargin);
		return (liPosition>=this.getScroll() && liPosition<this.getScroll()+this.ulH );
	},
	
	isLiBottomVisible: function (li,withMargin){
		var liPosition =  this.getLiPositionBottom(li,withMargin);
		return (liPosition>=this.getScroll() && liPosition<this.getScroll()+this.ulH );
	},
	
	getFirstLiHiddenTop: function(withMargin){
		//parcourir les lis a lenvers, premier que sont bottom et top sont plus petits que le getScroll
		for(var k = this.lis.length-1;k>=0;k--){
			var li = this.lis[k];
			if(this.getLiPositionTop(li,withMargin)< this.getScroll() && this.getLiPositionBottom(li,withMargin)<= this.getScroll() ){
				return li
			}
		}
		return false
	},
	
	getVisibleState: function(li,withMargin,threshold){
		var b = this.getLiPositionBottom(li,withMargin)+(threshold);
		var t = this.getLiPositionTop(li,withMargin)-(threshold);

		if((b<this.getScroll() && t<this.getScroll()) || (b>this.getScroll()+this.ulH && t>this.getScroll()+this.ulH)){
			return "hidden";			
		}
		if(b>this.getScroll()+this.ulH && t>=this.getScroll() && t<this.getScroll()+this.ulH){
			return "bottom";
		}
		if(t<=this.getScroll() && b>this.getScroll() && b<this.getScroll()+this.ulH){
			return "top";
		}

		return "both";
		
	},
	
	
	maximizeLis: function(){
		this.lis.each(function(li){
			if(li.getHeight() < this.ulH){
				Element.setStyle(li,{height:this.ulH+"px"})
			}
		}.bind(this)
		);	
	}
}
