var ComboboxManager = {
	list : [],

	add : function(index, combobox, select, size, fit, width) {
		this.list[index] = new Combobox(index, combobox, select, size, fit, width);
		return this.list[index];
	}, 

	get : function(index) {
		return this.list[index];
	}, 

	hideOptionListOther : function(index) {
		for(var i=0; i<this.list.length; i++) {
			if(!this.list[i]) continue;
			if(index!=this.list[i].index) {
				this.list[i].isActive = false;
				this.list[i].optionList.style.visibility = 'hidden';
				this.list[i].setBlur();
			}
		}
	}, 

	hideOptionListAll : function() {
		for(var i=0; i<this.list.length; i++) {
			if(!this.list[i]) continue;
			if(this.list[i].isActive) {
				this.list[i].isActive = false;
			}else {
				try { 
					this.list[i].optionList.style.visibility = 'hidden'; 
					this.list[i].setBlur();
				} catch (ex) {}
			}
		}
	}, 
	
	mousedown : function(event) {
		this.hideOptionListAll();
		return true;
	}
}

GlobalEvent.addEvent('mousedown', 'combobox', ComboboxManager.mousedown.bindAsEventListener(ComboboxManager));

var ComboboxOption = Class.create();
ComboboxOption.prototype = {
	value : '', 
	text : '', 
	selected : false, 
	layer : null, 
	initialize : function(value, text, selected, layer) {
		this.value = value;
		this.text = text;
		this.selected = selected;
		this.layer = layer;
	}
}

