﻿/**
 * DropDownList$BTD
 * 
 * @author     banhthidiem <banhthidiem@gmail.com>
 * @copyright  2008 Bach Khoa Computer Inc.
 * @version    1.5 2008/09/30
 */
 
 var EventNameDDL =
{
	/******* Event Name of DropDownList *******/
	click : "click",
	blur : "blur",
	focus : "focus",
	change : "change",
	
	/******* Event Name of Item DropDownList *******/
	itemClick : "itemClick",
	itemMouseOver : "itemMouseOver",
	itemMouseMove : "itemMouseMove",
	itemMouseOut : "itemMouseOut"
};

var ColummTypeDDL =
{
	label : "label",
	image : "image"
};
 
DropDownList$BTD = function(idParent, listData, myName, myStyle, isCbo)
{
	this.myName = myName;
	this.myStyle = typeof(myStyle) == "undefined" ? "" : myStyle;
	this.heightItem = 19;
	this.maxItem = 20;
	this.oContainerList = null;
	this.oContainer = null;
	this.oTableList = null;
	if (typeof(isCbo) == "undefined" || !isCbo) {
		this.oContainerParent = typeof (idParent) == "string" ? utilObj.getElById(idParent) : idParent;
		this.listData = listData;
	}
	else {
		var oCbo = typeof (idParent) == "string" ? utilObj.getElById(idParent) : idParent;
		this.oContainerParent = oCbo.parentNode;
		this.listData = null;
		this.createListFromCbo(oCbo);
		this.oContainerParent.removeChild(oCbo);
	}
	
	this.listEvent = new Array();
	this.itemSelected = null;
	this.oldValue = "";
	this.oldElRow = null;
	
	/*************** Properties ******************/
	this.isTextBoxReadOnly = false;
	this.enabledAutoCom = true;
	this.isMultiSelect = false;
	/*************** Properties ******************/
	
	if (this.oContainerParent != null) this.createMain();
	var self = this;
	this.alreadyKeyDown = false;
	
	this.whenKeyDown = function(e)
	{
		self.documentKeyDownDDL(e);
	};
};

DropDownList$BTD.prototype.checkDataHasImage = function()
{
	var isHasImage = false;
	var maxHeight = 0;
	var listCols = this.listData.mapField.display;
	for (var i = 0; i < listCols.length; i++)
	{
		if (listCols[i].type == ColummTypeDDL.image)
		{
			isHasImage = true;
			if (maxHeight < listCols[i].height)
			{
				maxHeight = listCols[i].height;
			}
		}
	}
	var delta = ((utilObj.isIE || utilObj.isOpera) ? 5 : 7);
	if (isHasImage && maxHeight > this.heightItem - delta)
	{
		this.heightItem = maxHeight + delta;
	}
};

/*****************************************************************************
					Create element in DropDownList Start
*****************************************************************************/

DropDownList$BTD.prototype.createMain = function()
{
	try
	{
		this.checkDataHasImage();
		this.createContainer();
		var self = this;
		utilObj.addEvent(document, "mousedown", function(e) { self.documentMouseDownDDL(e); });
		utilObj.addEvent(window, "resize", function(e) { self.hideList(e); });
		utilObj.addEvent(document, "scroll", function(e) { self.hideList(e); });
	}
	catch (e)
	{ }
};

DropDownList$BTD.prototype.setWidth = function(w) {
	w += "";
	w = (w.indexOf("%", 0) == -1) ? ((w.indexOf("px", 0) == -1) ? w + "px" : w) : w;
	this.oContainer.style.width = w;
};

DropDownList$BTD.prototype.checkParentHaxFixed = function() {
	var parent = this.oContainerParent;
	while (parent != null && parent.tagName != null && parent.tagName.toLowerCase() != "body") {
		var propertyPos = utilObj.getStyleEl(parent, "position");
		if (propertyPos == "fixed") {
			return true;
		}
		parent = parent.parentNode;
	}
	return false;
};

DropDownList$BTD.prototype.createContainer = function()
{
	this.oContainer = utilObj.createEl("DIV");
	this.oContainer.id = "containerDDL_" + this.myName;
	this.oContainer.className = "containerDDL" + this.myStyle;
	this.oContainerParent.appendChild(this.oContainer);
	this.createTextBox();
	this.createButton();
	this.createContainerList();
};

