Aheuh.SelectHtml = Class.create({
	
	initialize: function (params) {		
		this._params = params;
		this._onChangeFunction = params.onChangeFunction;
		this.isOpen = this._closeOnClick = this._keyActive = this.changeFunctionActive = false;
		this._styles = new Array();
		this._datas = new Array();
		this.keyIndex = {};
		this._select = $(params.selectHtml);
		this._select.setStyle({ visibility:'hidden' });
		this._index = this.keyCntCheck = 0;
	},
	
	init: function () {
		
		this._writeHtml = $(this._params.selectWrite);
		this._zIndex = this._writeHtml.getStyle('zIndex');
			
		this._setStyles();
		this._style = this._styles[this._params.style || 0];
		this._parseDatas(this._select);
		
		this._write();		
			
		this._main = $$('#'+this._params.selectWrite+' .selectMain')[0];
		this._mask = $$('#'+this._params.selectWrite+' .selectMask')[0];		
		this._content = $$('#'+this._params.selectWrite+' .selectOptions')[0];
		
		this._scroller =  new Aheuh.Scroller("vertical",{
			container: $$('#'+this._params.selectWrite+' .selectOptions')[0],
			mask: $$('#'+this._params.selectWrite+' .selectMask')[0],
			scUp: $$('#'+this._params.selectWrite+' .selectUp')[0],
			scDn: $$('#'+this._params.selectWrite+' .selectDn')[0],
			cursorV: $$('#'+this._params.selectWrite+' .selectCursor')[0],
			scrollbar: $$('#'+this._params.selectWrite+' .selectScrollbar')[0],
			scrollbarBgV: $$('#'+this._params.selectWrite+' .selectScrollbarBgV')[0],
			scrollElems: $$('#'+this._params.selectWrite+' .scrollElems')[0]
		},10,2);
			
		this._scroller.init();
	
		this._setEvents();
		this.setSelectedIndex(this._index);
		this._scroller.showScrollElems("vertical","hidden");

	},
	
	_setStyles: function () {
		var styles = Aheuh.SelectHtmlConfig.styles;
		for (var i in styles) {
			this._styles.push({ name:i, html:styles[i] });
		}
	},
	
	_parseDatas: function (o) {
		for (var i=0;i<o.length;i++) {
			if (o[i].selected) {
				this._index = i;
			}
			this._add({ data:o[i].value, label:o[i].innerHTML });
		}
	},
	
	_write: function () {
		
		this._writeHtml.innerHTML = this._style.html;
		var writeOptions = $$('#'+this._params.selectWrite+' .selectOptions')[0];
		
		var options = '<ul>';
		for (var i=0;i<this._datas.length;i++) {
			options += '<li id="'+i+''+this._select.id+'"><a href="#0">' + this._datas[i].label + '</a></li>';
		}
		options += '</ul>';
		writeOptions.innerHTML = options;		
		
	},
	
	_add: function (o) {
		this._addKeyIndex(o.label.charAt(0).toLowerCase(),this._datas.length);
		this._datas[this._datas.length] = o;
	},
	
	_addKeyIndex: function (key,index) {
		if (!this.keyIndex[key]) { this.keyIndex[key] = {index:[]}; }
		this.keyIndex[key].index[this.keyIndex[key].index.length] = index;
	},
	
	_setEvents: function () {
		
		var tmp = this._content.getElementsByTagName("a");
		
		for (var i=0;i<tmp.length;i++) {
			tmp[i].className = "s"+i;
			Event.observe(tmp[i], "click", this._onItemClickEvents.bindAsEventListener(this));
			Event.observe(tmp[i], "mouseover", this._onItemOverEvents.bindAsEventListener(this));
			Event.observe(tmp[i], "mouseout", this._onItemOutEvents.bindAsEventListener(this));
		}
		
		Event.observe(this._main, "click", this._onMainClick.bindAsEventListener(this));
		Event.observe(this._main, "click", Event.SelectionClear);
		Event.observe(this._main, "mouseover", this._onMainOver.bindAsEventListener(this));
		Event.observe(this._main, "mouseout", this._onMainOut.bindAsEventListener(this));		
		Event.observe(this._main, this._scroller._mouseWheelEvent, this._onMainMouseWheel.bindAsEventListener(this));
		
		Event.observe(this._writeHtml, "mouseover", this._onWriteMouseOver.bindAsEventListener(this));
		Event.observe(this._writeHtml, "mouseout", this._onWriteMouseOut.bindAsEventListener(this));
		
		Event.observe(document, "mouseup", this._checkToClose.bindAsEventListener(this));
		Event.observe(document, "keydown", this._setSelectedKeyboardIndex.bindAsEventListener(this));
		
	},
	
	_onItemClickEvents: function (e) {
		this._content.style.visibility = this._mask.style.visibility = "hidden";
		this.isOpen = this._closeOnClick = this._keyActive = false;
		this.setSelectedIndex(parseInt(Event.element(e).parentNode.id)); 
		this._scroller.reload();
		this._scroller.showScrollElems("vertical","hidden");
	},
	_onItemOverEvents: function (e) {
		if (this.itemMouseOver!="") { Element.removeClassName($(this.keyItemSelected), "on"); }
		this.itemMouseOver = Event.element(e);
	},
	_onItemOutEvents: function () {
		this.itemMouseOver = "";
	},
	
	_onMainClick: function () {
		this._scroller.reload();
		this._scroller.moveToAnchor(this._index+this._select.id);
		var visibility = (this.isOpen) ?'hidden' :'visible';	
		this._showHideDatas(visibility);
	},
	_onMainOver: function () {
		this._keyActive = true;
	},
	_onMainOut: function () {
		if (!this.isOpen){  this._keyActive = false; }
	},
	_onMainMouseWheel: function (e) {
		(Event.Wheel(e)==-1) ?this.setSelectedIndex(this._index+1) :this.setSelectedIndex(this._index-1);
	},
	
	_onWriteMouseOver: function () {
		if (this.isOpen) { this._keyActive = true; this._closeOnClick = false; }
	},
	_onWriteMouseOut: function () {
		if (this.isOpen) { this._keyActive = false; this._closeOnClick = true; }
	},
	
	_showHideDatas: function (visibility) {
		this._content.style.visibility = this._mask.style.visibility = visibility;
		if (this._scroller.scrollingV) { 
			(!this.isOpen) ?this._scroller.viewScrollElems("vertical","visible","noChange") :this._scroller.showScrollElems("vertical","hidden");
		}
		this.isOpen = this._keyActive = (visibility=="hidden") ?false :true;		
		var zIndex = (this.isOpen) ?Number(this._zIndex)+1 :this._zIndex;		
		this._writeHtml.setStyle({ zIndex:zIndex })		
		this.itemMouseOver = "";
	},
	
	getSelectedData: function () {
		return this._datas[this._index].data;
	},
	
	getSelectedLabel: function () {
		return this._datas[this._index].label;
	},
	
	setSelectedIndex: function (index) {
		if (index>=0&&index<this._datas.length) {
			Element.removeClassName(this._content.getElementsByTagName('a')[this._index], "on");
			this._index = index;
			this._main.innerHTML = this.getSelectedLabel();			
			Element.addClassName(this._content.getElementsByTagName('a')[index], "on");
			this._select.selectedIndex = index;			
			if (this._onChangeFunction&&this.changeFunctionActive) { this._onChangeFunction(); }
			if (!this.changeFunctionActive) { this.changeFunctionActive = true; }
		}
	},
	
	setSelectedData : function (data) {
		this.changeFunctionActive = false;
		for (var i=0;i<this._datas.length;i++) { if (this._datas[i].data==data) { this.setSelectedIndex(i); }}
	},
	
	_checkToClose: function () {
		if (this._closeOnClick&&this.isOpen) {
			this._showHideDatas("hidden");
			this._scroller.showScrollElems("vertical","hidden");
		}
	},
	
	_setSelectedKeyboardIndex: function (e) {
		
		if (this._keyActive) {
			
			e.stop();
			
			var keyCode = (window.event) ?e.keyCode :e.which;
			var keyCodeLabel = String.fromCharCode(keyCode).toLowerCase();
			
			if (keyCode==13&&this.isOpen) {
				if (this.itemMouseOver!="") this.setSelectedIndex(parseInt(this.itemMouseOver.parentNode.id));
				this._showHideDatas("hidden");
			}
			
			if (this.keyIndex[keyCodeLabel]) {
				
				this.keyCntCheck =  (this.currentKey==keyCodeLabel) ?(this.keyCntCheck<this.keyIndex[keyCodeLabel].index.length-1) ?this.keyCntCheck + 1 :0 :0;
				
				if (this.keyItemSelected!="") {
					Element.removeClassName($(this.keyItemSelected), "on");
				}
				Element.removeClassName(this._content.getElementsByTagName("div")[this._index], "on");
				
				this.keyItemSelected = this.keyIndex[keyCodeLabel].index[this.keyCntCheck] + this._select.id;
				Element.addClassName($(this.keyItemSelected), "on");
				
				this._scroller.moveToAnchor(this.keyItemSelected);
				this.currentKey = keyCodeLabel;
				this.itemMouseOver = $(this.keyItemSelected);
				
				this.setSelectedIndex(this.keyIndex[keyCodeLabel].index[this.keyCntCheck]);
			
			}
			
			if (keyCode==38&&this._index>0) {
				this.setSelectedIndex(this._index-1);
				this._scroller.moveToAnchor(this._content.getElementsByTagName('li')[this._index].id);
			}
			else if (keyCode==40&&this._index<this._datas.length) {
				this.setSelectedIndex(this._index+1);
				this._scroller.moveToAnchor(this._content.getElementsByTagName('li')[this._index].id);
			}
			
		}
		
	}
	
});
