/**
 * Table Sorting Control
 * @author Paul Serby 
 */
RumbleUI.TableSorter = Class.create();
RumbleUI.TableSorter.applyToAll = function(parentElement, requiredClassName) {
	if (parentElement == null) {
		parentElement = document.body;
	}
	var tables = parentElement.getElementsBySelector("table");
	tables.each(function(table) {
		if (requiredClassName) {
			if (!table.hasClassName(requiredClassName)) {
				return false;
			}
		}
		
		new RumbleUI.TableSorter(table);
	});
}

RumbleUI.TableSorter.prototype = {
	initialize: function(element, options) {
	
		if (element.rumbleTableSorter) {
			return false;
		}
		element.rumbleTableSorter = true;
		
		this.options = {
      className: "textbox"
    };
    
    Object.extend(this.options, options || { });
    
		this.element = $(element);
		var tbody;
		if (tbody = this.element.getElementsBySelector("tbody").first()) {
			this.element = tbody;
		}
		this.header = [];
		this.tableData = [];
		this.currentSortColum = 0;
		this.setupTable(this.element);
	},	
	
	setupTable: function() {
		this.element.getElementsBySelector("tr").each((function(row) {
			var headerRow = row.getElementsBySelector("th");
			if (headerRow) {				
				var column = 0;
				headerRow.each((function(cell, column) {
					this.header.push(cell);
					cell.originalHTML = cell.innerHTML;
					cell.onclick = (function(column, event) {
						this.sort(column);
					}).bind(this, column);
					column++;					
				}).bind(this));				
			}
			var dataRow = row.getElementsBySelector("td")
			if (dataRow) {
				var data = [];	
				dataRow.each(function(cell) {
					data.push(cell.innerHTML);
				});
				if (data.length > 0) {
					this.tableData.push({ tableRow: row, data: data });
				}
			}
		}).bind(this));
	},
	
	addOrderIndicator: function(column, ascending) {
		this.clearOrderIndicator(column);
		this.header[column].innerHTML += ascending ? "&#9662;" : "&#9652;";
	},
	
	clearOrderIndicator: function(column) {
		this.header[column].innerHTML = this.header[column].originalHTML;
	},
	
	sort: function(column) {		
		var sortedData = this.tableData.sortBy((function(object) {		
			return this.bestGuessValue(object.data[column]);
		}).bind(this));
		
		if (this.currentSortColum == column) {
			this.ascending = !this.ascending;
		} else {
			this.ascending = true;
			this.clearOrderIndicator(this.currentSortColum);
			this.currentSortColum = column;
		}
		
		this.addOrderIndicator(column, this.ascending);
		
		if (this.ascending) {
			sortedData = sortedData.reverse();
		}
		
		var node = this.element.childNodes[1];
		sortedData.each((function(data) {
			this.element.insertBefore(data.tableRow, node);
			node = data.tableRow;
		}).bind(this));
	},
	
	bestGuessValue: function(value) {
		
		if (isNaN(value)) {
			var date = new Date(value);
			if (!isNaN(date.getTime())) {
				return date.getTime();
			}
			var newValue = value.replace(/[^0-9.]/g, "");
			if (!isNaN(newValue)) {
				return parseFloat(newValue, 10);
			} else if (newValue == "") {
				return value;
			} else {
				return newValue;
			}
		} else {
			return parseFloat(value, 10);
		}
	}
}

/**
 * 
 */
