// Patch for webkit/chrome
Request.HTML.implement({

	processHTML: function(text){
		var match = text.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
		text = (match) ? match[1] : text;
		
		var container = new Element('div');
		
		return (function(){
			var root = '<root>' + text + '</root>', doc;
			if (Browser.Engine.trident){
				doc = new ActiveXObject('Microsoft.XMLDOM');
				doc.async = false;
				doc.loadXML(root);
			} else {
				doc = new DOMParser().parseFromString(root, 'text/html');
			}
			root = doc.getElementsByTagName('root')[0];
			for (var i = 0, k = root.childNodes.length; i < k; i++){
				var child = Element.clone(root.childNodes[i], true, true);
				if (child) container.grab(child);
			}
			return container;
		}).attempt() || container.set('html', text);
	}

});

Function.implement({
	bindWithEvent: function(bind, args){ 
		var self = this; 
		
		if (args != null) args = Array.from(args); 
		return function(event){
			return self.apply(bind, (args == null) ? arguments : [event].concat(args));
			}
		}
	})
	
Element.implement({
    
    // pulse options are appended to the tween settings of this pulse, as pulse is a tween user
    pulse : function (options) {
		if (!options) options = {}
		var duration	= (options.duration || 3000);
		var pulses	  = (options.pulses || 5);
		var pulse = this.get('tween'), o = 'opacity';
		var pulse_transition = function(pos)
		{
			// pos is the delta over duration
			//debugger;
			// do not use Fx.Transitions.Sine() as it has a range of [0..2].
			// We want a range of [0..1] starting at 0, ending at 0. So we use a sin(). But ho!
			// sin() has [-1...+1] so square to the rescue: it has a slighly faster ascent/descent, but
			// it pretty nice neverthless:
			//var rp = Math.pos(pos * this.options.pulses * 2 * Math.PI);
			// Note: sin^2 has a base frequency twice as high as sin(), so we need to divide the 
			// frequency by 2, i.e. loose the 2 in there!
			// Another note: as Fx.step() terminates the tween with a call to .set(tfrom, to, delta=1)
			// effectively setting the 'to' value at the end, we SWAP the 'intuitive' start() values
			// below, giving 'counter-intuitive' a whole 'nother meaning :-)
			// That way we may have step() covered, but now we need to start and end our wave at 1 instead
			// of 0: invert it is! --> 1 - val]
			var rp = Math.sin(pos * this.options.pulses * Math.PI);
			rp *= rp;
			//console.log('rp:', rp, ' @ pos', pos);
			return 1 - rp;
		}
		pulse.setOptions(Object.merge({
			pulses: pulses,
			duration: duration,
			transition: pulse_transition // can't use Fx.Transitions.Sine.easeInOut
			// for one reason, our 'end' value is not really the 'end' but the 
			// max contrasting value to pulse to
		}, options));
		var sval = this.retrieve('pulse:start', this.get('opacity'));
		this.store('pulse:start', sval);
		//debugger;
		//pulse.start(o, sval, 1 - sval);
		// The way highlight() solved the start() + step()-->set(end) concundrum is by chaining;
		// we are 'smarter' but put that in perspective: highlight() allows the use of arbitrary
		// tween-'compatible' transition functions, we do NOT!
		pulse.start(o, 1 - sval /* max contrast */, sval /* start == end */); 
		//.chain(function() {
		//	this.set(o, sval);
		//	pulse.callChain();
		//}.bind(this));
		
		return this;
	}
});


	
var SlideShow = new Class({
	Implements : [Events, Options],
	Extends: Fx,
	options : {
		delay			: 1000,
		duration		: 2000,	
		position		: 0,
		onInitialize	: function(){},
		onChange		: function(){},
		onMouseOver		: function(){},
		onMouseOut		: function(){},
		onPress			: function(){},
		onStart			: function(){},
		onComplete		: function(){}
		},
	initialize : function(element, options) {
		this.setOptions(options);
		this.container = element;
		this.setChildren(this.container.getElements(this.container.getFirst().tagName));
		if (isNaN(options.position)) {
			options.position = Numer.random(0, this.getCount()-1)
			}
		this.setPosition(Math.min(options.position, this.count-1));
		//this.children.setStyle("visibility", "visible");
		this.options.init = !options.onInitialize ? function(){} : options.onInitialize.bind(this);
		this.options.start = !options.onStart ? function(){} : options.onStart.bind(this);
		this.options.mouseover = !options.onMouseOver ? function(){} : options.onMouseOver.bind(this);
		this.options.mouseout = !options.onMouseOut ? function(){} : options.onMouseOut.bind(this);
		this.options.click = !options.onPress ? function(){} : options.onPress.bind(this)
		
		
		this.mouseoverEvent = function() {this.options.mouseover.attempt();}.bind(this);
		this.mouseoutEvent = function() {this.options.mouseout.attempt();}.bind(this);
		this.clickEvent = function() {this.options.click.attempt();}.bind(this);
		
		this.children.addEvent("mouseover", this.mouseoverEvent);
		this.children.addEvent("mouseout", 	this.mouseoutEvent);	
		this.children.addEvent("click", 	this.clickEvent);
		
		this.intervalID = null;
		
		
		this.init();
		
		},
	setPosition : function (position) {
		this.currentIndex = 0;
		this.children.setStyle("opacity", 0);
		if(position == 0) {
			this.children[0].setStyle("opacity", 1);
			}
		else {
			if (typeOf(position) == "element") {
				for (var i = 0; i < this.children.length; ++i) {

					if(position == this.children[i]) {
						this.currentIndex = i;
						this.children[i].setStyle("opacity", 1);
						break;
						}
					this.children[i].setStyle("opacity", 0);
					}
				}
			else {
				this.currentIndex = position;
				this.children[position].setStyle("opacity", 1);
				}
			}
		this.position = this.currentIndex+1;
		},
	setChildren : function (items) {
		//if(this.children) this.children.setStyle("opacity", 1);
		this.children = items;
		//this.children.setStyle("opacity", 0);
		//this.children[0].setStyle("opacity", 1);
		//this.currentIndex = 0;
		this.count = this.children.length;
		},
	dispose : function () {
		this.stop();
		this.children.removeEvent("mouseover", this.mouseoverEvent);
		this.children.removeEvent("mouseout", 	this.mouseoutEvent);	
		this.children.removeEvent("click", 	this.clickEvent);
		this.children.setStyle("opacity", 1);
		this.children.setStyle("visibility", "visible");
		},
	init : function () {
		
		this.options.init.attempt()
		},
	start : function () {
		this.fireEvent("start");
		},
	mouseover : function () {
		this.options.mouseover.attempt()
		},
		
	click : function () {
		this.options.click.attempt()
		},
	complete : function () {
		this.fireEvent("complete");
		},
	play : function () {
		this.intervalID = this.next.periodical(this.options.delay, this)
		},
	
	stop : function () {
		clearInterval(this.intervalID);
		},
	
	next : function () {

		if (this.fxIn) {this.fxIn.cancel();}
		if (this.fxOut) {this.fxOut.cancel();}
		this.fadeOut();
		this.fadeIn();
		this.fireEvent("change");
		},
	goTo : function () {
		
		if (arguments[0] == this.position-1) return
		if (this.fxIn) {this.fxIn.cancel();}
		if (this.fxOut) {this.fxOut.cancel();}
		this.stop();
		this.fadeOut();
		this.currentIndex = arguments[0] == 0 ? this.children.length-1 : arguments[0]-1;
		this.position = this.currentIndex + 1;
		this.fadeIn()
		if(arguments.length == 2) {
			if(arguments[1]) {this.play();}
			}
		else {
			this.play();
			}
		},
	prev : function () {
		//alert(this.position)
		this.goTo(this.position-1 == 0 ? this.children.length-1 : this.position-2);
		},
	fadeIn : function () {

		this.currentIndex = this.currentIndex+1 >= this.children.length ? 0 : ++this.currentIndex;
		this.position = this.currentIndex + 1;

		this.fxIn = new Fx.Morph(this.children[this.currentIndex], {
			duration : this.options.duration, 
			wait : false,
			onStart : function () {this.fireEvent("start")}.bind(this),
			onComplete : function () {this.fireEvent("complete")}.bind(this)
			}).start({"opacity": 1});
		},
			
	fadeOut : function () {
		this.fxOut = new Fx.Morph(this.children[this.currentIndex], {duration : this.options.duration, wait : false }).start({"opacity": 0});
		},
		
	getCount : function () {
		return this.count;
		},
	getPosition : function () {
		return this.position;
		},
	getItem : function () {
		return this.children[this.currentIndex];
		}
	});
	
	
	
