var MooSelect = new Class({	
	Implements: [Events, Options],	
	options: {	
		selectClass: 'moo-select',
		optionClass: 'moo-option',
		optionSelected: 'selected',
		optionShow: 6,
		selectHeight: 15,	
		fx: {
			duration: 200,
			link: 'cancel'
		},		
		onSelect: $empty,
		onShow: $empty,
		onHide: $empty,
		onOver: $empty		
	},	
	initialize: function(selector, options){
		this.setOptions(options);
		this.selector = $(selector);
		if(!this.selector) return;
		this.setup();		
	},	
	setup: function(){
		this.selector.addClass('hide');
		if(this.selector.get('tag') != 'select') return;				
		this.selector.getNext().addEvent('click', this.show.bind(this));
		this.selectOptions = new Element('ul', {
			'class': this.options.optionClass,
			'styles': {
				'opacity': 0,
				'position': 'absolute',
				'overflow-x': 'hidden',
				'width': 273
			}
		}).inject(document.body);
		
		this.selectOptions.fx = new Fx.Morph(this.selectOptions, $merge(this.options.fx));	
		this.selectText = new Element('input', {
			'type': 'text',
			'value': this.selector.get('text'),			
			'rel': this.selector.get('value'),			
			'name': this.selector.get('name'),			
			'id': this.selector.get('name')			
		}).replaces(this.selector);		
		this.selector.getElements('option').each(function(opt){
			this.createOptions(opt);				
		}.bind(this));
		this.selected = this.selectOptions.getElement('li.' + this.options.optionSelected);		
		this.heightOne = this.selected.getCoordinates().height;
		this.widthOne = this.selected.getCoordinates().width;
		this.heightShow = this.heightOne * this.options.optionShow;	
		this.optionHeight = this.selectOptions.getElements('li').length * this.heightOne;
		this.focused = this.selected;
		this.selectText.set('value', this.selected.get('text'));		
		this.showing = false;
		this.forceShow = false;		
	},
	createOptions: function(opt){
		var newOption = new Element('li', {				
			'styles':{				
				'width': 273
			},
			'events': {
				'mouseover': this.over.bind(this),				
				'mousedown': this.select.bind(this)				
			}

		}).adopt(new Element('span', {
			'html': opt.get('text'),
			'styles':{				
				'padding-left': this.options.paddingLeft,
				'height': this.options.selectHeight,
				'width': 273
			}
		}));	
		if(opt.selected){
			newOption.addClass(this.options.optionSelected);
		}
		newOption.store('value', opt.get('value')).inject(this.selectOptions);				
	},
	show: function(e){		
		var thisOption = ($type(e) == 'event' ? ($(e.target).get('tag') != 'li' ? $(e.target).getParent('li') : $(e.target)) : e) || this.selected;		
		if(this.selectOptions.getStyle('visibility') == 'visible'){
			this.hide(thisOption);
		}
		else{	
			if(this.focused)
				this.focused.removeClass(this.options.optionSelected);	
			this.focused = this.selected = thisOption;
			this.focused.addClass(this.options.optionSelected);
			
			this.selectOptions.fx.set({
				'top': this.selectText.getCoordinates().top + this.selectText.getCoordinates().height,
				'left': this.selectText.getCoordinates().left,
				'height': 0			
			});			

			if(this.heightShow > this.optionHeight){
				this.heightShow =  this.optionHeight
			}
			this.selectOptions.fx.set({
				'height': this.heightShow,
				'opacity': 1
			});		
			this.scroll();	
			this.selectText.focus();			
			this.fireEvent('show', thisOption);
			this.showing = true;			
		}
	},
	hide: function(e){
		var thisOption = ($type(e) == 'event' ? ($(e.target).get('tag') != 'li' ? $(e.target).getParent('li') : $(e.target)) : e);		
		this.selectOptions.fx.set({
			'height': 0,
			'opacity': 0
		});			
		this.selectOptions.scrollTop = 0;		
		if (this.focused) {
			this.focused.removeClass(this.options.optionSelected);
		}
		this.showing = this.focused = false;
		this.fireEvent('hide', thisOption);		
	},
	over: function(e){		
		var thisOption = ($(e.target).get('tag') != 'li' ? $(e.target).getParent('li') : $(e.target));
		if(this.focused)
			this.focused.removeClass(this.options.optionSelected);		
		this.focused = thisOption;
		this.focused.addClass(this.options.optionSelected);		
		this.fireEvent('over', thisOption);
	},	
	select: function(e, keep){	
		var thisOption = ($type(e) == 'event' ? ($(e.target).get('tag') != 'li' ? $(e.target).getParent('li') : $(e.target)) : e);		
		if(this.focused)
			this.focused.removeClass(this.options.optionSelected);
		if (this.showing) {
			this.selected = this.focused = thisOption;			
			this.focused.addClass(this.options.optionSelected);			
			this.scroll();
		} else {
			this.selected = thisOption;
		}
		this.selectText.set('rel', this.selected.retrieve('value'));
		this.selectText.set('value', this.selected.get('text'));					
		this.fireEvent('select', [thisOption, this.selector, this.selected.retrieve('value')]);
		
		if(keep){
			if(!this.showing){
				this.show(thisOption);
			}
		}
		else{
			this.hide(thisOption);
		}
	},
	scroll: function(){	
		var soCoord = this.selectOptions.getCoordinates();		
		var sCoord = this.selected.getCoordinates();
		var soScrollTop = this.selectOptions.scrollTop;
		var soScrollTopValue = soScrollTop;
		if ((soScrollTop + soCoord.height) < (sCoord.top - soCoord.top + 5)) {
			soScrollTopValue = (sCoord.top - soCoord.top - soCoord.height + sCoord.height);
		}
		else if ((sCoord.top - soCoord.top + sCoord.height) < (soScrollTop + 5)) {
			soScrollTopValue = Math.max(0, sCoord.top - soCoord.top - 2);
		}
		this.selectOptions.scrollTop = soScrollTopValue;		
	}	
});