RumbleUI.BaseExpander = Class.create();
RumbleUI.BaseExpander.prototype = {
	expanding: false,
	enabled: true,
  initialize: function(toggleSwitch, panel, params) {
		  	
  	if (!params) {
  		params = {};
  	}

		params.duration = params.duration ? params.duration :  0.2;  	
  	params.startVisible = params.startVisible != undefined ? params.startVisible : true;
  	params.expandedSwitchClass = params.expandedSwitchClass ? params.expandedSwitchClass : "expander-expanded";
  	params.afterFinish = params.afterFinish ? params.afterFinish :  function() {};
  	params.eventType = params.eventType ? params.eventType :  "click";
  	params.inDelay = params.inDelay ? params.inDelay : 0;
  	params.autoHideTimeout = params.autoHideTimeout ? params.autoHideTimeout :  0.5;
  	params.inEffect = params.inEffect ? params.inEffect : "blind";
  	params.outEffect = params.outEffect ? params.outEffect : "blind" ;
			
		if ((toggleSwitch) && (panel)) {
		
			if ((params.eventType == "mouseover") && (window.mouseX == undefined)) {
				Event.observe(document, "mousemove", function(event) { 
	   			window.mouseX = Event.pointerX(event);
	   			window.mouseY = Event.pointerY(event);
	   		});
	   	}
		
			if (params.startVisible) {
				panel.show();
				toggleSwitch.addClassName(params.expandedSwitchClass);
			} else {
				panel.hide();
				toggleSwitch.removeClassName(params.expandedSwitchClass);
			}
			
			var togglePanelVisiblity = (function(event) {
				if (this.enabled && !this.expanding) {
					
					var afterFinish = (function(obj) {
						params.afterFinish(obj);
						this.expanding = false;
					}).bind(this);
					
					if (panel.visible()) {
						if (params.eventType != "mouseover") {
							toggleSwitch.removeClassName(params.expandedSwitchClass);
												
							this.expanding = true;
							new Effect.BlindUp(panel, { duration: params.duration, afterFinish: afterFinish });
						}
					} else {					
												
						if (params.eventType == "mouseover") {				
						
							if (!this.pe1) {
								this.pe1 = new PeriodicalExecuter((function(pe) {
									var over =  
									Position.within(panel, window.mouseX, window.mouseY) ||
									Position.within(toggleSwitch, window.mouseX, window.mouseY);
																		
									if (this.enabled && panel.visible() && !over && !this.expanding) {
										this.expanding = true;
										
										new Effect.BlindUp(panel, { duration: params.duration, afterFinish: afterFinish });
										this.pe1.stop();
										this.pe1 = null;
										toggleSwitch.removeClassName(params.expandedSwitchClass);
									} 
									
									
								}).bind(this), params.autoHideTimeout);
							}
						}	
						
						var afterFinish = (function(obj) {
							params.afterFinish(obj);
							this.expanding = false;
						}).bind(this);
						
						if (params.inDelay > 0) {
							var pe2 = new PeriodicalExecuter((function() {
								var over = Position.within(toggleSwitch, window.mouseX, window.mouseY);				
								if (this.enabled && over && !this.expanding) {
									this.expanding = true;
									toggleSwitch.addClassName(params.expandedSwitchClass);									
									new Effect.BlindDown(panel, { duration: params.duration, afterFinish: afterFinish });
								}
								pe2.stop();
							}).bind(this), params.inDelay);
						} else {
							if (this.enabled) {
								toggleSwitch.addClassName(params.expandedSwitchClass);
								this.expanding = true;
								new Effect.BlindDown(panel, { duration: params.duration, afterFinish: afterFinish });
							}
						}						
					}
				}
			}).bind(this);
							
			Event.observe(toggleSwitch, params.eventType, togglePanelVisiblity);
		}
	},
	isOver: function(parent) {
		var over = false;
		if (parent.childNodes) {
			for (var i = 0; i < parent.childNodes.length; i++) {
				over = over || Position.within(parent.childNodes[i], window.mouseX, window.mouseY);
				if (parent.childNodes[i].childNodes) {
					over = over || this.isOver(parent.childNodes[i]);
				}	
			}
		}
		return over;
	}
}

RumbleUI.Expander = Class.create();
RumbleUI.Expander.prototype = {
	expanding: false,
	
  initialize: function(element, params) {
  	element = $(element);
		var panels = $A(element.getElementsByClassName("expander-panel"));
		var toggleSwitches = $A(element.getElementsByClassName("expander-switch"));
		for (var i = 0; i < toggleSwitches.length; i++) {
			new RumbleUI.BaseExpander(toggleSwitches[i], panels[i], params);	
		}		  
	}
}  