/* ////////////////////////////////////////////////////////////////////
This class rotats elements top to bottom making the item of focus
full opacity and the others .1 opacity and transitions them through
//////////////////////////////////////////////////////////////////// */ 
var FeedRotator = new Class({
	Implements : [Events, Options],
	Extends: Fx,
	options : {
		delay			: 5000,
		duration		: 2000,	
		onInitialize	: function(){},
		onChange		: function(){},
		onMouseOver		: function(){},
		onMouseOut		: function(){},
		onPress			: function(){},
		onStart			: function(){},
		onComplete		: function(){}
		},
	initialize : function(element, options) {
		this.setOptions(options);
		this.container = element;
		this.children = this.container.getElements(this.container.getFirst().tagName);
		
		if (this.children.length < 5) {
			do {
				for(var i = 0; i < this.children.length; ++i) {
					this.children[i].clone(true, true).inject(this.container);
					}
				this.children = this.container.getElements(this.container.getFirst().tagName);
				} 
			while (this.children.length < 5)
			}
		
		this.options.init = !options.onInitialize ? function(){} : options.onInitialize.bind(this);
		this.options.start = !options.onStart ? function(){} : options.onStart.bind(this);
		this.options.mouseover = !options.onMouseOver ? function(){} : options.onMouseOver.bind(this);
		this.options.mouseout = !options.onMouseOut ? function(){} : options.onMouseOut.bind(this);
		this.options.click = !options.onPress ? function(){} : options.onPress.bind(this)
		
		
		this.children.addEvent("mouseover", function() {this.options.mouseover.attempt();}.bind(this));
		this.children.addEvent("mouseout", 	function() {this.options.mouseout.attempt();}.bind(this));	
		this.children.addEvent("click", 	function() {this.options.click.attempt();}.bind(this));
		
		this.intervalID = null;
		this.currentIndex = 0;
		this.children.setStyle("opacity", .1);
		this.children[0].setStyle("opacity", 1);
		
		if (this.children.length < 5) {
			
			}
		
		this.init();
		
		},
	
	init : function () {
		this.container.setStyle("margin-top", (parseFloat(this.container.getParent().getStyle("height")) - this.children[this.currentIndex+1].getSize().y)/2);
		this.children.setOpacity(0);
		this.children[0].setOpacity(1)
		this.children[1].setOpacity(.1);
		this.options.init.attempt()
		},
	start : function () {
		this.fireEvent("start");
		},
	mouseover : function () {
		this.options.mouseover.attempt()
		},
		
	click : function () {
		this.options.click.attempt()
		},
	complete : function () {
		this.fireEvent("complete");
		},
	play : function () {
		this.intervalID = this.next.periodical(this.options.delay+this.options.duration, this)
		},
	
	stop : function () {
		//alert("");
		clearInterval(this.intervalID);
		},
	
	next : function () {
		if (this.fxIn) {this.fxIn.cancel();}
		if (this.fxOut) {this.fxOut.cancel();}
		new Fx.Morph(this.container, {
			duration : this.options.duration,
			wait: false,
			onStart : function () {
				//alert(this.currentIndex)
				new Fx.Morph(this.children[this.currentIndex], {duration:this.options.duration, wait:false}).start({"opacity":.1});
				new Fx.Morph(this.children[this.currentIndex+1], {duration:this.options.duration, wait:false}).start({"opacity":1});
				new Fx.Morph(this.children[this.currentIndex+2], {duration:this.options.duration, wait:false}).start({"opacity":[0,.1]});
				}.bind(this),
			onComplete : function () {
				
				if (this.currentIndex >= 2) {
					this.children[0].clone(true, true).cloneEvents(this.children[0]).inject(this.container);
					this.container.setStyle("margin-top", this.children[1].getCoordinates(this.container.getParent()).top)
					//this.container.setStyle("margin-top", parseFloat(this.container.getStyle("margin-top")) + (this.children[1].getSize().y/2))
					this.children[0].dispose();
					this.children = this.container.getElements("li");
					}
				else {
					++this.currentIndex;
					}
				}.bind(this)
			}).start({"margin-top": 
									parseFloat(this.container.getStyle("margin-top")) - 
									this.children[this.currentIndex+1].getCoordinates(this.container.getParent()).top + 
									(parseFloat(this.container.getParent().getStyle("height")) - this.children[this.currentIndex+1].getSize().y)/2
									});
		this.fireEvent("change");
		},
	
	getCount : function () {
		return this.count;
		},
	
	getItem : function () {
		return this.children[this.currentIndex];
		}
	});
	
	