var Combobox = Class.create();
Combobox.prototype = {
	index : 0, 
	id : '', 
	size : 10, 
	fit : false, 
	width : 0, 
	selectedIndex : 0, 
	value : null, 
	options : null, 
	isActive : false, 
	hoverBackColor : '#fd6', 
	hoverColor : '#000', 
	focusColor : '#fd6', 
	toprow : 0, 
	lastIndex : 0, 
	buttonWidth : 0, 
	buttonHeight : 0, 

	combobox : null, 
	select : null, 
	input : null, 
	wrap : null, 
	display : null, 
	button : null, 
	optionList : null, 

	initialize : function(index, combobox, select, size, fit, width) {
		this.index = index;
		this.combobox = $(combobox);
		this.select = $(select);
		this.id = this.combobox.id;
		if(size) this.size = parseInt(size);
		if(fit) this.fit = fit;
		if(width) this.width = parseInt(width);
		this.options = [];
		this.select.setAttribute('index', index);

		this.init();
	}, 

	init : function() {
		if(this.select.offsetWidth==0 && this.select.offsetHeight==0) {
			setTimeout(this.init.bind(this), 10);
			return;
		}

		if(!this.width) this.width = this.select.offsetWidth + 2;
		if(!this.height) this.height = this.select.offsetHeight + 2;

		this.buttonWidth = this.height - 2;
		this.buttonHeight = this.height - 2;

		this.input = $(this.id+'_focus');
		this.display = $(this.id+'_display');
		this.button = $(this.id+'_button');
		this.optionList = $(this.id+'_optionwrap');

		for(var i=0, count=0; i<this.optionList.childNodes.length; i++) {
			var option = this.optionList.childNodes[i];
			if(!option || option.tagName!='DIV') continue;
			var value = option.getAttribute('value');
			var selected = option.getAttribute('selected');
			if(selected=="selected") {
				selected = true;
				this.selectedIndex = count;
			}else {
				selected = false;
			}
			var text = option.innerHTML;
			if(this.select.style.fontSize) option.style.fontSize = this.select.style.fontSize;
			else option.style.fontSize = '10pt';
			option.style.cursor = 'pointer';
			this.options[this.options.length] = new ComboboxOption(value, text, selected, option);
			count++;
		}

		$(this.select).setStyle({
			position : 'absolute', 
			left : 0, 
			top : 0, 
			width : 0, 
			height : 0
		});

		$(this.combobox).setStyle({
			display : 'inline', 
			zIndex : this.index, 
			width : this.width + 'px', 
			visibility : 'visible'
		});
		var buttonCells = this.combobox.getElementsByTagName('td');
		$(buttonCells[1]).setStyle({
			width : this.buttonWidth + 'px'
		});

		$(this.display).setStyle({
			overflow : 'hidden', 
			zIndex : this.index, 
			border : '2px solid #fff', 
			cursor : 'pointer'
		});
		if(this.select.style.fontSize) this.display.style.fontSize = this.select.style.fontSize;
		else this.display.style.fontSize = '10pt';

		$(this.button).setStyle({
			zIndex : this.index, 
			cursor : 'pointer'
		});

		$(this.optionList).setStyle({
			position : 'absolute', 
			left : 0, 
			top : 0, 
			overflowY : 'auto', 
			visibility : 'hidden', 
			zIndex : 1000
		});
		if(!this.fit) this.optionList.style.width = this.width + 'px';
	}, 
	
	sync : function() {
		this.options[this.selectedIndex].layer.style.backgroundColor = '#fff';
		this.options[this.selectedIndex].layer.style.color = '#000';
		if(this.select.selectedIndex < 0) return;
		this.selectedIndex = this.select.selectedIndex;
		this.display.innerHTML = this.options[this.selectedIndex].text;
		this.value = this.options[this.selectedIndex].value;
	}, 
	
	setFocus : function() {
		ComboboxManager.hideOptionListOther(this.index);
		this.display.style.border = '2px solid '+this.focusColor;
	}, 

	setBlur : function() {
		this.display.style.border = '2px solid #fff';
	}, 
	
	relocation : function() {
		try {
			this.options = [];
			this.options.length = 0;
		}catch(e) {}

		for(var i=this.optionList.childNodes.length-1; i>=0; i--) {
			this.optionList.removeChild(this.optionList.childNodes[i]);
		}

		var option;
		var height;
		var selectedIndex = this.select.selectedIndex;
		for(var i=0; i<this.select.options.length; i++) {
			option = this.select.options[i];
			height = option.getAttribute('height');
			this.addOption(option.value, option.text, selectedIndex==i);
		}
	}, 
	
	addOption : function(value, text, selected) {
		var index = this.options.length;

		var option = document.createElement('div');
		option.setAttribute('value', value);
		option.setAttribute('selected', (selected)?'selected':'');
		option.className = 'gc_combobox_option';
		option.innerHTML = text;
		this.optionList.appendChild(option);
		
		$(option).observe('mouseup', function() {
			this.selectOption(index);
		}.bind(this));
		$(option).observe('mouseover', function() {
			this.hoverOption(index);
		}.bind(this));

		if(this.select.style.fontSize) option.style.fontSize = this.select.style.fontSize;
		else option.style.fontSize = '10pt';
		option.style.cursor = 'pointer';

		this.options.push(new ComboboxOption(value, text, selected, option));

		if(index==0 || selected) {
			this.setDisplay(this.options[index].text);
			this.value = this.options[index].value;
			this.selectedIndex = index;
			this.lastIndex = this.selectedIndex;
		}
	}, 
	
	setDisplay : function(html) {
		this.display.innerHTML = html;
	}, 
	
	setSelectedIndex : function(index) {
		this.options[this.selectedIndex].layer.style.backgroundColor = '#fff';
		this.options[this.selectedIndex].layer.style.color = '#000';
		this.display.innerHTML = this.options[index].text;
		this.value = this.options[index].value;
		this.selectedIndex = index;
		this.select.selectedIndex = index;
		if(this.select.onchange) this.select.onchange();
	}, 

	hoverOption : function(index) {
		this.options[this.selectedIndex].layer.style.backgroundColor = '#fff';
		this.options[this.selectedIndex].layer.style.color = '#000';
		this.options[this.lastIndex].layer.style.backgroundColor = '#fff';
		this.options[this.lastIndex].layer.style.color = '#000';
		this.options[index].layer.style.backgroundColor = this.hoverBackColor;
		this.options[index].layer.style.color = this.hoverColor;

		this.lastIndex = index;
	}, 

	selectOption : function(index) {
		this.isActive = false;
		this.toggleOptionList();
		this.input.focus();
		this.setSelectedIndex(index);

		try {
			event.cancelBubble = true;
			event.returnValue = false;
		}catch(e) {}
	}, 

	setActive : function() {
		this.isActive = true;
	}, 
	
	viewOptionList : function() {
		if(this.options.length > 1 && !this.options[this.options.length-1].layer.offsetTop) {
			setTimeout(this.viewOptionList.bind(this), 10);
			return;
		}
		var position = Position.positionedOffset(this.combobox);
		var left = position[0];
		var top = position[1];
		this.optionList.style.top = top + Element.getHeight(this.combobox) + 'px';
		this.optionList.style.left = left + 'px';
		
		var totalHeight = 2;
		for(var i=0; i<this.options.length; i++) {
			if(i < this.size) {
				totalHeight += Element.getHeight(this.options[i].layer);
			}
		}
		if(this.fit) {
			var width;
			if(this.size < this.options.length) {
				width = this.optionList.scrollWidth + 25 + 2;
			}else {
				width = this.optionList.scrollWidth + 2;
			}
			if(width < this.width) width = this.width;
			this.optionList.style.width = width + 'px';
		}
		this.optionList.style.height = totalHeight + 'px';

		this.options[this.lastIndex].layer.style.backgroundColor = '#fff';
		this.options[this.lastIndex].layer.style.color = '#000';
		this.options[this.selectedIndex].layer.style.backgroundColor = this.hoverBackColor;
		this.options[this.selectedIndex].layer.style.color = this.hoverColor;
		this.optionList.scrollTop = this.options[this.selectedIndex].layer.offsetTop;
		this.toprow = this.selectedIndex - 1;
	}, 
	
	toggleOptionList : function() {
		if(this.optionList.style.visibility=='hidden') {
			this.isActive = true;
			this.optionList.style.visibility = 'visible';
			
			this.input.focus();

			if(this.size < this.options.length) {
				this.optionList.style.height = this.size * 20 + 'px';
			}
			if(this.fit) this.optionList.style.width = '20px';

			this.viewOptionList();
		}else {
			this.isActive = false;
			this.optionList.style.visibility = 'hidden';
			this.optionList.style.top = '-1000px';
			this.optionList.style.left = '-1000px';
		}
	}, 

	keydown : function(event) {
		if(event.keyCode==Keyboard.VK_ENTER) {
			Event.stop(event);
			this.toggleOptionList();
		}
		if(event.keyCode==Keyboard.VK_UP) {
			Event.stop(event);
			if(this.selectedIndex > 0) {
				if(this.optionList.style.visibility!='hidden') {
					var divObj1 = this.options[this.selectedIndex].layer;
					var divObj2 = this.options[this.selectedIndex-1].layer;
					divObj1.style.color = '#000';
					divObj1.style.backgroundColor = '#fff';
					divObj2.style.color = this.hoverColor;
					divObj2.style.backgroundColor = this.hoverBackColor;
					this.setSelectedIndex(this.selectedIndex-1);
					if(this.toprow==this.selectedIndex) {
						this.optionList.scrollTop = this.options[this.selectedIndex].layer.offsetTop;
						this.toprow--;
					}
				}else {
					var divObj1 = this.options[this.selectedIndex].layer;
					var divObj2 = this.options[this.selectedIndex-1].layer;
					divObj1.style.color = '#000';
					divObj1.style.backgroundColor = '#fff';
					divObj2.style.color = this.hoverColor;
					divObj2.style.backgroundColor = this.hoverBackColor;
					this.setSelectedIndex(this.selectedIndex-1);
					if(this.toprow==this.selectedIndex) {
						this.toprow--;
					}
				}
			}
		}
		if(event.keyCode==Keyboard.VK_DOWN) {
			Event.stop(event);
			if(this.selectedIndex < this.options.length - 1) {
				if(this.optionList.style.visibility!='hidden') {
					var divObj1 = this.options[this.selectedIndex].layer;
					var divObj2 = this.options[this.selectedIndex+1].layer;
					divObj1.style.color = '#000';
					divObj1.style.backgroundColor = '#fff';
					divObj2.style.color = this.hoverColor;
					divObj2.style.backgroundColor = this.hoverBackColor;
					this.setSelectedIndex(this.selectedIndex+1);
					if(this.toprow+this.size==this.selectedIndex) {
						if(this.options.length - 1 == this.selectedIndex) {
							this.optionList.scrollTop = this.optionList.scrollHeight;
						}else {
							this.optionList.scrollTop = this.options[this.selectedIndex].layer.offsetTop - this.options[this.size-1].layer.offsetTop;
						}
						this.toprow++;
					}
				}else {
					var divObj1 = this.options[this.selectedIndex].layer;
					var divObj2 = this.options[this.selectedIndex+1].layer;
					divObj1.style.color = '#000';
					divObj1.style.backgroundColor = '#fff';
					divObj2.style.color = this.hoverColor;
					divObj2.style.backgroundColor = this.hoverBackColor;
					this.setSelectedIndex(this.selectedIndex+1);
					if(this.toprow+this.size==this.selectedIndex) {
						this.toprow++;
					}
				}
			}
		}
	}
}