DropDownList$BTD.prototype.createTextBox = function()
{
	var o = utilObj.createEl("INPUT");
	o.id = "inputDDL_" + this.myName;
	o.className = "inputDDL";
	o.readOnly = this.isTextBoxReadOnly;
	o.nameDDL = this.myName;
	var self = this;
	o["onmouseover"] = function(e) { self.mouseOverDDL(e); };
	o["onmouseout"] = function(e) { self.mouseOutDDL(e); };
	o["onclick"] = function(e) { self.mouseClickDDL(e); };
	o["onkeydown"] = function(e) { self.textBoxKeyDownDDL(e); };
	o["onfocus"] = function(e) { self.mouseFocusDDL(e); };
	this.oTextBox = o;
	this.oContainer.appendChild(o);
};

DropDownList$BTD.prototype.createButton = function()
{
	var o = utilObj.createEl("DIV");
	o.id = "ImgButtonDDL_" + this.myName;
	o.className = "imgButtonDDL";
	o.nameDDL = this.myName;
	var self = this;
	o["onmouseover"] = function(e) { self.mouseOverDDL(e); };
	o["onmouseout"] = function(e) { self.mouseOutDDL(e); };
	o["onclick"] = function(e) { self.mouseClickDDL(e); };
	o["onfocus"] = function(e) { self.mouseFocusDDL(e); };
	this.oBtn = o;
	this.oContainer.appendChild(o);
};

DropDownList$BTD.prototype.createContainerList = function()
{
	this.oContainerList = utilObj.createEl("DIV");
	this.oContainerList.id = "DivListDDL_" + this.myName;
	this.oContainerList.className = "divListDDL";
	this.oContainerList.nameDDL = this.myName;
	this.oContainerList.style.display = "none";
	this.oContainerList.style.top = "-1000px";
	this.oContainerList.style.left = "-1000px";
	utilObj.addChildToBody(this.oContainerList);
	this.createList();
};

DropDownList$BTD.prototype.createList = function()
{
	this.oTableList = utilObj.createEl("TABLE");
	this.oTableList.id = "TableListDDL_" + this.myName;
	this.oTableList.className = "tableListDDL";
	this.oTableList.nameDDL = this.myName;
	this.oTableList.style.visibility  = "visible";
	this.oContainerList.appendChild(this.oTableList);
	this.createTBodyList();
};

DropDownList$BTD.prototype.createTBodyList = function()
{
	for (var i = 0; i < this.listData.data.length; i++)
	{
		this.insertRow(this.listData.data[i]);
	}
};

DropDownList$BTD.prototype.insertRow = function(item)
{
	var elRow = this.oTableList.insertRow(this.oTableList.rows.length);
	elRow.item = item;
	item.elRow = elRow;
	elRow.nameDDL = this.myName;
	elRow.className = "itemListDDL";
	for (var i = 0; i < this.listData.mapField.display.length; i++)
	{
		this.insertCell(elRow, this.listData.mapField.display[i]);
	}
	this.mapEventForRow(elRow);
};

DropDownList$BTD.prototype.insertCell = function(elRow, oCol)
{
	switch (oCol.type)
	{
		case ColummTypeDDL.label:
			this.createLabel(elRow, oCol);
			break;
		case ColummTypeDDL.image:
			this.createImage(elRow, oCol);
			break;
	}
};

DropDownList$BTD.prototype.createLabel = function(elRow, oCol)
{
	elCell = elRow.insertCell(elRow.cells.length);
	elCell.nameDDL = this.myName;
	elCell.element = utilObj.createEl("LABEL");
	elCell.element.nameDDL = this.myName;
	elCell.element.innerHTML = elRow.item[oCol.field];
	elCell.appendChild(elCell.element);
};

DropDownList$BTD.prototype.createImage = function(elRow, oCol)
{
	elCell = elRow.insertCell(elRow.cells.length);
	elCell.nameDDL = this.myName;
	elCell.element = utilObj.createEl("IMG");
	elCell.element.nameDDL = this.myName;
	elCell.element.src = elRow.item[oCol.field];
	elCell.element.height = oCol.height;
	elCell.element.width = oCol.width;
	elCell.appendChild(elCell.element);
};

/*****************************************************************************
					Create element in DropDownList End
*****************************************************************************/

/*****************************************************************************
					Create action when execute event Start
*****************************************************************************/

/*=================================Item Event=========================================*/
DropDownList$BTD.prototype.mouseOverItemDDL = function(elRow, e)
{
	if (this.oldElRow != null && this.oldElRow != elRow)
	{
		this.oldElRow.className = "itemListDDL";
	}
	elRow.className = "itemListDDL_over";
	this.oldElRow = elRow;
};