RumbleUI.Accordion = Class.create();
RumbleUI.Accordion.prototype = {

	initialize: function(element, params) {
  	element = $(element);
  	
  	var panels = element.getElementsByClassName("accordion-panel");
		if (!panels) {
			return false;
		}
  	
  	if (!params) {
  		params = {};
  	}

		params.duration = params.duration ? params.duration :  0.2;  	
  	params.visibleElement = params.visibleElement ? $(params.visibleElement) : null;
  	params.expandedSwitchClass = params.expandedSwitchClass ? params.expandedSwitchClass : "accordion-expanded";
  	params.afterFinish = params.afterFinish ? params.afterFinish :  function() {};

		var switches = element.getElementsByClassName("accordion-switch");

		for (i = 0; i < panels.length; i++) {
			if (params.visibleElement == panels[i]) {
				element.currentSwitch = switches[i];
				element.currentExpanded = panels[i];
				element.currentSwitch.addClassName(params.expandedSwitchClass);
			} else {
				panels[i].hide();
			}
		}

		for (i = 0; i < switches.length; i++) {
			switches[i].panel = panels[i];
		}

		var accordionFunction = function() {
			if (element.currentExpanded == this.panel) {
				if (params.allowClose && element.currentExpanded) {
					new Effect.BlindUp(this.panel, { duration: params.duration, afterFinish: params.afterFinish });
					element.currentSwitch.removeClassName(params.expandedSwitchClass); 
					element.currentSwitch = null;
					element.currentExpanded = null;				
				}		
			}	else {
				if (element.currentExpanded) {
					new Effect.Parallel(
		      [
		          new Effect.BlindUp(element.currentExpanded),
		          new Effect.BlindDown(this.panel)
		      ], { duration: params.duration, afterFinish: params.afterFinish });
		      element.currentSwitch.removeClassName(params.expandedSwitchClass); 
				} else {
					new Effect.BlindDown(this.panel, { duration: params.duration, afterFinish: params.afterFinish });
				}		      
	      this.addClassName(params.expandedSwitchClass);
  			element.currentSwitch = this;
				element.currentExpanded = this.panel;
			}					 
		}
		
		$A(switches).each(function(currentSwitch) {
			Event.observe(currentSwitch, "click", accordionFunction.bind(currentSwitch));
		});
  }
}

/**
 * Text Ticker Widget
 * @author Paul Serby - Tom Smith 
 */
RumbleUI.Ticker = Class.create();
RumbleUI.Ticker.prototype = {
  
	initialize: function(element, text, params) {
	
		if (!params) {
			params = {};
		}
		 
		params.speed = params.speed ? params.speed :  0.08;	
		params.movement = params.movement ? params.movement :  5;					
		params.slowOnHover = params.slowOnHover ? params.slowOnHover : true;
		params.stopOnClick = params.stopOnClick ? params.stopOnClick : false;
		 	
		element = $(element)
			
		if (!element) {
			return false;
		}
			
		element.style["overflow"] = "hidden";
			
		var innerDiv = document.createElement("div");
		var measureDiv = document.createElement("div");
			
		measureDiv.innerHTML = text.stripTags().replace(/\s/g, "&nbsp;");
			
		innerDiv.innerHTML = text;
			
		measureDiv.style["position"] = "absolute";
		measureDiv.style["display"] = "none";
			
					    	
		innerDiv.style["position"] = "";
			
		element.appendChild(innerDiv);
		element.appendChild(measureDiv);
		
		Element.extend(measureDiv); 
		Element.extend(innerDiv);
		
		var outerWidth = element.getWidth() + 50;   	
		var pos = outerWidth;
		var width = measureDiv.getWidth();
			
		innerDiv.style["width"] = width + "px";
		innerDiv.style["marginLeft"] = pos + "px";
			
		var isStopped = false;
			
		var originalMovement = params.movement;
			
		if (params.slowOnHover) {
		 	innerDiv.onmouseover = function() {
		 		params.movement = originalMovement / 3;
		 	}
		 	
		 	innerDiv.onmouseout = function() {
		 		params.movement = originalMovement;
		 	}
		}
			
		if (params.stopOnClick) {
		 	innerDiv.onclick = function() {
		 		isStopped = !isStopped;
			}
		}
	
		this.pe = new PeriodicalExecuter(function() {		    		
			if (!isStopped) {
	  		outerWidth = element.getWidth();
	  		
			 	if (pos < -width) {
			 		innerDiv.style["marginLeft"] = width + "px";
			 		pos = outerWidth; 
			 	}
			 	innerDiv.style["marginLeft"] = (pos -= params.movement) + "px";
			}			 	  
		}, params.speed);	
	},
  
	stop: function() {
   	this.pe.stop();
	}
}