var Overlay = new Class({
	Implements : [Events, Options],
	Extends : Fx,
	options : {
		elementClass	: "",
		title 			: "",
		type 			: "",
		size			: "",
		url				: "",
		height			: null,
		html			: "",
		buttons			: [],
		onInitialize	: function(){},
		onBeforeCreate	: function(){},
		onAfterCreate	: function(){},
		onBeforeDispose	: function(){},
		onAfterDispose	: function(){},
		onComplete		: function(){}
		},
	initialize : function (options) {
		
		this.setOptions(options);
		this.options.init = !options.onInitialize ? function(){} : options.onInitialize.bind(this);
		this.options.beforeCreate = !options.onBeforeCreate ? function(){} : options.onBeforeCreate.bind(this);
		this.options.afterCreate = !options.onAfterCreate ? function(){} : options.onAfterCreate.bind(this);
		this.options.beforeDispose = !options.onBeforeDispose ? function(){} : options.onBeforeDispose.bind(this);
		this.options.afterDispose = !options.onAfterDispose ? function(){} : options.onAfterDispose.bind(this);
		if(options.height != null) {
			this.options.height = options.height;
			}
		this.maskElement;
		this.titleElement;
		this.bodyElement;
		this.messageElement
		this.footerElement;
		this.containerHeight;
		this.resizeFx;
		this.resizeInt;
		this.urlRequest;
		this.init();
		
		window.addEvent("resize", function () {
			clearInterval(this.resizeInt);
			//console.log("resize....")
			if($("site-mask")) {
				$("cover").setStyle("height" , window.getScrollSize().y)
				$("site-mask").setStyle("height" , window.getScrollSize().y)
				//$("loader").setStyle("height" , window.getScrollSize().y)
				}
			  this.resizeInt = (function(){
					if ($("site-mask")) {
						this.resize();
						}
				  }).delay(400, this);
			
			}.bind(this));
		},
	init : function () {
		this.options.init.attempt()
		},
	create : function () {
		var blocks = {};
		this.options.beforeCreate.attempt();
		$(document.body).setStyle("overflow","hidden");
		$(document.body).addClass("moo-mask");
		blocks.mask 		= new Element("div", {"id":"site-mask", "class":this.options.elementClass});
		blocks.cover 		= new Element("div", {"id":"cover", "title" : "Click here to close this window"}).set("html", "&nbsp;").setOpacity(0.4).addEvent("click", function () {this.dispose();}.bind(this));
		blocks.container 	= new Element("div", {"id":"container"});
		blocks.title 		= new Element("h2").set("text", this.options.title);
		blocks.body 		= new Element("div", {"id":"mask-body"}).setStyles({"height":"25px"});
		blocks.message 		= new Element("div", {"id":"mask-message"}).set("html", "<p class=\"loading-indicator\">&nbsp;</p>");
		blocks.footer 		= new Element("div", {"id":"mask-footer"}).set("html", "<p>&nbsp;</p>");
		
		if (this.options.type != "") {
			blocks.mask.addClass(this.options.type);
			}
		
		this.maskElement 	= blocks.mask;
		this.titleElement	= blocks.title;
		this.bodyElement 	= blocks.body;
		this.messageElement = blocks.message;
		this.footerElement	= blocks.footer;
		
		if(this.options.size != "") {this.maskElement.addClass(this.options.size);}
		this.maskElement.setStyle("height", window.getScrollSize().y + "px");
		
		
		
		for(var b = 0; b < this.options.buttons.length; ++b) {
			if (!this.options.buttons[b]["class"]) {
				this.options.buttons[b]["class"] = "";
				}
			new Element("input", {
								"type":"button", 
								"value": this.options.buttons[b].label, 
								"id": this.options.buttons[b].id, 
								"class":this.options.buttons[b]["class"]
								}).addEvent("click", function (button) {
									//console.log(button.onClick)
									if (button.label.toLowerCase() == "close" && !button.onClick) {
										this.dispose();
										}
									else if (button.label.toLowerCase() == "print" && !button.onClick) {
										print();
										}
									else {
										//console.log("clicking....")
										button.onClick.attempt(this)
										}
									
									}.bind(this, this.options.buttons[b])).inject(this.footerElement.getElement("p"));
			
			}
		this.maskElement.setStyle("top", window.getScroll().y + "px");
		
		blocks.message.inject(blocks.body);
		blocks.title.inject(blocks.container);
		blocks.message.inject(blocks.body);
		blocks.body.inject(blocks.container);
		blocks.footer.inject(blocks.container);
		blocks.cover.inject(this.maskElement);
		
		blocks.container.inject(this.maskElement);
		
		
		this.maskElement.inject(document.body, "bottom");
		
		if (this.options.url != "") {
			this.loadURL(this.options.url)
			}
		this.options.afterCreate.attempt();
		if(this.options.html != "") this.setHTML(this.options.html)
		return this;
		},
	loading : function () {
		this.bodyElement.setStyles({"height":"25px"});
		this.messageElement.set("html", "<p class=\"loading-indicator\">&nbsp;</p>");
		//this.options.title = "Loading.....";
		this.setTitle();
		},
	dispose : function () {
		$(document.body).removeClass("moo-mask");
		if(this.urlRequest) {
			this.urlRequest.cancel()
			}
		if (this.maskElement) {
			this.options.beforeDispose.attempt();
			var fx = new Fx.Morph(this.maskElement, {
				duration: 400, 
				wait: true,
				onComplete : function () {
					this.maskElement.dispose();
					$(document.body).setStyle("overflow","auto");
					this.options.afterCreate.attempt();
					}.bind(this)
				}).start({"opacity":0});
			}
		},
	setTitle : function () {
		this.titleElement.set("text", this.options.title);
		},
	setHTML : function (html) {
		this.getBodyElement().set("html", html);
		this.setContainerHeight();
		this.resize();
		this.fireEvent("complete");
		//return this;
		},
	getTitleElement : function() {
		return this.titleElement;
		},
	getBodyElement : function() {
		return this.messageElement;
		},
	getFooterElement : function() {
		return this.footerElement;
		},
	putMessage : function (html, type) {
		if (!type) type = "info";
		if(!$("mask-form-response")) {
			new Element("div", {"id":"mask-form-response", "class":type}).set("html", "<div id=\"response-body\">" + html + "</div>").inject(this.getBodyElement(), "top");
			}
		else {
			$("mask-form-response").set("class", type);
			$("response-body").set("html", html);
			}
		},
	setContainerHeight : function () {
		this.getBodyElement().setStyle("height", "auto");
		if (this.options.height) {
			this.containerHeight = this.options.height;
			}
		else {
			this.containerHeight = this.getBodyElement().getScrollSize().y;
			}
		},
	resize : function () {
		//console.log("resizing mask")
		this.setContainerHeight();
		var _fromTop = this.getBodyElement().getCoordinates().top;
		var _scrollTop = window.getScroll().y;
		var _winHeight = window.getSize().y
		var _containerHeight = this.containerHeight;
		var _availableHeight = _winHeight - (_fromTop - _scrollTop) - this.footerElement.getSize().y;
		var _targetHeight = Math.min(_containerHeight, _availableHeight);
		//console.debug(_winHeight +  "-  ( "+ _scrollTop + "-"+ _fromTop + ") -" + this.footerElement.getSize().y)
		//console.debug(_winHeight + " : " + _availableHeight)
		//console.log(_targetHeight)
		if ((_targetHeight != this.bodyElement.getSize().y || this.getBodyElement().getStyle("visibility") == "hidden")) {
			if (this.getBodyElement().getStyle("visibility") == "hidden") this.getBodyElement().setStyle("display","none");
			this.getBodyElement().setStyles({"overflow":"hidden"});
			this.resizeFx = new Fx.Morph(this.bodyElement, {
											wait:false, 
											duration:500,
											onComplete : function () {
												if (this.getBodyElement().getStyle("display") == "none") {
													this.getBodyElement().setStyle("display","block");
													var _fx = new Fx.Morph(this.getBodyElement(), {wait:false, duration:500}).start({opacity:[0,1]});
													}
												//if (_targetHeight < _containerHeight) {
													this.getBodyElement().setStyle("height", _targetHeight);
													this.getBodyElement().setStyles({"overflow":"auto"});
												//	}
												//this.resize.delay(3000, this);
												
												//this.resizeInt = this.resize.periodical(1000, this);
												}.bind(this)
											}).start({height:_targetHeight});
				
			
			}
		//alert(this.getBodyElement().getSize().y)
		},
	
	reloadURL : function (options) {
		if(options) this.setOptions(options);
		//this.loading();
		this.setTitle();
		this.getBodyElement().set("html", "");
		this.loading();
		this.resize();
		this.loadURL();
		},
	
	loadURL : function () {
		
	//	console.log(this.options.url)
		this.urlRequest = new Request.HTML({
					url: this.options.url,
					update : this.getBodyElement(),
					evalResponse  : true,
					onComplete : function (responseText) {
						//this.setHTML(responseText.toString())
						
						
						//this.resizeInt = this.resize.periodical(1000, this);
						this.fireEvent("complete");
						}.bind(this),
					onSuccess : function (responseText) {
						this.bodyElement.setStyles({"overflow":"hidden"});
						this.getBodyElement().setStyle("visibility","hidden");
						this.setContainerHeight();
						this.resize();
						
						//this.setHTML(responseText.toString())
						}.bind(this),
					onFailure : function (result) {	
					//for(p in result) alert(p)
						//alert(this.url);
						var _tmp = new Element("div").set("html", result.responseText).setStyle("display","none");
						//alert(_tmp.getElement("h2"));
						this.setHTML(_tmp.get("html"));
						this.maskElement.addClass("error");
						var h = this.getBodyElement().getElement("td[id=tableProps2]").get("text");
						var d = this.getBodyElement().getElement("td[id=tablePropsWidth]").get("text");
						_tmp.dispose();
						this.getBodyElement().setStyle("visibility","hidden");
						this.setHTML("<h3>Exception Occured</h3><p><strong>" + h + "</strong></p><p>" + d + "</p><p>URL : " + this.options.url + "</p>");
						this.setContainerHeight();
						this.resize();

						//this.resize();
						}.bind(this)
					}).send();
		}
	});

	

