/**
 * Custom Select Class
 * @author 58062 Florian Collot
 * @copyright technomarine.com
 * 
 * var select = new Selects(FormReference,SelectReference,{
 *				'max' : {
 *					'height' : 250 (int) pixels
 *				},
 *				'gap' : {
 *					'left' : 0, (int) 
 *					'width': 0, (int)
 *					'top'  : 0, (int)
 *					'rTop': 0, (int)
 *					'rLeft': 0 (int)
 *				},
 *				'adjustable' : (bool),
 *				'values'	:	[{'label' : '', 'value' : '', 'selected : (bool)}], 
 *				'className' : 'select', (string) prefix of className,
 *				'position' : 'auto', (string) can be auto | top | bottom 
 *				'hotKey'	:	false,
 *				'label'		:	null (string),
 *				'scroll'	: {
 *					'button' : false
 *				},
 *				onSelect:function(){}, (Event)
 *				onBuilt:function(){} (Event)
 *			});
 * 
 */

var Selects = new Class ({
	Implements: [Events, Options],
	options : {
		'gap' : {
			'top' 	: 0,
			'left' 	: 0,
			'width'	: 0,
			'rTop'	: 0,
			'rLeft' : 0
			},
		'className' : 'select',
		'max' : {
			'height' : 250
			},
		'scroll' : {
			'button' : false	
		},
		'position' : 'auto',
		'adjustable' : true,
		'values' : null,
		'label' : null,
		'hotKey' : false,
		'tips' : false
	},
	initialize:function(form, element, options){
		this.setOptions(options);
		if (element.get('id') == null){
			var selectID = "select_"+this.getUniqid();
			element.set('id', selectID);
		}
		
		this.parent = element.getParent();
		
		/* BUG FF 3.0 */
		var ulWidth = parseInt(this.parent.getStyle('width').split('px')[0]);
		
		
		this.id = element.get('id');
		this.type = (element.get('multiple') == true) ? 'multiple' : 'simple'; 
		this.position = '';
		this.element = element.clone(true, true);
		
		this.tip = {
				'object' : null,
				'content' : null
			};
		if (this.options.label != null)
			this.label = this.options.label;
		else{
			var labels = $$('label');
			for (var i=0;i<labels.length;i++){
				if (labels[i].get('for') == this.id){
					this.label = labels[i].get('html');
				}
			}
		}
		this.form = form;
		
		this.container = new Element('div', {
			'class' : this.options.className+'_content',
			'id' : this.id+'_container'
		});
		
		this.hidden = new Element('select', {
			'name' : this.element.get('name'),
			'styles' : {
				'display' : 'none'
			},
			'id' : this.id
		}).inject(this.container);
		
		this.text = new Element('span', {
			'class' : this.options.className+'_text',
			'id' : this.id+'_text',
			'html': this.label
		}).inject(this.container);
		if ($chk($$('label#'+this.id+'_for')[0]))
			this.text.set('html', $$('label#'+this.id+'_for')[0].get('title'));
	
		this.overflowContainer = new Element('div', {
			'id' : this.id+'_overflow_container',
			'class' : this.options.className+'_overflow_container',
			'styles' : {
				'width'		: String(ulWidth+this.options.gap.width)+"px",
				'top'		: "0px",
				'left'		: "0px"
			}
		});
		this.overflow = new Element('div', {
			'id'	: this.id+'_overflow',
			'class' : this.options.className+'_overflow'
		}).inject(this.overflowContainer);
	
		// Simulate scrollbar width
		var scrollTestO = new Element('div', {
			'class' : this.options.className+'_overflow',
			'styles' : {
				'visibility' : 'hidden'
			}
		}).inject($$('body')[0]);
		var scrollTestWW = new Element('div', {
			'class' : 'scroll_wrapper'
		}).inject(scrollTestO);
		if (this.options.scroll.button){
			var scrollTestT = new Element('div', {
				'class' : 'scroll_top'
			}).inject(scrollTestWW);
		}
		var scrollTestW = new Element('div', {
			'class' : 'scroll_content'
		}).inject(scrollTestWW);
		if (this.options.scroll.button){
			var scrollTestT = new Element('div', {
				'class' : 'scroll_foot'
			}).inject(scrollTestWW);
		}
		this.ul = new Element('ul', {
			'id'	:	this.id+"_ul",
			'styles' : {
				'width' : String(parseInt(ulWidth-parseInt(scrollTestWW.getStyle('width').split("px")[0])+this.options.gap.width)+"px")
			}
		}).inject(this.overflow);
		// Destroy Simulation
		scrollTestO.destroy();
		
		if (this.options.values == null)
			this.loadOptions();
		else
			this.addOptions(this.options.values);
		
		var foot = new Element('div', {
			'id' : this.id+"_footer"
		}).inject(this.overflowContainer, 'bottom');
	
		
		this.size = 0; 
		
		this.scroll = {
					'has' : false,
					'object' : null
				};
		
		this.container.replaces(element);
		
		this.overflowContainer.inject($$('body')[0]);
		
		window.addEvent('resize', function(){
			this.replaceAbsoluteSelectOverflow();
		}.bind(this));
		
		this.cheatPosition = {
				'bottom' : new Element('div', {
					'styles' : {
						'width' : '1px',
						'height' : '1px',
						'display' : 'none'
					},
					'id' : this.id+'_cheat_bottom'
				}).inject(this.container, 'bottom')
		}; 
		
		// Create Tip if items selected
		if (this.tip.content != null && this.options.tips){
			this.buildSelectTip();
		}
		Selects.elements[this.id] = this;
		this.container.addEvent('click', function(e){
			this.showSelect();
		}.bind(this));
		this.handlePrevNextInput();
		this.enable();
		this.fireEvent('built');
	},
	/**
	 * Can Set more options in select
	 * @param options like [{
	 * 					'label' : 'title of option',
	 * 					'value' : 'value of option',
	 * 					'selected : true or false
	 * 					}]
	 * @type (optionnal) if null, it will be reset all options, else, it will be incremental
	 */

	addOptions : function(options, type){
		var html = "";
		for (var i=0;i<options.length;i++){
			html += (options[i].selected) ? "<option value='"+options[i].value+"' selected='selected'>"+options[i].label+"</option>" : "<option value='"+options[i].value+"'>"+options[i].label+"</option>"; 
		}
		if (type == null)
			this.element.set('html', html);
		else 
			this.element.set('html', this.element.get('html')+html);
		this.loadOptions();
	},
	loadOptions : function(){
		var selectOptions = [];
		this.element.getElements('option').each(function(option, iOption){
			selectOptions.push({'value':option.get('value'),'selected':option.get('selected'),'label':option.get('html')});
		});
		this.selectOptions = selectOptions;
		this.ul.empty();
		var alreadySelected = {'label' : '', 'value':'', 'tip' : null};
		for (var i=0;i<this.selectOptions.length;i++){
			var classSelected = 'option_style';
			if (this.selectOptions[i].selected == true){
				classSelected = 'option_style_hover';
				if (this.type == 'simple'){
					alreadySelected.label = this.selectOptions[i].label;
					alreadySelected.value = "<option value='"+this.selectOptions[i].value+"' selected='selected'></option>";
					alreadySelected.tip = this.selectOptions[i].value;
				}
				else {
					alreadySelected.label += (alreadySelected.label == '') ? this.selectOptions[i].label : ' - '+this.selectOptions[i].label;
					alreadySelected.value += "<option value='"+this.selectOptions[i].value+"' selected='selected'></option>";
					alreadySelected.tip += "<li>"+this.selectOptions[i].label+"</li>";
				}
			}
			
			var li = new Element('li');
			
			if (this.type == 'multiple'){
				var span = new Element('span', {
					'class': classSelected
				});
				span.addEvent('mouseover', function(i){
						this.setCurrentHover(i);
					}.bind(this, [i]));
				
				var input = new Element('input', {
					'type' : 'checkbox',
					'class' : 'check',
					'id'	: this.id+'_check_'+this.selectOptions[i].value,
					'value' : this.selectOptions[i].value
				});
				if (this.selectOptions[i].selected == true)
					input.set('checked', true);
				input.addEvent('click', function(e){
					this.chooseOptionSelect(e);
				}.bind(this));
				
				var text = new Element('label', {
					'class' : 'label',
					'html' : this.selectOptions[i].label,
					'for' : this.id+'_check_'+this.selectOptions[i].value
				});
				input.inject(span, 'top');
				text.inject(span, 'bottom');
				span.inject(li);
				// Recreate a multiple select 
				this.hidden.set('multiple', true);
			}
			else{
				var li = new Element('li');
				var a = new Element('a', {
					'class' : classSelected,
					'href'	: this.selectOptions[i].value,
					'html'  : this.selectOptions[i].label,
					'title' : this.selectOptions[i].label
				});
				
				/// BACK
				a.addEvent('click', function(e){
					
					this.chooseOptionSelect();
					e.stop();
				}.bind(this));
				a.addEvent('mouseenter', function(index){
					this.setCurrentHover(index);
				}.bind(this, [i]));	
				//// BACK
				
				a.inject(li);
			}
			li.inject(this.ul);
		}
		this.items = {
				'currentHover' : null, 
				'total' : this.selectOptions.length,
				'selected' : []
			};
		
		if (alreadySelected.value != ''){
			this.text.set('text', alreadySelected.label);
		}
		else{
			this.text.set('text', this.label);
		}
		this.tip.content = alreadySelected.tip;
		if (this.tip.content == null && this.tip.object != null)
			this.destroySelectTip();
		if (this.tip.content != null && this.options.tips)
			this.buildSelectTip();
		this.hidden.set('html', alreadySelected.value);
		
	},
	
	getUniqid : function(){
	    return uniqid.get();
	},
	
	showSelect : function(){
		smooth = (arguments.length == 0)? true : arguments[0];

		var overflow = this.overflow;
		var overflowContainer = this.overflowContainer;
		var ul = this.ul;
		var parent = this.container.getParent();

		// Ouverture
		
		if (overflowContainer.getStyle('display') == 'none' && this.enabled) {
			
			this.destroySelectTip();
			if (this.size != 0){
				overflow.setStyles({
					'height': '0px',
					'overflow' : 'hidden'
				});
				if (this.options.adjustable){
					this.ul.setStyle('height', '');
					overflow.setStyles({
						'height': '',
						'visibility' : 'hidden'
					});
				}
			}
			overflowContainer.setStyles({
				'visibility': 'hidden',
				'display': 'block'
			});
			if (this.size == 0 || this.options.adjustable)
				this.size = (parseInt(overflow.getStyle('height').split("px")[0]) > this.options.max.height) ? this.options.max.height : overflow.getStyle('height').split("px")[0];
			
			if (!this.options.adjustable)
				this.size = this.options.max.height;
			
			//console.log(this.size);
			this.positionOverflow();
			overflow.setStyles({
				'height': '0px',
				'marginTop' : '0px'
			});
			overflowContainer.setStyles({
				'left' : (this.position == 'bottom') ? String(Display.getX(this.container)+this.options.gap.left)+"px" : String(Display.getX(this.container)+this.options.gap.rLeft)+"px",
				'top' : (this.position == 'bottom') ? String(parseInt(this.getCheatBotOffset())+this.options.gap.top)+"px" :  String((Display.getY(this.container)+this.options.gap.rTop))+"px"
			});
			
			if (smooth) {
				
				var morphIn = new Fx.Morph(overflow, {
					'duration' : 'short',
					onStart: function(){
						ul.setStyle('height', this.size);
						overflowContainer.setStyle('visibility', 'visible');
						overflow.setStyles({
							'visibility': 'visible',
							'overflow': 'hidden'
						});
						
						this.resetCurrentHover();
					}.bind(this),
					onComplete: function(){
						if (this.size == this.options.max.height || !this.options.adjustable)
						{
							this.scrollWrapper = new Element('div', {
								'class' : 'scroll_wrapper',
								'styles' : {
									'height' : this.size
								},
								'id' : this.id+'_scrollWrapper'
							});
							var hContent = this.size;
							if (this.options.scroll.button){
								// Simulate scrollbar width
								var scrollTestO = new Element('div', {
									'class' : this.options.className+'_overflow',
									'styles' : {
										'visibility' : 'hidden'
									}
								}).inject($$('body')[0]);
								var scrollTestWW = new Element('div', {
									'class' : 'scroll_wrapper'
								}).inject(scrollTestO);
								var scrollTestT = new Element('div', {
									'class' : 'scroll_top'
								}).inject(scrollTestWW);
								var scrollTestW = new Element('div', {
									'class' : 'scroll_content'
								}).inject(scrollTestWW);
								var scrollTestF = new Element('div', {
									'class' : 'scroll_foot'
								}).inject(scrollTestWW);
								hContent = this.size-parseInt(scrollTestT.getStyle('height').split('px')[0])-parseInt(scrollTestF.getStyle('height').split('px')[0]);
								// Destroy Simulation
								scrollTestO.destroy();
							}
							if (this.options.scroll.button){
								this.scrollTop = new Element('div',{
									'class' : 'scroll_top',
									'id'	: this.id+"_scrollTop"
								}).inject(this.scrollWrapper);
							}
							this.scrollContent = new Element('div', {
								'class' : 'scroll_content',
								'styles' : {
									'height' : hContent
								},
								'id' : this.id+'_scrollContent'
							}).inject(this.scrollWrapper);
							
							this.scrollHandle = new Element('div', {
								'class' : 'scroll_handle',
								'id'	: this.id+'_scrollHandle'
							}).inject(this.scrollContent);
							if (this.options.scroll.button){
								this.scrollFoot = new Element('div',{
									'class' : 'scroll_foot',
									'id'	: this.id+"_scrollFoot"
								}).inject(this.scrollWrapper);
							}
							$(this.id+'_footer').set('class', 'foot_scroll');
							this.scrollWrapper.inject(overflow);
							this.scroll.object = this.makeScrollbar();
							if (this.options.scroll.button) {
								this.scrollTop.addEvent('mousedown', function(e){
									var step = this.scroll.object.object.step-30;
									this.scroll.object.object.set(step);
								}.bindWithEvent(this));
								this.scrollFoot.addEvent('mousedown', function(e){
									var step = this.scroll.object.object.step+30;
									this.scroll.object.object.set(step);									
								}.bindWithEvent(this));
							}
							this.scroll.has = true;
							overflowContainer.setStyles({
								'left' : (this.position == 'bottom') ? String(Display.getX(this.container)+this.options.gap.left)+"px" : String(Display.getX(this.container)+this.options.gap.rLeft)+"px"
							});
							
							
						}
						else {
							$(this.id+'_footer').set('class', 'foot_no_scroll');
							overflowContainer.setStyles({
								'left' : (this.position == 'bottom') ? String(Display.getX(this.container)+this.options.gap.left)+"px" : String(Display.getX(this.container)+this.options.gap.rLeft)+"px"
							});
						}
						// BACK
						if (Browser.Engine.trident){
							$$('body')[0].addEvents({
								'keydown': function(e){
									this.handleSelectKey(e);
								}.bind(this),
								'click' : function(e){
									this.handleSelectClick(e);
								}.bind(this)
							});
						}
						else{
							window.addEvents({
								'keydown': function(e){
									this.handleSelectKey(e);
								}.bind(this),
								'click' : function(e){
									this.handleSelectClick(e);
								}.bind(this)
							});
						}
						this.fireEvent('show');
					}.bind(this)
				});
				morphIn.start({
					'marginTop' : (this.position == 'bottom') ? '0px' : '-'+String(this.size)+"px",
					'height': this.size
				});
				
				
			}
			else
			{ 
				this.resetCurrentSelected();
				overflowContainer.setStyles({
					'left' : (this.position == 'bottom') ? String(Display.getX(this.container)+this.options.gap.left)+"px" : String(Display.getX(this.container)+this.options.gap.rLeft)+"px"
				});
				overflow.setStyles({
					'visibility' : 'visible',
					'height' : this.size,
					'marginTop' : (this.position == 'bottom') ? '0px' : '-'+String(this.size)+"px"
				});
				if (this.size == this.options.max.height)
					overflow.setStyle('overflow', 'auto');
				overflowContainer.setStyles({
					'visibility': 'visible',
					'left' :(this.position == 'bottom') ? String(Display.getX(this.container)+this.options.gap.left)+"px" : String(Display.getX(this.container)+this.options.gap.rLeft)+"px"
				});
				
				if (Browser.Engine.trident){
					$$('body')[0].addEvents({
						'keydown': function(e){
							this.handleSelectKey(e);
						}.bind(this),
						'click' : function(e){
							this.handleSelectClick(e);
						}.bind(this)
					});
				}
				else{
					window.addEvents({
						'keydown': function(e){
							this.handleSelectKey(e);
						}.bind(this),
						'click' : function(e){
							this.handleSelectClick(e);
						}.bind(this)
					});
				}
				this.fireEvent('show');
			}
		}
		// Fermeture
		else if (overflowContainer.getStyle('display') == 'block'){
			if (Browser.Engine.trident){
				$$('body')[0].removeEvents('keydown');
				$$('body')[0].removeEvents('click');
			}
			else{
				window.removeEvents('keydown');
				window.removeEvents('click');
			}

			if (smooth) {
				var morphIn = new Fx.Morph(overflow, {
					'duration' : 'short',
					onStart: function(){
						overflowContainer.setStyles({
							'left' : (this.position == 'bottom') ? String(Display.getX(this.container)+this.options.gap.left)+"px" : String(Display.getX(this.container)+this.options.gap.rLeft)+"px"
						});
						overflow.setStyles({
							'overflow': 'hidden'
						});
					}.bind(this),
					onComplete: function(){
						overflow.setStyles({
							'overflow': 'auto',
							'height': ''
						});
						overflowContainer.setStyles({
							'display' : 'none',
							'left' : (this.position == 'bottom') ? String(Display.getX(this.container)+this.options.gap.left)+"px" : String(Display.getX(this.container)+this.options.gap.rLeft)+"px",
							'top' : "0px"	
						});
						if (this.options.tips)
							this.buildSelectTip.delay(50, this);
						if (this.options.adjustable && this.scroll.object != null){
							this.scrollWrapper.destroy();
							this.scrollHandle.destroy();
							$(this.id+'_footer').set('class', 'foot_no_scroll');
							this.scroll.object = null;
							this.scroll.has = false;
						}
						this.fireEvent('hide');
					}.bind(this)
				});
				morphIn.start({
					'height': '0px',
					'marginTop' : '0px'
				});
			}
			else{
				overflowContainer.setStyles({
					'left' : (this.position == 'bottom') ? String(Display.getX(this.container)+this.options.gap.left)+"px" : String(Display.getX(this.container)+this.options.gap.rLeft)+"px"
				});
				overflow.setStyles({
					'overflow': 'auto',
					'height': ''
				});
				overflowContainer.setStyles({
					'display' : 'none',
					'top' : '0px'
				});
				if (this.options.tips)
					this.buildSelectTip.delay(50, this);
				if (this.options.adjustable && this.scroll.object != null){
					this.scrollWrapper.destroy();
					this.scrollHandle.destroy();
					$(this.id+'_footer').set('class', 'foot_no_scroll');
					this.scroll.object = null;
					this.scroll.has = false;
				}
				this.fireEvent('hide');
			}
		}
	},
	makeScrollbar : function (horizontal,ignoreMouse){
		//$(selectID+'_ul'), $(selectID+'_scrollContent'), $(selectID+'_scrollHandle')
		var XSize = this.ul.getScrollSize().x;
		var YSize = this.ul.getScrollSize().y;
		var slider = null;
		if (this.size < YSize){
			var steps = (horizontal?(this.ul.getScrollSize().x - this.ul.getSize().x):(this.ul.getScrollSize().y - this.ul.getSize().y));
			slider = new Slider($(this.id+'_scrollContent'), $(this.id+'_scrollHandle'), {
				steps: steps,
				mode: (horizontal?'horizontal':'vertical'),
				onChange: function(step){
					// Scrolls the content element in x or y direction.
					var x = (horizontal?step:0);
					var y = (horizontal?0:step);
					this.ul.scrollTo(x,y);
				}.bind(this)
			}).set(0);
			if( !(ignoreMouse) ){
				// Scroll the content element when the mousewheel is used within the
				// content or the scrollbar element.
				$$(this.ul, this.scrollbar).addEvent('mousewheel', function(e){
					e = new Event(e).stop();
					var step = slider.step - e.wheel * 30;
					slider.set(step);
				});
			}
			// Stops the handle dragging process when the mouse leaves the document body.
			$(document.body).addEvent('mouseleave',function(){slider.drag.stop();});
		}
		return {'object' : slider, 'x' : XSize, 'y' : YSize};
	},
	replaceAbsoluteSelectOverflow : function(){
		var parent = this.container.getParent();
		this.overflowContainer.setStyles({
			'left' : String(Display.getX(parent)+this.options.gap.left)+"px"
		});
	},
	chooseOptionSelect : function(){
		var index = this.items.currentHover;
		var element = (this.type == 'simple') ? $$('#'+this.id+'_ul li a')[index] : $$('#'+this.id+'_ul li span')[index];
		if (this.type == 'simple'){
			
			$(this.id+'_text').set('html', element.get('title'));
			$(this.id).set('html', "<option value='"+element.get('href')+"' selected='selected'></option>");
			this.items.selected[0] = index;
			this.setTipContent("<span class='simple'>"+element.get('title')+"</span>");
			this.showSelect(false);
		}
		else{
			
			var input = element.getElement('input');
			if (input.checked){
				element.set('class', 'option_style_hover');
			}
			else{
				element.set('class', 'option_style');
			}
			var str = "";
			var value = "";
			var tipText = "<ul>";
			var arraySelected = [];
			$$('#'+this.id+'_ul li input').each(function(el, index){
				if (el.checked == true)	{
					arraySelected.push(index);
					str += el.getNext('label').get('text')+' - ';
					tipText += "<li>"+el.getNext('label').get('text')+"</li>";
					value += "<option value='"+el.get('value')+"' selected='selected'></option>";
				}
			});
			this.items.selected = arraySelected;
			tipText += "</ul>";
			if (str.length > 3){		
				$(this.id+'_text').set('html', str.substr(0, str.length-3));
				this.setTipContent(tipText);
			}
			else{
				$(this.id+'_text').set('html', this.label);
				this.tip.content = null;
			}
			
			this.hidden.set('html', value);
			
		}
		
		// Set Virtual Original Select
		this.element.getElements('option').each(function(item, index){
			item.set('selected', false);
		});
		for (var i=0;i<this.items.selected.length;i++)
			this.element.getElements('option')[i].set('selected', true);
		
		this.fireEvent('select',[element]);
		
	},
	setTipContent : function(str){
		this.tip.content = (str == '') ? null : str; 
	},
	handleSelectClick : function(e) {
		sX = (Browser.Engine.trident) ? e.client.x+parseInt(document.body.parentNode.scrollLeft) : e.client.x+parseInt(window.scrollX);
		sY = (Browser.Engine.trident) ? e.client.y+parseInt(document.body.parentNode.scrollTop) : e.client.y+parseInt(window.scrollY);
		if (this.overflow.getStyle('display') == 'block')
		{	
			var xMinOverflow = Display.getX(this.overflow);
			var yMinOverflow = Display.getY(this.overflow);
			var xMaxOverflow = xMinOverflow+parseInt(this.overflow.getStyle('width').split('px')[0]);
			var yMaxOverflow = yMinOverflow+parseInt(this.overflow.getStyle('height').split('px')[0]);
			if (sX > xMinOverflow && sX < xMaxOverflow && sY > yMinOverflow && sY < yMaxOverflow){
				return;
			}
			else{
				this.showSelect(false);
			}
		}
		
	},
	handleSelectTabKey : function(e) {
		var code = e.code;
		if (code != 9)
			return;
		else
		{
			this.previousElement.blur();
			this.showSelect();
			e.stop();
		}
	},
	handleSelectKey : function(e) {
		/* Down = 40
		 * Up = 38
		 * Right = 39
		 * Left = 37
		 * Enter = 13
		 * Esc = 27 	
		 * Tab = 9
		 * Shift = 16
		 * Space = 32 
		 */

		var code = e.code;
		// Esc
		if (code == 27)
			this.showSelect(false);
		// Up
		if (code == 38){
			this.setPreviousSelectHover();
			e.stop();
		}
		// Down
		if (code == 40){
			this.setNextSelectHover();
			e.stop();
		}
		// Space & Enter
		if (code == 32 || code == 13){
			if (this.type != 'simple'){
				var input = $$("#"+this.id+"_ul li span")[this.items.currentHover].getElement("input"); 
				input.set("checked", (input.get('checked') == true) ? false : true);
			}
			/// BACK
			this.chooseOptionSelect.delay(10, this,[this.items.currentHover]);
			e.stop();
		}
		if (code == 9){
			this.showSelect(false);
			if (this.nextElement != null){
				this.nextElement.focus();
				e.stop();
			}
		}
	},
	setNextSelectHover : function (){
		if (this.items.currentHover == null || this.items.currentHover == (this.items.total-1)){
			if (this.scroll.has){
				this.scroll.object.object.set(0);
			}
			this.setCurrentHover(0);
		}
		else{
			var newIndex = this.items.currentHover+1;
			if (this.scroll.has){
				var itemSelect = $$('#'+this.id+'_ul li')[newIndex];
				var scrollMore = Display.getY(itemSelect)-Display.getY($$('#'+this.id+'_ul li')[this.items.currentHover]);
				var step = this.scroll.object.object.step + scrollMore;
				this.scroll.object.object.set(step);
			}
			this.setCurrentHover(newIndex);
		}
	},
	setPreviousSelectHover : function (){
		if (this.items.currentHover == null || this.items.currentHover == 0){
			if (this.scroll.has){
				this.scroll.object.object.set(this.scroll.object.y);
			}
			this.setCurrentHover((this.items.total-1));
		}
		else{
			var newIndex = this.items.currentHover-1;
			if (this.scroll.has){
				var itemSelect = $$('#'+this.id+'_ul li')[newIndex];
				var scrollMore = Display.getY($$('#'+this.id+'_ul li')[this.items.currentHover])-Display.getY(itemSelect);
				var step = this.scroll.object.object.step - scrollMore;
				this.scroll.object.object.set(step);
			}
			this.setCurrentHover(newIndex);
		}
	},
	resetCurrentHover : function (){
		if (this.type == 'simple') {
			if ($chk($$('#'+this.id+'_ul li a.option_style_hover')[0])){
				$$('#'+this.id+'_ul li a.option_style_hover')[0].set('class', 'option_style');
			}
		}
		else{
			$$('#'+this.id+'_ul li span.option_style_hover input').each(function(el, index){
				if (el.checked == false) {
					el.getParent().set('class', 'option_style');
				}
			});
		}	
		this.items.currentHover = null;
	},
	setCurrentHover : function(index){
		this.resetCurrentHover();
		this.items.currentHover = parseInt(index);
		if (this.type == 'simple'){
			$$('#'+this.id+'_ul li a')[index].set('class', 'option_style_hover');
		}
		else {
			$$('#'+this.id+'_ul li span')[index].set('class', 'option_style_hover');
		}	
	},
	positionOverflow : function(){
		if (this.options.position == 'top')
			this.position = 'top';
		else if (this.options.position == 'bottom')
			this.position = 'bottom';
		else {
			var heightD = window.innerHeight;
			var spaceBefore = Display.getY($(this.container))-window.scrollY;
			var spaceAfter = this.getCheatBotOffset(true);
			if ((heightD-(spaceAfter+this.options.gap.top)) >= this.size)
				this.position = 'bottom';
			else
				this.position = ((spaceBefore+this.options.gap.rTop) >= this.size) ? 'top' : 'bottom';
		}
	},
	getCheatBotOffset : function(relative){
		this.cheatPosition.bottom.setStyle('display', 'block');
		if (relative == null)
			var offset =  (Browser.Engine.trident) ? Display.getY($(this.cheatPosition.bottom)) : Display.getY($(this.cheatPosition.bottom));
		else
			var offset =  (Browser.Engine.trident) ? Display.getY($(this.cheatPosition.bottom))-document.body.parentNode.scrollTop : Display.getY($(this.cheatPosition.bottom))-window.scrollY;
		this.cheatPosition.bottom.setStyle('display', 'none');
		return parseInt(offset);
	},
	buildSelectTip : function(){
		if (this.options.tips) {
			if (this.tip.content != null){
				this.container.store('tip:text', this.tip.content);
				this.tip.object = new Tips('#'+this.id+'_container',{'className':this.options.className+'_tips'});
			}
		}
	},
	destroySelectTip : function(){
		if (this.tip.object != null){
			this.container.store('tip:text', '');
			this.tip.object.hide();
			this.tip.object.detach('#'+this.id+'_container');
			this.tip.object = null;
		}
	},
	enable : function(){
		this.enabled = true;
	},
	disable : function(){
		this.enabled = false;
	},
	handlePrevNextInput : function(){
		this.previousElement = null;
		this.nextElement = null;
		if (!Browser.Engine.trident) {
			for (var e=0;e<$(this.form.get('id')).elements.length;e++){
				if ($(this.form.get('id')).elements[e].get('id') == this.id && e != 0 && (e-1) != $(this.form.get('id')).elements.length){
					if ($(this.form.get('id')).elements[e-1].get('tag') == 'input' && $(this.form.get('id')).elements[e-1].get('type') != 'hidden')
						this.previousElement = $(this.form.get('id')).elements[e-1];
					if ($(this.form.get('id')).elements[e+1].get('tag') == 'input' && $(this.form.get('id')).elements[e+1].get('type') != 'hidden')
						this.nextElement = $(this.form.get('id')).elements[e+1];
				}
			}
		}
		if (this.previousElement != null){
			this.previousElement.addEvent('blur', this.windowTabBlur.bind(this));
			this.previousElement.addEvent('focus', this.windowTabFocus.bind(this));
			
		}
	},
	windowTabBlur : function(){
		if (Browser.Engine.trident){
			$$('body')[0].removeEvents('keydown');
		}
		else{
			window.removeEvents('keydown');
		}
	},
	windowTabFocus : function(){
		if (Browser.Engine.trident){
			$$('body')[0].addEvent('keydown',function(e){
				this.handleSelectTabKey(e);
			}.bind(this));	
		}
		else{
			window.addEvent('keydown', function(e){
				this.handleSelectTabKey(e);
			}.bind(this));	
		}	
	},
	reset : function(){
		this.items.selected = [];
		$(this.id+'_text').set('html', this.label);
		$(this.id).set('html', "");
		this.tip.content = null;
		
		if (this.type != 'simple'){
			
			$$('#'+this.id+'_ul li input').each(function(el, index){
				el.set('class', 'option_style');
				el.set('checked', false);
			});
			this.hidden.set('html', '');
		}
		
		// Set Virtual Original Select
		this.element.getElements('option').each(function(item, index){
			item.set('selected', false);
		});
	}
});
Selects.elements = {};