/**
* Element Text Ticker Widget
* @author Paul Serby - Hannah 
*/
RumbleUI.ElementTicker = Class.create();
RumbleUI.ElementTicker.prototype = {
 
	initialize: function(element, text, options) {
	
		if (!options) {
			options = {};
		}
		
		options.speed = options.speed ? options.speed :  0.02;	
		options.movement = options.movement ? options.movement :  1;					
			 	
		element = $(element)
			
		if (!element) {
			return false;
		} 
		
		element.style["overflow"] = "hidden";
		
		var totalWidth = 0;
		
		var innerDiv = element.down("div");
			
		$A(innerDiv.childNodes).each(function(subelement) {
			totalWidth += subelement.getWidth();
		});
		
		innerDiv.style["width"] = totalWidth + "px";
		
		var offset = 0;
		var x = 10;
		
		var containerWidth = element.getWidth();
		
		this.pe = new PeriodicalExecuter(function() {		    		
			
			var firstElement = innerDiv.childNodes[0];
  		                                   
		 	if (offset + x < -firstElement.getWidth()) {
		 		
		 		innerDiv.appendChild(firstElement);
		 		firstElement.style["marginLeft"] = "";
		 		offset = -x;
		 	}
		 	innerDiv.childNodes[0].style["marginLeft"] = (offset -= options.movement) + "px";
		 	
		}, options.speed);	
	},
	 
	stop: function() {
  	this.pe.stop();
	}
}

RumbleUI.ImageSwapper = Class.create();
RumbleUI.ImageSwapper = {
	swap: function (imageElement, newSource, afterFinish, duration) {
		imageElement = $(imageElement);
		if (duration == undefined) {
			duration = 1;
		}
		
		var image = new Image();
		
		image.onload = function() {
		
			new Effect.Fade(imageElement, {	
				duration: duration,
				afterFinish: function() {
					imageElement.src = image.src;
					imageElement.width = image.width;
					imageElement.height = image.height;
					new Effect.Appear(imageElement, {
						duration: duration,
						afterFinish: afterFinish
					});
				}
			});
		}		
		image.src = newSource;
	}	
}

/**
 * Slide Show
 * @author Paul Serby 
 */
RumbleUI.SlideShow = Class.create();
RumbleUI.SlideShow.prototype = {
	
	initialize: function(element, options) {
	
		this.options = {
    	showControls: true,
    	showPosition: true,
    	showPrevious: true,
			showNext: true,
    	duration: 2,
    	effectDuration: 0.5
    };
  
  	this.playing = false;
  	this.images = [];
  	this.setup = false;
  	this.position = -1;
  	this.timer = null;
  	      
    Object.extend(this.options, options || { });
	
		this.element = $(element);
		
		this.element.style.position = "relative";
		
		this.image = document.createElement("img");
		this.image.className = "rumbleui-slideshow-image";

		Element.extend(this.image);
	},

	play: function() {
		this.playing = true;
		
		clearTimeout(this.timer);
		this.timer = setTimeout(this.next.bind(this), this.options.duration * 1000);
	
	},
	
	stop: function() {
		this.playing = false;
	},
	
	next: function(callback) {		
		if (this.images.length <= 1 &&  this.position > -1) {
			if (Object.isFunction(callback)) {
				callback();
			}
			return;
		}
		this.position++;  
		if (this.position >= this.images.length) {
			this.position = 0;
		}
	
		if (!this.setup) {
			this.element.innerHTML = "";
			this.element.appendChild(this.image);
			this.setup = true;
		}
		
		RumbleUI.ImageSwapper.swap(this.image, this.images[this.position].src, 
			(function() {
				if (Object.isFunction(callback)) {
					callback();
				}
				if (this.playing) {
					this.play();
				}
			}).bind(this));
			
		this.image.onclick = (function() {
			window.location = this.images[this.position].url;
		}).bind(this);
	},

	previous: function() {
	},
		
	addImage: function(src, url, title, callback) {
		this.images.push({ src: src, url: url, title: title });
		if (this.position == -1) {
			this.next(callback);
		}	
	}	
}