DropDownList$BTD.prototype.clickItemDDL = function(elRow, e)
{
	this.itemSelected = elRow.item;
	this.oldElRow = elRow;
	this.hideList();
	if (this.oTextBox.value != elRow.item[this.listData.mapField.text] || this.oTextBox.value != this.oldValue)
	{
		this.oldValue = this.oTextBox.value;
		this.oTextBox.value = elRow.item[this.listData.mapField.text];
		this.executeEvent(e, EventNameDDL.change);
	}
};
/*===================================Item Event=======================================*/

/*===================================Document Event=======================================*/
DropDownList$BTD.prototype.documentMouseDownDDL = function(e)
{
	var o = utilObj.getTargetElement();
	if (typeof(o.nameDDL) != "undefined" && o.nameDDL == this.myName)
	{
		return;
	}
	this.hideList();
};

DropDownList$BTD.prototype.documentKeyDownDDL = function(e)
{
	e = utilObj.getWindowEvent();
	switch (e.keyCode)
	{
		case 38:
			this.gotoItem(true);
			break;
		case 40:
			this.gotoItem(false);
			break;
		case 27:
			this.hideList();
			break;
		case 13: case 9:
			if (this.oldElRow != null && this.enabledAutoCom)
			{
				this.clickItemDDL(this.oldElRow, e);
			}
			else if (this.oTextBox.value != this.oldValue) // No Use AutoComplete
			{
				this.oldValue = this.oTextBox.value;
				this.hideList();
				this.executeEvent(e, EventNameDDL.change);
			}
			utilObj.stopEvent();
			break;
		default:
			var self = this;
			if (!this.isTextBoxReadOnly)
			{
				setTimeout( function() { self.toComplete(); }, 50);
			}
			break;
	}
	return false;
};
/*===================================Document Event=======================================*/

/*===================================Element Event=======================================*/
DropDownList$BTD.prototype.mouseFocusDDL = function(e)
{
	if (!this.alreadyKeyDown)
	{
		this.alreadyKeyDown = true;
		utilObj.addEvent(document, "keydown", this.whenKeyDown);
	}
	this.executeEvent(e, EventNameDDL.focus);
};

DropDownList$BTD.prototype.mouseOverDDL = function(e)
{
	this.oBtn.className = "imgButtonDDL_over";
};

DropDownList$BTD.prototype.mouseOutDDL = function(e)
{
	this.oBtn.className = "imgButtonDDL";
};

DropDownList$BTD.prototype.mouseClickDDL = function(e)
{
	this.showList(e);
	this.executeEvent(e, EventNameDDL.click);
};

DropDownList$BTD.prototype.textBoxKeyDownDDL = function(e)
{
	if (!this.alreadyKeyDown)
	{
		this.alreadyKeyDown = true;
		utilObj.addEvent(document, "keydown", this.whenKeyDown);
	}
	if (this.oContainerList.style.display == "none")
	{
		this.mouseClickDDL(e);
	}
};
/*===================================Element Event=======================================*/

/*****************************************************************************
					Create action when execute event End
*****************************************************************************/

/*****************************************************************************
								Event Start
*****************************************************************************/

DropDownList$BTD.prototype.mapEventForRow = function(elRow)
{
	var self = this;
	elRow["onclick"] = function(e)
	{
		self.clickItemDDL(elRow, e);
		e = utilObj.getWindowEvent();
		e.item = elRow.item;
		self.executeEvent(e, EventNameDDL.itemClick);
	};
	elRow["onmouseover"] = function(e)
	{
		self.mouseOverItemDDL(elRow, e);
		e = utilObj.getWindowEvent();
		e.item = elRow.item;
		self.executeEvent(e, EventNameDDL.itemMouseOver);
	};
	elRow["onmousemove"] = function(e) 
	{
		e = utilObj.getWindowEvent();
		e.item = elRow.item;
		self.executeEvent(e, EventNameDDL.itemMouseMove);
	};
	elRow["onmouseout"] = function(e) 
	{
		e = utilObj.getWindowEvent();
		e.item = elRow.item;
		self.executeEvent(e, EventNameDDL.itemMouseOut);
	};
};

DropDownList$BTD.prototype.addEvent = function(eventName, func)
{
	if(this.listEvent[eventName] == null)
	{
		this.listEvent[eventName] = [];
	}
	this.listEvent[eventName].push(func);
};

DropDownList$BTD.prototype.removeEvent = function(eventName, func)
{
	if(this.listEvent[eventName] == null)
	{
		return;
	}
	for (var i = 0; i < this.listEvent[eventName].length; i++)
	{
		if (func == this.listEvent[eventName][i])
		{
			this.listEvent[eventName].splice(i, 1);
			break;
		}
	}
};

