// ***************************************************************************************************
// * Combo - a combo box control
// ***************************************************************************************************

function Combo(selectField, hiddenField, otherText) {
	this.KEYCODE_SHIFT = 16;
	this.KEYCODE_CTRL = 17;
	this.KEYCODE_ALT = 18;
	this.KEYCODE_ESC = 27;
	
	this.selectField = selectField;
	
	// add "Other..." option
	this.otherOpt = document.createElement("option");
	this.otherOpt.appendChild(document.createTextNode(otherText));
	this.selectField.appendChild(this.otherOpt);
	
	this.selectField.combo = this;
	this.selectField.onchange = Combo_selectField_onchange;
		
	this.inputField = document.createElement("input");
	this.inputField.type = "text";
	this.inputField.className = "text";
	this.inputField.style.display = "none";
	this.inputField.combo = this;
	this.inputField.onkeyup = Combo_inputField_onkeyup;
	this.selectField.parentNode.insertBefore(this.inputField, this.selectField);
	
	this.hiddenField = hiddenField;
	
	this.selectVisible = true;
	
	// add activeElement property for Mozilla
	if(!document.activeElement) {
		document.addEventListener("focus", Combo_document_onfocus, false);
	}
}

Combo.prototype.setValue = function(value) {
	var foundInList = false;
	for(var i = 0; i < this.selectField.options.length; i++) {
		if(this.selectField.options[i].value == value) {
			this.setSelectVisible(true);
			this.selectField.selectedIndex = i;
			foundInList = true;
			break;
		}
	}
	
	if(!foundInList) {
		this.setSelectVisible(false);
		this.inputField.value = value;
		this.inputField.defaultValue = value; // for isFormDirty function
	}
	
	this.hiddenField.value = value;
}

Combo.prototype.selectList_onchange = function(e) {
	e = EventManager.fix(e);
	if(this.selectField.options[this.selectField.selectedIndex] == this.otherOpt) {
		this.setSelectVisible(false);
	} else {
		this.hiddenField.value = this.selectField.value;
	}
}

Combo.prototype.inputField_onkeyup = function(e) {
	e = EventManager.fix(e);
	
	switch(e.keyCode) {
		case this.KEYCODE_SHIFT:
		case this.KEYCODE_CTRL:
		case this.KEYCODE_ALT:
			return;
	}
	
	if(e.keyCode == this.KEYCODE_ESC || this.inputField.value.length == 0) {
		this.setSelectVisible(true);
	} else {	
		this.hiddenField.value = this.inputField.value;
	}
}

Combo.prototype.setSelectVisible = function(isVisible) {
	var doFocus = false;
	if(document.activeElement == this.selectField || document.activeElement == this.inputField) {
		doFocus = true;
	}
	
	this.selectField.style.display = isVisible ? "block" : "none";
	this.inputField.style.display = isVisible ? "none" : "block";
	this.selectVisible = isVisible;
	
	if(isVisible) {
		this.selectField.selectedIndex = 0;
		this.hiddenField.value = this.selectField.options[0].value;
		if(doFocus) this.selectField.focus();
	} else {
		if(doFocus) this.inputField.focus();
	}
}

Combo.prototype.toString = function() {
	return "[object Combo]";
}

// Event handlers
function Combo_inputField_onkeyup(e) {
	var combo = this.combo;
	combo.inputField_onkeyup(e);
}

function Combo_selectField_onchange(e) {
	var combo = this.combo;
	combo.selectList_onchange(e);
}

function Combo_document_onfocus(e) {
	if(typeof EventManager == 'undefined') {
		// Too quick for events.js to load? In any case just ignore
		return; 
	}
	e = EventManager.fix(e);
	
	document.activeElement = e.target;
}