/**
 * Tool Tip Control
 */
RumbleUI.ToolTips = Class.create();
  
RumbleUI.ToolTips.prototype = {

	initialize: function(options) {
		
		this.options = {
      className: "rumbleui-tooltip-tooltip",
      delay: 0.5,
      xOffset: 20,
      yOffset: 20,
			showOnHover: true,
      showOnClick: false,
      autoAddDocument: true
    };
    
    Object.extend(this.options, options || { });					
		
		this.toolTipElement = $("rumbleui-tooltip-element");

		if (!this.toolTipElement) {
			this.toolTipElement = document.createElement("div");
			this.toolTipElement.className = this.options.className;
			Element.extend(this.toolTipElement);
			this.toolTipElement.hide();
			document.body.appendChild(this.toolTipElement);
		}

		document.observe("mouseover", this.cancelTimer.bind(this));
		
		if (this.options.autoAddDocument) {
			this.autoAdd(document);
		}		
	},

	add: function(element, text) {
		element = $(element);
		if (this.options.showOnClick) {
			element.observe("click", this.activateTip.bindAsEventListener(this, element, text, false));
		}
		if (this.options.showOnHover) {
			element.observe("mousemove", this.activateTip.bindAsEventListener(this, element, text, true));
		}
	},

	activateTip: function(event, element, text, waitForDelay) {
		if (this.currentToolTipElement != element) {
			if (this.displayTimer) {
				this.displayTimer.stop();
			}	
			this.hide(true);
			var x = Event.pointerX(event);
			var y = Event.pointerY(event);			
			if (waitForDelay) {
				this.displayTimer = new PeriodicalExecuter((function(pe) {
					this.show(x, y, element, text);
					pe.stop();
				}).bind(this), this.options.delay);
			} else {
				this.show(x, y, element, text);
			}
		}
		event.stop();					
	},

	cancelTimer: function(event) {
		this.hide(true);
		if (this.displayTimer) {
			this.displayTimer.stop();
			this.displayTimer = null;
		}
	},

	show: function(x, y, element, text) {
		this.currentToolTipElement = element;
		this.toolTipElement.innerHTML = text;

		var position = Position.cumulativeOffset(element);
		Position.absolutize(this.toolTipElement);
		
		this.toolTipElement.setStyle({
			top: (this.options.yOffset + y) + "px",
			left: (this.options.xOffset + x) + "px"
		});
		
		new Effect.Appear(this.toolTipElement, { duration: 0.2 });
	},

	hide: function(quick) {	
		if (quick) {
			this.toolTipElement.hide();
		} else {
			new Effect.Fade(this.toolTipElement, { duration: 1 });
		}
		this.currentToolTipElement = null;
	},

	autoAdd: function(element) {
		$A(element.getElementsByClassName("rumbleui-tooltip")).each((function(newToolTip) {
			this.add(newToolTip, newToolTip.title);
			newToolTip.title = "";
		}).bind(this));
	}
}
/**
 * Sequential Loader Control
 */
RumbleUI.SequentialLoader = Class.create();
  
RumbleUI.SequentialLoader.prototype = {

	initialize: function(toBeLoaded, onclickFunction, options) {
		
		this.options = {
      duration: 0.5,
      effectDuration: 0.5
    };
    
    Object.extend(this.options, options || { });					
				
		var i = 1;
		toBeLoaded.each((function(element) {
			if (onclickFunction) {
				element.onclick = onclickFunction.bindAsEventListener(element);
			}
			var element = $(element);
			new PeriodicalExecuter((function() {
				this.show(element)
			}).bind(this), (this.options.duration * i++));
		}).bind(this));
	},
	
	show: function(element) {
		new Effect.Appear(element, { duration: this.options.effectDuration } );
	}
}

/**
 * Carrousel Scrolling List Widget
 * @author Paul Serby  
 */
