
function gettpDropDownById(id)
{
	return new tpDropDown(id);	
}

function tpDropDown(Id, items)
{
	/*detect object if it already exist*/
	var element = document.getElementById(Id);
	if (element == null) return null;
	if(element.obj != null)
		return element.obj;
	// TO DO: Viacheslav Kopichev (Memory leak problem)	
	dom_setProperty(element, "obj", this);
	
	
	/*********** PRIVATE VARIABLES**********/
	var ImgUp =		cmn_GetImageUrl("ImgUp.gif");
	var ImgDown =	cmn_GetImageUrl("ImgDown.gif");
	var ImgOver =	cmn_GetImageUrl("ImgOver.gif");
	var events = new cmn_EventContainer();	
	
	var thisObj = this;	
	var inputElement = element.getElementsByTagName('input')[0];
	var buttonElement = element.getElementsByTagName('img')[0];
	var listElement = (element.children.length>1)?element.children[1]:null;
	var hiddenElement = document.createElement('input');
	hiddenElement.id = hiddenElement.name = "h_"+Id;
	hiddenElement.type = 'hidden';
	element.appendChild(hiddenElement);
	hiddenElement.value = inputElement.getAttribute("hiddenValue");
	
	/********** PUBLIC VARIABLES ***********/
	this.ReadOnly = inputElement.readOnly;
	this.DropDownEnable = listElement!=null;
	this.SelectionColor = (element.SelectionColor==null)?"DarkBlue":element.SelectionColor;
	this.TextSelectionColor = (element.TextSelectionColor==null)?"#FFFFFF":element.TextSelectionColor;
	this.TextColor = (element.TextColor==null)?"#000000":element.TextColor;	
	this.BorderCss = null;
	var onSelectedAttr = element.getAttribute("onselected");
	if(onSelectedAttr!=null)
		events.attachEvent("onselected", new Function("dropDown", "if(typeof(eval(\""+onSelectedAttr+"\"))=='function') eval(\""+onSelectedAttr+"(dropDown)\")"));
	tpdd_initialize(items);
	
	
	/**************** PUBLIC FUNCTIONS ***************/
	
	/// dropdownObject.GetValue()
	/// Return value of selected item 
	this.GetValue = function()
	{
		return hiddenElement.value;
	};

	/// dropdownObject.GetDisplayValue()
	/// Return display value of selected item 
	this.GetDisplayValue = function()
	{
		return inputElement.value;
	};
	
	this.GetListElement = function()
	{
		return listElement;
	};
	// dropdownObject.SetValue(obj)
	// Set obj item as selected
	this.SetValue = function(obj,fireevent)
	{
		try
		{
			if (typeof(obj) == "object" && obj.tagName.toLowerCase() == "div")		
			{				
				listElement.style.visibility = 'hidden';
				//[AL] Safari & Chrome support				
				return this.SelectItem(obj.innerText ? obj.innerText : obj.textContent, obj.value, fireevent)				
			}
			else
			{
				var val = str_Trim(obj.toString());
				if (this.DropDownEnable)
				{
					var rows = listElement.children;					
					for(var i=0; i<rows.length; i++)
					{
						//[AL] Chrome & Safari support
						var text = rows[i].innerText ? rows[i].innerText : rows[i].textContent;
						if(rows[i].value == val || text == val)
							return this.SelectItem(text, rows[i].value, fireevent);
					}
				}

				if(!this.ReadOnly)
					return this.SelectItem(val, val, fireevent);
			}
		}
		catch(e)
		{
		}

		return false;
	};
	
	this.SelectItem = function(text, value,fireevent)
	{
		try
		{	
			var oldvalue = hiddenElement.value;
			inputElement.value = text;
			hiddenElement.value = value;
			if (fireevent != false)
				events.fireEvent("onselected", thisObj, oldvalue);
			return true;
		}
		catch(e){}
		return false;
	}
	
	// dropdownObject.Select(idx)
	// Set item by idx index as selected
	this.Select = function(idx, fireevent)
	{				
		if (listElement!=null && listElement.children.length>idx)
			return this.SelectItem(listElement.children[idx].innerText, listElement.children[idx].value ,fireevent);
		return false;
	}
	
	/// dropdownObject.AddValue(name, value)
	/// Add new item to dropdown items collection
	///  name - display value of new item
	///  value - value of new item
	this.AddValue=function(name, value)
	{
		if(value==null)
			value = name;
		var newRow = document.createElement('div');
		listElement.appendChild(newRow);
		newRow.innerText = name;
		newRow.title=name;
		newRow.value = value;
		newRow.noWrap = true;
		newRow.className = "ddItm";
		newRow.style.width = "100%";
		thisObj.DropDownEnable=true;		
		return newRow;
	}	
	
	this.Clear = function()
	{
		listElement.innerHTML = inputElement.value = hiddenElement.value = "";		
	}
	
	/// dropdownObject.attachEvent(sEvent, func)
	/// Binds the specified function to an event
	/// sEvent	- string that specifies event. 
	/// func	- pointer that specifies the function to call when sEvent fires 
	this.attachEvent=function(sEvent, func)
	{
		events.attachEvent(sEvent, func);
	}	
	
	/// dropdownObject.Enable(isEnable)
	/// Set dropdown as enabled or disabled	
	this.Enable = function(isEnable)
	{
		if(inputElement.disabled == !isEnable)
			return;
		
		inputElement.disabled = !isEnable;
		var func = dom_attachEventForObject;
		if(!isEnable)
			func = dom_detachEventForObject;
				
		func(buttonElement, "mousedown", tpdd_buttonMouseDown);
		func(buttonElement, "mouseup", tpdd_buttonMouseUp);
		func(buttonElement, "mouseover", tpdd_buttonMouseOver);
		func(buttonElement, "mouseout", tpdd_buttonMouseOut);

		if(thisObj.ReadOnly)
		{
			// TO DO: Viacheslav Kopichev (Memory leak problem)	
			func(inputElement, "mousedown", tpdd_buttonMouseDown);
			func(inputElement, "mouseup", tpdd_buttonMouseUp);
			func(inputElement, "mouseover", tpdd_buttonMouseOver);
			func(inputElement, "mouseout", tpdd_buttonMouseOut);
		}
		
	}	
			
	/*********** PRIVATE FUNCTIONS **********/
	
	function tpdd_initialize()
	{
		// TO DO: Viacheslav Kopichev (Memory leak problem)
		if(!inputElement.readOnly)
			dom_attachEventForObject(inputElement, "change", tpdd_inputChange);
		if(listElement!=null)
			listElement.style.height = listElement.style.width = "0%";			
		if (thisObj.DropDownEnable)
		{		
			if(!buttonElement || !listElement)
			{
				thisObj.DropDownEnable = false;
				return;
			}
			// TO DO: Viacheslav Kopichev (Memory leak problem)	
			dom_attachEventForObject(buttonElement, "mousedown", tpdd_buttonMouseDown);
			dom_attachEventForObject(buttonElement, "mouseup", tpdd_buttonMouseUp);
			dom_attachEventForObject(buttonElement, "mouseover", tpdd_buttonMouseOver);
			dom_attachEventForObject(buttonElement, "mouseout", tpdd_buttonMouseOut);
			dom_attachEventForObject(listElement, "mouseover", tpdd_listMouseOver);
			dom_attachEventForObject(listElement, "mouseout", tpdd_listMouseOut);
			dom_attachEventForObject(listElement, "blur", tpdd_listBlur);
			dom_attachEventForObject(listElement, "focus", tpdd_listFocus);
			dom_attachEventForObject(listElement, "click", tpdd_listClick);
			
			if(thisObj.ReadOnly)
			{
				// TO DO: Viacheslav Kopichev (Memory leak problem)	
				dom_attachEventForObject(inputElement, "mousedown", tpdd_buttonMouseDown);
				dom_attachEventForObject(inputElement, "mouseup", tpdd_buttonMouseUp);
				dom_attachEventForObject(inputElement, "mouseover", tpdd_buttonMouseOver);
				dom_attachEventForObject(inputElement, "mouseout", tpdd_buttonMouseOut);
			}	
		
			var rows = listElement.children;
			for(var i=0; i<rows.length; i++)
				rows[i].title = rows[i].innerText;
		}
	}
	
	function tpdd_ShowList(isShow)
	{	
		if(isShow==true)
		{
			var maxHeight = listElement.getAttribute("maxHeight");
			if(maxHeight!=null && listElement.scrollHeight>maxHeight)
				listElement.style.height = maxHeight;			
			else
				listElement.style.height = "";				
			listElement.style.width = listElement.previousSibling.offsetWidth;
		}else
			listElement.style.height = listElement.style.width = "0%";
		listElement.style.visibility = (isShow==true)?'inherit':'hidden';
		events.fireEvent(isShow==true?"onlistopen":"onlistclose", thisObj);
	}
	
	function tpdd_inputChange()
	{
		thisObj.SelectItem(inputElement.value, inputElement.value, true);		
	}

	function tpdd_buttonMouseDown()
	{
		buttonElement.src = ImgDown;
		tpdd_ShowList(listElement.style.width == '0%');
		if(listElement.style.visibility!='hidden')
		{
            //[AL] Safari & Chrome support
			listElement.isFocused = true;
			listElement.focus();
		}
	}
	function tpdd_buttonMouseUp()
	{
		buttonElement.src = ImgUp;
	}
	function tpdd_buttonMouseOver(obj)
	{
		buttonElement.src = ImgOver;
	}
	function tpdd_buttonMouseOut()
	{
		buttonElement.src = ImgUp;
	}
	function tpdd_listFocus()
	{
		listElement.isFocused = true;
	}
	function tpdd_listBlur()
	{
		if(listElement.isFocused==true)
		{
			listElement.isFocused = false;
			if (listElement.isMouseOver != true)
				tpdd_ShowList(false);
			}
		}
	function tpdd_listMouseOver()
	{
		if(event.srcElement!=listElement)
		{
			listElement.isMouseOver = true;
			if (thisObj.BorderCss)
				new dom_DOMObject(event.srcElement).applyClass(thisObj.BorderCss);
			else
			{
				event.srcElement.style.backgroundColor = thisObj.SelectionColor;	
				event.srcElement.style.color=thisObj.TextSelectionColor;
			}
		}
	}
	function tpdd_listMouseOut()
	{
		if(event.srcElement!=listElement)
		{		
			listElement.isMouseOver = false;
			if (listElement.isFocused != true)
				tpdd_ShowList(false);
			if (thisObj.BorderCss)
				new dom_DOMObject(event.srcElement).removeClass(thisObj.BorderCss);				
			else
			{
				event.srcElement.style.backgroundColor = '#FFFFFF';	
				event.srcElement.style.color=thisObj.TextColor; 
			}
		}	
	}

	function tpdd_listClick()
	{
		if(event.srcElement!=listElement)
		{
			tpdd_listMouseOut();
			thisObj.SetValue(event.srcElement);
		}
		//[AL] Support Chrone & Safari
		//listElement.blur();
		tpdd_listBlur();
	}	
	/*********** END PRIVATE FUNCTIONS **********/
	
	if(items!=null)
		for(var i=0; i<items.length-1; i+=2)
			this.AddValue(items[i], items[i+1]);	
}


function tpldd_fillfromCache(ddId, cache, undefinedValue, selectedValue, textField, valueField)
{
	var dd = gettpDropDownById(ddId);
	if(undefinedValue!=null)
		dd.AddValue(undefinedValue,"");
	if(dd==null || cache==null)
		return;
	for(var i=0; i<cache.length; i++)
	{
		if(typeof(cache[i])=='object')
			dd.AddValue(cache[i][textField], cache[i][valueField]);
		else
			dd.AddValue(cache[i], cache[i]);
	}
	
	if(selectedValue!=null)
		dd.SetValue(selectedValue);
	else
		if(cache.length>0)
			dd.Select(0);
}