DropDownList$BTD.prototype.executeEvent = function(e, eventName)
{
	if (this.listEvent[eventName] != null)
	{
		for (var i = 0; i < this.listEvent[eventName].length; i++)
		{
			this.listEvent[eventName][i](e);
		}
	}
};

/*****************************************************************************
								Event End
*****************************************************************************/

/*****************************************************************************
							Private Method Start
*****************************************************************************/

DropDownList$BTD.prototype.clearListItems = function()
{
	this.listData.data = [];
	while (this.oTableList.rows.length > 0)
	{
		this.oTableList.deleteRow(0);
	}
	this.oTextBox.value = "";
};

DropDownList$BTD.prototype.isExistItem = function(value)
{
	var list = this.listData.data;
	var isExist = false;
	for (var i = 0; i < list.length; i++)
	{
		if (list[i][this.listData.mapField.value] == value)
		{
			isExist = true;
			break;
		}
	}
	return isExist;
};

/*======================Create List From ComboBox===========================*/
DropDownList$BTD.prototype.createListFromCbo = function(oCbo) {
	this.listData = {
		mapField: {
			value: "value",
			text: "text",
			search: "text",
			display: [
				{ name: "text", field: "text", type: ColummTypeDDL.label }
			]
		},
		data: []
	};
	for (var i = 0; i < oCbo.length; i++) {
		this.listData.data.push({ value: oCbo[i].value, text: oCbo[i].text });
	}
};

DropDownList$BTD.prototype.enableIextBox = function()
{
	this.isTextBoxReadOnly = false;
	this.oTextBox.readOnly = this.isTextBoxReadOnly;
};

DropDownList$BTD.prototype.disableIextBox = function()
{
	this.isTextBoxReadOnly = true;
	this.oTextBox.readOnly = this.isTextBoxReadOnly;
};

DropDownList$BTD.prototype.toComplete = function()
{
	for (var i = 0; i < this.listData.data.length; i++)
	{
		var v = this.listData.data[i][this.listData.mapField.search].toUpperCase();
		var vSearch = this.oTextBox.value.toUpperCase();
		if (v.indexOf(vSearch, 0) == 0)
		{
			if (this.oldElRow != null)
			{
				this.oldElRow.className = "itemListDDL";
			}
			if (this.listData.data[i].elRow != null)
			{
				var curentPos = i * this.heightItem;
				this.oContainerList.scrollTop = curentPos;
				this.listData.data[i].elRow.className = "itemListDDL_over";
				this.oldElRow = this.listData.data[i].elRow;
				this.itemSelected = this.oldElRow.item;
			}
			break;
		}
	}
};

DropDownList$BTD.prototype.gotoItem = function(isUp)
{
	var rowIndex = 0;
	if (this.oldElRow != null)
	{
		rowIndex = this.oldElRow.rowIndex;
		if ((rowIndex == 0 && isUp) || (rowIndex == this.oTableList.rows.length - 1 && !isUp)) return;
		this.oldElRow.className = "itemListDDL";
		if (isUp)
		{
			rowIndex--;
			this.oldElRow = this.oldElRow.previousSibling;
		}
		else
		{
			this.oldElRow = this.oldElRow.nextSibling;
			rowIndex++;
		}
	}
	else
	{
		if (this.oTableList.rows.length > 0)
		{
			this.oldElRow = this.oTableList.rows[0];
			rowIndex = this.oldElRow.rowIndex;
		}
	}
	if (this.oldElRow != null)
	{
		var curentPos = rowIndex * this.heightItem;
		var startPos = this.oContainerList.scrollTop;
		var endPos = startPos + (this.maxItem * this.heightItem);
		if (startPos > curentPos || endPos <= curentPos)
		{
			var scrollDown = curentPos - (this.maxItem * this.heightItem) + this.heightItem;
			this.oContainerList.scrollTop = isUp ? curentPos : (scrollDown < 0 ? 0 : scrollDown);
		}
		
		this.itemSelected = this.oldElRow.item;
		this.oldElRow.className = "itemListDDL_over";
		this.oTextBox.value = this.oldElRow.item[this.listData.mapField.text];
		this.oTextBox.select();
	}
};