RumbleUI.Carrousel = Class.create();
RumbleUI.Carrousel.Direction = { Vertical: 0 , Horizontal: 1 };  
RumbleUI.Carrousel.prototype = {
	

	initialize: function(element, previousHandle, nextHandle, options) {
	  
	  this.options = {
	  	listItemClassName: null,
	  	direction: RumbleUI.Carrousel.Direction.Vertical,
	  	duration: 0.4,
	 		fadeWrap: false,
	 		effectDuration: 0.5,
	 		autoSwitchTimer: 0
	  }
	  
		Object.extend(this.options, options || { });
	  
	  this.length = 0;
	  this.transition = false;
	  this.element = $(element);
	  this.containerHeight = this.element.getHeight();
	  this.containerWidth = this.element.getWidth();
	  
	  if (this.element.match("ul")) {
			this.listElement = this.element;
	  } else {
	  	this.listElement = this.element.down();
	  	this.listElement.style.position = "relative";
	  	this.element.style.position = "relative";
	  }
		this.listHeight = this.listElement.getHeight();
		this.listWidth = this.listElement.getWidth();
		this.listItems = this.getListItems();
		
		if (this.listItems.length <= 0) {
			return false;
		}
		
		if (this.options.direction == RumbleUI.Carrousel.Direction.Vertical) {
			this.units = this.listHeight;
		} else {
			this.units = this.listWidth;
		}
		
		this.length = this.listItems.length;
		this.previousHandle = $(previousHandle);
		if (this.previousHandle) { 
			this.previousHandle.observe("click", this.movePrevious.bind(this));
		}
		this.nextHandle = $(nextHandle);
		if (this.nextHandle) { 
			this.nextHandle.observe("click", this.moveNext.bind(this));
		}	
		
		if (this.options.autoSwitchTimer > 0) {
			new PeriodicalExecuter(this.autoMoveNext.bind(this), this.options.autoSwitchTimer);
			
			this.element.observe("mouseover", this.onMouseOver.bind(this));
			Event.observe(document.body, "mouseover", this.onDocumentOver.bind(this));
		}
	},
	
	onMouseOver: function(event) {
		this.mouseOverCarrousel = true;
		Event.stop(event);
	},
	
	onDocumentOver: function(event) {
		this.mouseOverCarrousel = false;		
	},
	
	getListItems: function() {
		var listItems;
		if (this.options.listItemClassName == null) {
			listItems = $A(this.listElement.getElementsByTagName("li"));
		} else {
			listItems = $A(this.listElement.getElementsByClassName(this.options.listItemClassName));
		}
		return listItems;
	},
	
	movePrevious: function() {
		if (!this.transition) {
			this.transition = true;
			var xMovement = 0;
			var yMovement = 0;
			var afterTransition = this.afterTransition.bind(this, -1, this.options.fadeWrap);
			var listItem = this.listItems[this.length - 1];
			
			if (this.options.direction == RumbleUI.Carrousel.Direction.Vertical) {
				yMovement = Element.getHeight(listItem);
				if (this.listHeight - yMovement > this.containerHeight) {
					this.listElement.style.top = -yMovement	 + "px";
					this.listElement.insertBefore(listItem, this.listItems[0]);
					afterTransition = this.afterTransition.bind(this, -1, false);
				}					
			} else {
				xMovement = Element.getWidth(listItem);				
				if (this.listWidth - xMovement > this.containerWidth) {				
					this.listElement.style.left = -xMovement + "px";
					this.listElement.insertBefore(listItem, this.listItems[0]);
					afterTransition = this.afterTransition.bind(this, -1, false);
				}
			}
			
			new Effect.Move(this.listElement, { 
				x: xMovement,
				y: yMovement,
				mode: "relative",
				duration: this.options.duration,
				afterFinish: afterTransition
			});
		}
	},

	autoMoveNext: function() {
		if (!this.mouseOverCarrousel) { 
			this.moveNext();
		}
	},
	
	moveNext: function() {
		if (!this.transition) {
			this.transition = true;
			if (this.options.direction == RumbleUI.Carrousel.Direction.Vertical) {
				var listItemMovement = Element.getHeight(this.listItems[0]);
				new Effect.Move(this.listElement, { 
					x: 0,
					y: -listItemMovement,
					mode: "relative",
					duration: this.options.duration,
					afterFinish: this.afterTransition.bind(this, 1, this.options.fadeWrap) 
				});
			} else {
				var listItemMovement = Element.getWidth(this.listItems[0]);
				new Effect.Move(this.listElement, { 
					x: -listItemMovement,
					y: 0,
					mode: "relative",
					duration: this.options.duration,
					afterFinish: this.afterTransition.bind(this, 1, this.options.fadeWrap) 
				});
			}			
		}
	},

	afterTransition: function(direction, fadeIn) {		
		if (direction > 0) {
			
			var listItem = this.listItems[0];
			var height = Element.getHeight(listItem);
			var width = Element.getWidth(listItem);
			
			if (fadeIn) {
				Element.setStyle(listItem, { opacity: 0 });
			}
			
			this.listElement.appendChild(listItem);
			if (this.options.direction == RumbleUI.Carrousel.Direction.Vertical) {
				this.listElement.style["top"] = "0px";	
			} else {
				this.listElement.style["left"] = "0px";
			}
			if (fadeIn) {
				new Effect.Appear(listItem, { duration: this.options.effectDuration });
			}
			
		} else {
			var listItem = this.listItems[this.length - 1];
			var height = Element.getHeight(listItem);
			var width = Element.getWidth(listItem);
			var listItemMovement = 0;
			
			if (fadeIn) {
				Element.setStyle(listItem, { opacity: 0 });
			}
					
			this.listElement.insertBefore(listItem, this.listItems[0]);
			if (this.options.direction == RumbleUI.Carrousel.Direction.Vertical) {
				listItemMovement = height;
				this.listElement.style["top"] = "0px";	
			} else {
				listItemMovement = width; 
				this.listElement.style["left"] = "0px";	
			}
			
			if (fadeIn) {				
				new Effect.Appear(listItem, { duration: this.options.effectDuration });
			}	
		}
		this.listItems = this.getListItems();
		this.clearTransition();
	},
	
	clearTransition: function() {
		this.transition = false;
	}
}