var SelectBox = new Class({
	Implements : [Events, Options],
	Extends : Fx,
	options : {
		elementClass	: "moo-select",
		onChange		: function(){},
		onClick			: function(){}
		},
	initialize : function (element, options) {
		var liItem;
		if (!options) options = {};
		this.setOptions(options);
		this.element = element;
		if(!window.mooselectBaseIndex) {
			window.mooselectBaseIndex = 50000;
			window.mooSelects = [];
			}
		window.mooSelects.push(this);
		this.options.onchange = !options.onChange ? (function () {eval(this.element.getProperty("onchange"))}.bind(this)) : options.onChange.bind(this);
		this.isOpen = false;
		this.options.onclick = !options.onClick ? function(){} : options.onClick.bind(this);
		this.optionElements = $(element).getChildren("option");
		this.value = "";
		this.text = "";
		
		for (var o = 0; o < this.optionElements.length; ++o) {
			var s = new Element("select")
			this.optionElements[o].clone().inject(s);
			if (s.get("html").indexOf('selected="selected"') != -1) {
				this.value = this.optionElements[o].value;
				this.text = this.optionElements[o].text;
				s.dispose();
				break;
				}
			s.dispose();	

			}
		
		// Build the container holding the UL that has the select options
		this.container = new Element("div", {"class": this.options.elementClass, "style":"z-index:" + --window.mooselectBaseIndex}).inject(element.getParent(), "top");
		this.container.setStyle("z-index", --window.mooselectBaseIndex);
		this.selUL = new Element("ul", {"class" : element.getProperty("class") == "" ? "moo-select-ul" : element.getProperty("class")});
		//this.selUL.setStyle("width", this.element.getSize().x);
		
		for (var o=0; o < this.optionElements.length; ++o) {
			if (this.optionElements[o].value != "") {
				var itemClass = (o == 0 ? " first" : (o == this.optionElements.length-1 ? " last" : ""))
				var liItem = new Element("li", {
						"title":this.optionElements[o].text, 
						"class":this.options.elementClass + "-option-idle" + itemClass,
						"id":this.element.get("name") + "_option_" + o
						}).set("text", this.optionElements[o].text).inject(this.selUL);
				
				liItem.store("optionFx", new Fx.Morph($(liItem), {duration:200, wait:false}));
				
				liItem.addEvent("click", function (item) {	
				//	console.log(this)
					this.element.options[item].selected = true;
					this.element.options[item].setProperty("selected", "selected")
					this.value = this.element.options[item].value;
					this.text = this.element.options[item].text;
					this.label.set("text", this.text);
					if(this.isOpen) {this.hide()} else {this.show();}
					this.options.onchange.attempt();
					}.bind(this, o));
			
				liItem.addEvent("mouseenter", function (ev) {
					var fx = ev.target.retrieve("optionFx");
					fx.cancel();
					fx.start("." + this.options.elementClass + "-option-hover");
					}.bindWithEvent(this, liItem));
			
				liItem.addEvent("mouseleave", function (ev) {
					var fx = ev.target.retrieve("optionFx");
					fx.cancel();
					fx.start("." + this.options.elementClass + "-option-idle");
					}.bindWithEvent(this));
				}
			}
			
		this.selUL.setStyle("visibility", "hidden");	
		this.selUL.inject(this.container, "top");
		this.fx = new Fx.Slide(this.selUL);
		this.element.setStyle("display", "none");
		/////////////////////////////////////////////////////////////
	
		// Build the link part of the select box that shows the selected option
		this.label = new Element("div", {"class":this.options.elementClass + "-label", "title":this.optionElements[0].text})
		this.setLabel(this.text == "" ? this.element.get("title") : this.text );
		this.label.addEvent("click", function () {
			for (var s=0; s < window.mooSelects.length; ++s) {
				if(window.mooSelects[s] != this && window.mooSelects[s].isOpen) {window.mooSelects[s].hide();}
				}
			this[this.isOpen ? "hide" : "show"]();
			this.options.onclick.attempt();
			}.bind(this));
		this.label.addEvent("mouseenter", function () {this.label.addClass("hover");}.bind(this));
		this.label.addEvent("mouseleave", function () {
			//console.log(this.isOpen)
			if (!this.isOpen) {this.label.removeClass("hover")};
			}.bind(this));
			
		this.label.inject(this.container, "top");
		this.fx.hide();
		
		this.selUL.setStyle.delay(1000, this.selUL, ["visibility", "visible"]);	
		},
	setLabel : function (label) {
		this.label.set("text", label)
		},
	reset : function () {
		this.label.set("text", this.element.get("title"));
		this.element.options[0].selected = true;
		this.element.options[0].setProperty("selected", "selected")
		},
	show : function () {
		//console.log("show : " + this.isOpen)
		this.fx.slideIn();
		this.label.addEvent("mouseenter", function () {this.label.addClass("hover");}.bind(this));
		this.isOpen = true;
		},
	hide : function () {
		//console.log("hide : " + this.isOpen)
		this.label.addEvent("mouseenter", function () {this.label.addClass("hover");}.bind(this));
		this.fx.slideOut();
		this.isOpen = false;
		}
	});	
	
	

var ArrayQue = new Class({
	Extends : Array,
	initialize : function (array) {
		this.array = array;
		this.index = 0;
		},
	next : function () {
		this.index = this.index == this.array.length-1 ? 0 : ++this.index;
		return this.array[this.index];
		},
	previous : function () {
		this.index = this.index == 0 ? this.array.length-1 : --this.index;
		return this.array[this.index];
		},
	get : function (type) {
		
		switch (type) {
			
			case "next" : {
				return this.next();
				}
			case "previous" : {
				return this.previous();
				}
			default : {
				return this.array[this.index];
				}
			}
		
		}
	});
