var CustomSelect = new Class({
	Implements     : [Events, Options],
	options        : {
		onChange : $empty,
		onSelect : $empty,
		onShow   : $empty,
		onHide   : $empty,
		theme    : 'aqua',
		max_lines : 20, 
		line_height : 18 
	},
	box            : null, // เ?เฮเสแ? (a c div เยเอแ?แ?แ?เศ)
	select         : null, // เ?เภแ?เศเยเอแ?เษ แ?เลเหเลเสแ?เมเฮเสแ?
	selectbox      : null, // เ?เมแ?เลเสแ? แ?เลเหเลเสแ?เมเฮเสแ?เภ (UL เฤเลแ?เลเยเฮ)
	selectedIndex  : null, // เเลเสแ?แ?เศเษ เศเอเฤเลเสแ? แ?เลเหเลเสแ?เมเฮเสแ?เภ
	currentElement : null, // เเลเสแ?แ?เศเษ เยแ?เฤเลเหเลเอเอแ?เษ แ?เหเลเฬเลเอแ? แ?เลเหเลเสแ?เมเฮเสแ?เภ
	currentText    : null, // เเลเสแ?แ?เศเษ แ?เลเสแ?แ?
	width          : null, // เฃเศแ?เศเอเภ เอเภแ?เศเยเอเฮเรเฮ แ?เลเหเลเสแ?เมเฮเสแ?เภ
	display        : false, // เจแ?เภแ?แ?แ? แ?เลเหเลเสแ?เมเฮเสแ?เภ (เฯเฮเสเภเวเภเอ เศเหเศ เอเลแ?)
	has_scrolling  : false, // เ?แ?แ?แ? เหเศ เฯแ?เฮเสแ?แ?แ?เสเภ แ? แ?เลเหเลเสแ?เมเฮเสแ?เภ
	
	initialize: function(select, options) {
		this.setOptions(options);
		this.select = select;
		
		this.width = this.select.getWidth();
		
		// เเมเศแ?เภเลเฬ เอเภแ?เศเยเอแ?เษ แ?เลเหเลเสแ?เมเฮเสแ?
		this.select.setStyle('display', 'none');
		
		// เจเฮเวเฤเภเลเฬ แ?เฮเมแ?แ?เยเลเอเอแ?เษ แ?เลเหเลเสแ?เมเฮเสแ? เอเภ เฮแ?เอเฮเยเล select
		this.build_selectbox();
		
		// เ?เภเฦเภแ?เศเล เอเภ แ?เลเหเลเสแ?เมเฮเสแ?
		this.box.addEvent('mousedown', function(e) {
			if (this.display) {
				this.hide();
			} else {
				this.show();	
				this.box.focus();
			}
			
			e.stop();
		}.bind(this) );
		

		// เ?เมแ?เภแ?เอเภแ? แ?เลเภเสแ?เศแ? เอเภ onchange เอเภแ?เศเยเอเฮเรเฮ แ?เลเหเลเสแ?เมเฮเสแ?เภ
		this.select.addEvent('change', function(e) {
			e.stop();
			this.selectbox.getElements('li').each(function(li) {
				if (li.getProperty('index') == this.select.selectedIndex)
					this.change_item.run(li, this);
			}.bind(this) )
		}.bind(this) );
		
		// เ?แ?เศ เสเหเศเสเล เอเภ document เวเภเสแ?แ?เยเภเลเฬ แ?เลเหเลเสแ?เมเฮเสแ?
		window.document.addEvent('click', function(e) {
			var obj = e.target;
			while (obj.parentNode && obj != this.box) obj = obj.parentNode;
			if (obj != this.box) this.hide();
		}.bind( this ));
	},
	
	/* เเมแ?เภแ?แ? เยแ?เฯเภเฤเภแ?แ?เศเษ แ?เฯเศแ?เฮเส */
	hide: function() {
		if (this.display) {
			this.selectbox.setStyle('display', 'none');
			this.display = false;
			this.box.removeClass('focused');
			
			this.selectbox.getElements('li').each(function(li) {
				if (li.getProperty('index') == this.select.selectedIndex) {
					this.unselect_lis();
					this.currentElement = li.addClass('selected');;
				}
			}.bind(this) );
			
			this.fireEvent('onHide', this.currentElement);
		}
	},
	
	/* เ?เฮเสเภเวเภแ?แ? เยแ?เฯเภเฤเภแ?แ?เศเษ แ?เฯเศแ?เฮเส */
	show: function() {
		if (!this.display) {
			this.fireEvent('onShow', this.currentElement);
			this.selectbox.setStyle('display', 'block');
			this.display = true;
			this.box.addClass('focused');
			
			// เ?แ?แ?แ? เหเศ เฯแ?เฮเสแ?แ?แ?เสเภ แ? แ?เหเลเฬเลเอแ?เภ?
			this.has_scrolling = this.selectbox.getScrollSize().y > this.selectbox.getHeight();
		}
	},
	
	/* เจเฮเวเฤเภแ?แ? แ?เฮเมแ?แ?เยเลเอเอแ?เษ แ?เลเหเลเสแ?เมเฮเสแ? เศเว แ?แ?เภเอเฤเภแ?แ?เอเฮเรเฮ */
	build_selectbox: function() {
		// เจเฮเวเฤเภแ?แ? แ?เหเลเฬเลเอแ? A เศ DIV เยเอแ?แ?แ?เศ A
		this.box = new Element('a', {
			'class'  : this.options.theme,
			'href'   :  'javascript:;',
			'styles' : {
			}
		}).inject(this.select, 'after');
		
		this.box_div = new Element('div').inject(this.box);
		
		// เจเฮเวเฤเภแ?แ? แ?เฯเศแ?เฮเส UL
		this.selectbox     = new Element('ul', {
			'class' : this.options.theme
		}).inject( this.box, 'after' );
		this.selectedIndex = this.select.selectedIndex;
		
		// เแ?แ?เภเอเภเยเหเศเยเภเลเฬ แ?เศแ?เศเอแ? เยแ?เฯเภเฤเภแ?แ?เลเรเฮ เฬเลเอแ?
//		if (this.selectbox.getWidth() < this.width)
//			this.selectbox.setStyle('width', this.width + 'px');
		
		// เจเฮเวเฤเภเลเฬ li แ?เหเลเฬเลเอแ?แ? แ?เฯเศแ?เสเภ, เยแ?เฤเลเหแ?เลเฬ แ?เลเสแ?แ?เศเษ แ?เหเลเฬเลเอแ?
		// เศ เอเภเยเลแ?เศเยเภเลเฬ แ?เฮเมแ?แ?เศแ?
		this.build_options();
		
		// เ เลเภเรเศแ?เฮเยเภเอเศเล แ?เหเลเฬเลเอแ?เภ A เอเภ เสเอเฮเฯเสเศ
		this.box.addEvent((Browser.Engine.trident || Browser.Engine.webkit) ?
			'keydown' : 'keypress', this.change_item_on_keyup.bind( this ));
		
		// เ เลเภเรเศแ?เฮเยเภเอเศเล เอเภ แ?เฮเสแ?แ?
		this.box.addEvent('focus', function() {
			this.box.addClass('focused');
		}.bind(this) );
		
		this.box.addEvent('blur', function() {
			this.box.removeClass('focused');
		}.bind(this) );
	},
	
	/* เ?เฮแ?แ?แ?เฮเศแ?แ? แ?เฯเศแ?เฮเส LI แ?เหเลเฬเลเอแ?เฮเย */
	build_options: function() {
		this.select.getElements('option').each(function(option) {
			var li = new Element('li')
			  .set('text', option.get('text') )
			  .inject( this.selectbox )
			  .setProperty('index', option.index); // เแ?แ?เภเอเภเยเหเศเยเภเลเฬ เศเอเฤเลเสแ?
			
			// เแ?แ?เภเอเภเยเหเศเยเภเลเฬ เฮแ?เฬเลแ?เลเอเอแ?เษ แ?เหเลเฬเลเอแ?
			
			if (option.get("value").contains(":all")){
			   li.setStyle("font-weight","bold");
			   li.setStyle("color","#293C5A");
			}
			
			if (option.selected) {
				this.currentElement = li.addClass( 'selected' );
				this.currentText = option.get('text');
			}
			
			// เแ?แ?เภเอเภเยเหเศเยเภเลเฬ แ?เฮเมแ?แ?เศเล เอเภ เยแ?เมเฮแ? แ?เหเลเฬเลเอแ?เภ เย แ?เฮเวเฤเภเอเอเฮเฬ เฤแ?เฮเฯเมเฮเสแ?เล 
			li.addEvent('mouseup', function(e) {
				e.stop();
				this.change_item.run(li, this);
				this.hide();
			}.bind(this) );
		}.bind(this));
		
		// เ?เรแ?เภเอเศแ?เศเยเภเลเฬ เยแ?แ?เฮแ?แ? แ?เลเหเลเสแ?เมเฮเสแ?เภ, เลแ?เหเศ เย เอเลเฬ เมเฮเหเลเล
		if (this.select.options.length > this.options.max_lines) {
			// เ เภแ?แ?แ?เศแ?แ?เยเภเลเฬ เยแ?แ?เฮแ?แ? แ?เลเหเลเสแ?เมเฮเสแ?เภ
			// TODO: this.options.line_height แ?เภแ?แ?แ?เศแ?แ?เยเภแ?แ? เฤเศเอเภเฬเศแ?เลแ?เสเศ
			var height = this.options.line_height * this.options.max_lines;
			
			this.selectbox.setStyles({
				'height'     : height+'px',
				'overflow-y' : 'auto'
			});
		}
		
		/* เแ?แ?เภเอเภเยเหเศเยเภเลเฬ เยแ?เฤเลเหเลเอเศเล เฯแ?เศ เอเภเยเลเฤเลเอเศเศ เฬแ?แ?เศ */
		this.toggle_selection();
		
		/* เแ?แ?เภเอเภเยเหเศเยเภเลเฬ แ?เลเสแ?แ?เศเษ แ?เลเสแ?แ? */
		this.box_div.set('text', this.currentText );
	},
	
	/* เ?เลแ?เลแ?แ?แ?เฮเศแ?แ? แ?เลเหเลเสแ?เมเฮเสแ? */
	rebuild: function() {
		// เ?แ?เศแ?เภเลเศเฬ แ?เลเหเลเสแ?เมเฮเสแ?
		this.selectbox.getElements('li').each(function(li) {
			li.dispose();
		});
		
		this.build_options();
	},
	
	/* เแ?แ?เภเอเภเยเหเศเยเภเลเฬ เยแ?เฤเลเหเลเอเศเล เฯแ?เศ เอเภเยเลเฤเลเอเศเศ เฬแ?แ?เศ */
	toggle_selection: function() {
		this.selectbox.getElements('li').each(function(li) {
			li.addEvent('mouseenter', function() {
					this.unselect_lis();
					this.currentElement = li.addClass('selected'); 
					this.selectedIndex = this.currentElement.getProperty('index');
					this.fireEvent('onSelect', this.currentElement);
			}.bind( this ) );
		}.bind( this ));
	},
	
	/* เจเอแ?แ?แ? เยแ?เฤเลเหเลเอเศเล แ?เฮ เยแ?เลแ? แ?เหเลเฬเลเอแ?เฮเย li */
	unselect_lis: function() {
		this.selectbox.getElements('li').each(function(li) {
			li.removeClass('selected');
		});
	},
	
	/* Change item srom selectbox */
	change_item: function(li) {
		// เ?แ?เศแ?เภเลเฬ เยแ?เล
		this.unselect_lis(this.selectbox);
		
		this.selectedIndex  = li.getProperty('index');
		this.currentElement = li;
		
		// เแ?แ?เภเอเภเยเหเศเยเภเลเฬ เสเหเภแ?แ? เยแ?เมแ?เภเอเอเฮเฬแ? แ?เหเลเฬเลเอแ?แ?
		this.currentElement.addClass('selected');

		// เแ?แ?เภเอเภเยเหเศเยเภเลเฬ เยแ?เมแ?เภเอเอแ?เษ แ?เลเสแ?แ?
		this.box.getElement('div').set('text', this.currentElement.get('text') );
		
		// เ?เลเอแ?เลเฬ เศเอเฤเลเสแ? เย เอเภแ?เศเยเอเฮเฬ แ?เลเหเลเสแ?เมเฮเสแ?เล
		this.select.selectedIndex = this.selectedIndex;
		
		// เ?แ?เหเศ เย selectbox เฯเฮแ?เยเศเหเภแ?แ? เฯแ?เฮเสแ?แ?แ?เสเภ ...
		//for (i in this.selectbox) console.log(i)
		//alert( this.selectbox.getScrollSize().y + ' - ' + this.selectbox.getHeight())
		if (this.has_scrolling) {
			//console.log('has scrolling')
		}
		//console.log(this.selectbox.getScroll().y);

		
		this.fireEvent('onChange', [this.currentElement,
			this.select.options[ this.selectedIndex ].get('value')]);
	},
	
	/* เฝแ?เอเฤเหเศเอเร เอเภเฦเภแ?เศเษ เอเภ เสเอเฮเฯเสเศ up down left right esc */
	change_item_on_keyup: function(e) {
		if (e.key == 'tab' || e.key == 'esc' || e.key == 'enter') {
			this.hide();
			return true;
		}
		if ((e.key == 'up' || e.key == 'down') && e.alt) {
			this.display ? this.hide() : this.show();
			return true;
		}
		
		var li = null;
		
		/* เ?เภเยเศเรเภแ?เศแ? เศ เฯเฮเศแ?เส */
		if (e.key == 'up' || e.key == 'left') {
			li = this.change_element_by_method('getPrevious');
		} else if (e.key == 'down' || e.key == 'right') {
			li = this.change_element_by_method('getNext');
		} else if (e.code == 36 || e.code == 33) {
			li = this.change_element_by_method('getFirst', true);
		} else if (e.code == 35 || e.code == 34) {
			li = this.change_element_by_method('getLast', true);
		} else {
			// เ?เศเมเฮ เศแ?เลเฬ แ?เหเลเฬเลเอแ? เฯเฮ เยเยเลเฤเลเอเอเฮเษ เมแ?เสเยเล
			li = this.change_element_by_char(e.key);
		}
		
		if (li != null) {
			this.fireEvent('onSelect', li);
			this.change_item.run(li, this);
		}
	},
	
	/* เ?เฮเหแ?แ?เศแ?แ? แ?เหเลเฬเลเอแ? แ?เฯเศแ?เสเภ เฯเฮ แ?เสเภเวเภเอเอเฮเฬแ? เฬเลแ?เฮเฤแ? */
	change_element_by_method: function(method, from_child) {
		return from_child ? this.currentElement.getParent()[method]() : 
			this.currentElement[method]();
	},
	
	/* เ?เฮเหแ?แ?เศแ?แ? แ?เหเลเฬเลเอแ? แ?เฯเศแ?เสเภ เฯเฮ แ?เสเภเวเภเอเอเฮเษ เมแ?เสเยเล */
	change_element_by_char: function(key) {
		// เ?แ?เลเฬ เอแ?เฦเอแ?เษ แ?เหเลเฬเลเอแ?
		var length  = this.selectbox.getElements('li').length;
		var li   = null;
		var patt = new RegExp('^'+key, 'i');
		
		var i = 0;
		var el = this.currentElement;
		while ((el = el.getNext() || el.getParent().getFirst()) && li == null) {
			i++;
			if (i > length) { break;} // Ugly, but works
			if (patt.test( el.get('text') )) {
				li = el;
			}
		}
		
		return li;
	}
});