RumbleUI.Scrollbar = Class.create();
RumbleUI.Scrollbar.prototype = {

	initialize: function(scrollElement, options) {
	
		this.options = {
            
    };
    
    Object.extend(this.options, options || { });
	
		scrollElement = $(scrollElement);
		var firstChild = scrollElement.down();
		var scrollPanelWidth = firstChild.getWidth();
		
		scrollElement.style.overflow = "hidden";
		
		var scrollPanel = document.createElement("div");
		Element.extend(scrollPanel);
		
		var scrollBar = document.createElement("div");
		Element.extend(scrollBar);
		
		var scrollHandle = document.createElement("div");
		Element.extend(scrollHandle);
		
		scrollElement.appendChild(scrollPanel);
		scrollPanel.appendChild(firstChild);
		scrollPanel.style.width = scrollPanelWidth + "px"; 
		
		scrollElement.appendChild(scrollBar);
		
		var scrollHeight = scrollPanel.getHeight() - scrollElement.getHeight();
		
		scrollPanel.setStyle({ 
			float: "left",
			position: "absolute",
			overflow: "hidden"  
		});
		
		scrollBar.setStyle({ position: "absolute", right: "0px" });
		scrollBar.style.height = scrollElement.getHeight() + "px";
		scrollBar.style.width = "17px";
		scrollBar.className  = "rumbleui-scrollbar-scrollbar";
		
		scrollBar.appendChild(scrollHandle);
		scrollHandle.setStyle({ 
			width: "17px",
			height: "17px"
		});
		
		scrollHandle.className  = "rumbleui-scrollbar-handle";
		
		var s2 = new Control.Slider(scrollHandle, scrollBar, {
			axis: "vertical",
			disabled: false
		});	
	    
		s2.options.onSlide  = function(value) {
			scrollHeight = scrollPanel.getHeight() - scrollElement.getHeight();
	  	scrollPanel.style.top = -parseInt(scrollHeight * value, 10) + "px";
		}
	}
}