DropDownList$BTD.prototype.showList = function(e) {
	this.oContainerList.style.display = "";
	this.oTableList.style.width = "0px";
	var sizeTableList = utilObj.getElementSize(this.oTableList);
	var w = sizeTableList.width + 17 < 170 ? 170 : sizeTableList.width;
	var maxHeight = (this.maxItem * this.heightItem);

	if (sizeTableList.height > maxHeight) {
		this.oContainerList.style.overflowY = "scroll";
		this.oContainerList.style.height = maxHeight + "px";
		this.oTableList.style.width = (utilObj.isEE ? w - 17 : w) + "px";
		w = w + 17;
	}
	else {
		this.oContainerList.style.overflowY = "";
		this.oContainerList.style.height = sizeTableList.height + "px";
		this.oTableList.style.width = (w - 1 < 0 ? 0 : w - 1) + "px";
	}

	// Set width for container DDL
	this.oContainerList.style.width = w + "px";

	this.oContainerList.style.top = "0px";
	this.oContainerList.style.left = "0px";
	var posParent = utilObj.getElementPosition(this.oContainer);
	var sizeParent = utilObj.getElementSize(this.oContainer);
	var posChild = utilObj.getElementPosition(this.oContainerList);
	var sizeChild = utilObj.getElementSize(this.oContainerList);

	var deScroll = utilObj.getDocumentScroll();
	var topPos = (this.checkParentHaxFixed() ? deScroll.scrollTop : 0) + posParent.Y - posChild.Y;
	if ((posParent.Y - deScroll.scrollTop + sizeChild.height) > utilObj.getDocument().clientHeight) {
		topPos -= sizeChild.height;
	}
	else {
		topPos += sizeParent.height - 1;
	}
	this.oContainerList.style.top = topPos + "px";
	this.oContainerList.style.left = (posParent.X + (this.checkParentHaxFixed() ? deScroll.scrollLeft : 0)) + "px";
};

DropDownList$BTD.prototype.hideList = function()
{
	if (this.oContainerList == null) return;
	this.oContainerList.style.display = "none";
	this.oContainerList.style.top = "-1000px";
	this.oContainerList.style.left = "-1000px";
	if (this.alreadyKeyDown)
	{
		this.alreadyKeyDown = false;
		utilObj.removeEvent(document, "keydown", this.whenKeyDown);
	}
};

/*****************************************************************************
							Private Method End
*****************************************************************************/

/*****************************************************************************
							Public Method Start
*****************************************************************************/
DropDownList$BTD.prototype.dispose = function()
{
	this.oContainerParent.removeChild(this.oContainer);
	this.oContainerList = null;
	this.oContainer = null;
};

DropDownList$BTD.prototype.reset = function()
{
	this.oContainerList.scrollTop = 0;
	if (this.oldElRow != null)
	{
		this.oldElRow.className = "itemListDDL";
	}
	this.oldElRow = this.itemSelected = null;
	this.oTextBox.value = "";
};

DropDownList$BTD.prototype.loadListItems = function(list)
{
	this.clearListItems();
	this.listData.data = list;
	this.createTBodyList();
};

DropDownList$BTD.prototype.addItem = function(item)
{
	this.listData.data.push(item);
	this.insertRow(item);
};

DropDownList$BTD.prototype.removeItem = function(value)
{
	// Delete data array
	var list = this.listData.data;
	for (var i = 0; i < list.length; i++)
	{
		if (value == list[i][this.listData.mapField.value])
		{
			if (this.itemSelected != null && this.itemSelected.elRow == list[i].elRow)
			{
				this.reset();
			}
			this.oTableList.tBodies[0].removeChild(list[i].elRow);
			list.splice(i, 1);
			break;
		}
	}
};

DropDownList$BTD.prototype.getItemSelected = function()
{
	return this.itemSelected;
};

DropDownList$BTD.prototype.getValue = function()
{
	return this.itemSelected[this.listData.mapField.value];
};

DropDownList$BTD.prototype.getText = function()
{
	return this.enabledAutoCom ? this.itemSelected[this.listData.mapField.text] : this.oTextBox.value;
};

DropDownList$BTD.prototype.selectedValue = function(v)
{
	if (this.oTableList != null)
	{
		var elRows = this.oTableList.rows;
		for (var i = 0; i < elRows.length; i++)
		{
			if (elRows[i].item[this.listData.mapField.value] == v)
			{
				if (this.oldElRow != null)
				{
					this.oldElRow.className = "itemListDDL";
				}
				this.oldElRow = elRows[i];
				this.itemSelected = this.oldElRow.item;
				this.oTextBox.value = this.oldElRow.item[this.listData.mapField.text];
				this.oldElRow.className = "itemListDDL_over";
				break;
			}
		}
	}
};
/*****************************************************************************
							Public Method End
*****************************************************************************/