
 /**
 * Combobox
 * (C) ICSoft, http://www.icsoft.ru
 *
 * author Egor Stremousov
 * version 1.0
 */

 /** Global variables  **/
 var comboKeyPressHandled = false;
 var comboKeyDownHandled = false;
 var comboCurrentSelectedItem = -1

 /** Utils **/
 function getTag(id){   return document.getElementById(id); }


 /** HTML-Constructor **/
 function createComboBox(id, sForm, formElement, itemsTitle, itemsValue, otherValue, autoShow, autoSelect, useFilter, css, defaultValueIndex){
 var countTitle = itemsTitle.length;
 var countValue = itemsValue.length;
 if ((countTitle!=countValue)||(countTitle<2)){alert('Length of itemsTitle is not equal: '+countTitle); return false; }

 document.write("<div id='"+id+"' class='combo"+css+"' hideNow='1' sForm='"+sForm+"' formElement='"+formElement+"' lastValue='' otherValue='"+otherValue+"' autoShow='"+autoShow+"' autoSelect='"+autoSelect+"' count='"+countValue+"' useFilter='"+useFilter+"' oldValue='' css='"+css+"' defaultIndex='"+defaultValueIndex+"' lastRequestId=''>");
 document.write("   <div id='dp-"+id+"' class='combo-dp"+css+"'> 																			");
 document.write("		<div id='dp-img-"+id+"' class='no-drop"+css+"' onclick=\"return _onComboShowHide('"+id+"');\" ></div> 				");
 document.write("   </div>                                                                                      					");
 document.write("	<input id='input-"+id+"' class='combo-input"+css+"'                               						");
 document.write("			onchange    = \"return _onComboChange('"+id+"');\"                                    					");
 document.write("			onkeyup     = \"return _onComboKeyUp(this,'"+id+"', event, false);\"                   					");
 document.write("			onkeypress  = \"return _onComboKeyPress(this,'"+id+"', event, false);\"                					");
 document.write("			onkeydown   = \"return _onComboKeyDown(this,'"+id+"', event, true);\"                  					");
 document.write("			onfocus     = \"return _onComboFocus('"+id+"');\"                                 						");
 document.write("			onblur      = \"return _onComboBlur('"+id+"');\"                                     					");
 document.write("	value=''><br>                                                              			 	");
 document.write("	<div id='container-"+id+"' class='combo-hidden' onscroll=\"return _onComboScroll('"+id+"');\">                  ");

 for(var i=0; i<countTitle; i++){

 document.write("              	<div id='combo-element-"+id+"-"+i+"'                                                            	");
 document.write("						onclick=\"return _comboItemClick(this, '"+id+"');\"                          	    		");
 document.write("                       onmouseover=\"return _comboItemOver('"+id+"',"+i+");\"                               		");
 document.write("                       onmouseout=\"return _comboItemOut('"+id+"',"+i+");\"                                    	");
 document.write("			            class='element"+css+"'   			                                                      	");
 document.write("			            contentTitle='"+itemsTitle[i]+"'                                                      		");
 document.write("                       contentValue='"+itemsValue[i]+"'>"+itemsTitle[i]+"</div>                                	");

 }

 document.write("	</div>                                                                                              			");
 document.write("</div>                                                                                                 			");

 // set default
 comboSetDefaultValue(id);
 }

 /** Combobox properties
    Form        	- sended form is not null
	FormElement 	- value of attribute
	ListVisible 	- true|false
	OtherValue  	- true|false (possible add other value)
	AutoShow    	- true|false
	AutoSelect  	- true|false
	UseFilter		- true|false
	Img				- image with arrow "down"
	Input			- a-la object (input tag)
	Container   	- a-la object (tag "div", container)
	Count    		- count of items
	Item			- item from list of items
	LastValue   	- last sended Value
	HideNow			- hide list or not hide
	CSS				- CSS PostFix
	DefaultIndex 	- index of default item
	DefaultValue    - value of default item
	DefaultTitle    - title of default item

 **/
 function comboForm(id){
   return getTag( getTag(id).getAttribute("sForm") );
 }
 function comboFormElement(id){
   return getTag( getTag(id).getAttribute("formElement") );
 }
 function comboListVisible(id){
   if (getTag("container-"+id).className == "combo-container"+comboCSS(id)) { return true; } else { return false; }
 }
 function comboOtherValue(id){
   if (getTag(id).getAttribute("otherValue") == 1) { return true; } else { return false; }
 }
 function comboAutoShow(id){
   if (getTag(id).getAttribute("autoShow") == 1) { return true; } else { return false; }
 }
 function comboAutoSelect(id){
   if (getTag(id).getAttribute("autoSelect") == 1) { return true; } else { return false; }
 }
 function comboUseFilter(id){
 	if (getTag(id).getAttribute("useFilter") == 1){ return true; } else{ return false; 	}
 }
 function comboImg(id){   return getTag("dp-img-"+id); }
 function comboInput(id){ 	return getTag("input-"+id); }
 function comboContainer(id){
 	return getTag("container-"+id);
 }
 function comboCount(id){ 	return getTag(id).getAttribute("Count"); }
 function comboItem(id, Index){ 	var obj = getTag("combo-element-"+id+"-"+Index);
 	if (obj){ return obj; }else{ alert("Item("+Index+") from "+id+" not found."); } }
 function comboLastValue(id){
    return getTag(id).getAttribute("lastValue"); }
 function comboOldValue(id){
    return getTag(id).getAttribute("oldValue");
 }
 function comboHideNow(id){ 	if (getTag(id).getAttribute("hideNow") == 1){ return true; } else{ setHideNow(id,1); return false; 	} }
 function comboCSS(id){ 	return getTag(id).getAttribute("css"); }
 function comboDefaultIndex(id){    return getTag(id).getAttribute("defaultIndex"); }
 function comboDefaultValue(id){    return comboItem(id, comboDefaultIndex(id)).getAttribute("contentValue"); }
 function comboDefaultTitle(id){
    return comboItem(id, comboDefaultIndex(id)).getAttribute("contentTitle");
 }



 /** Combobox event (outer methods) **/

 // on change
 function _onComboChange(id){
   return true;
 }

 // on scroll
 function _onComboScroll(id){
   setHideNow(id,0);
   comboInput(id).focus();
   setTimeout("comboHideNow('"+id+"');",200);
   return true;
 }

 // on focus
 function _onComboFocus(id){
	if (comboInput(id).value==comboDefaultTitle(id)) {
  			comboInput(id).value="";
  			if ((comboAutoShow(id))&&(!(comboListVisible(id)))){ comboShowList(id); }
	}
	return false; }

 // on blur
 function _onComboBlur(id){
	if ( comboInput(id).value=="" ) { comboSetDefaultValue(id); }
	if ((!comboOtherValue(id))&&(comboFormElement(id))){		var V = comboFormElement(id).value;
		var Found = false;
		for(var i=0; i<comboCount(id); i++){			if (comboItem(id,i).getAttribute("contentValue") == V){				Found = true;
				comboInput(id).value = comboItem(id,i).getAttribute("contentTitle");
				break;			}		}
		if (!Found){ alert('Warning! Form has invalid values!'); }

	}
 	setTimeout("comboHideOrNot('"+id+"');",200);
 	return true;
 }

 // show or hide list
 function _onComboShowHide(id){   if (comboListVisible(id)){   		comboHideList(id);   }
   else{
   		setHideNow(id,0);
   		clearFilter(id);   	    comboShowList(id);
   	    setTimeout("comboHideNow('"+id+"');",200);   }
   return false; }

 //on key up
 function _onComboKeyUp(self, id, event, IsKeyDown){

   var r = false;

   if (!comboKeyPressHandled){ r = comboKeyPress(self, id, event, IsKeyDown); }
   comboKeyPressHandled = false;

   var keyIgnore = false;
   switch(event.keyCode)
   {
           case 13:
           case 38:
           case 40:
           case 27:
           case 9:
           case 16:
           case 17:
           case 18:
           case 33:
           case 34:
           case 35:
           case 36:
           case 45:
           case 37:
           case 39:
           keyIgnore = true;
           break;
   }

   if (!keyIgnore){

     if (comboOtherValue(id)){
        if (comboUseFilter(id)){ comboFilter(id); }

        if (comboFormElement(id)){ comboFormElement(id).value = self.value; }
     }else{
		if (comboUseFilter(id)){

			if(comboFilter(id)==0){              	if(self.value){              		self.value = comboOldValue(id);
              		comboFilter(id);
              	}			}
			else{				getTag(id).setAttribute("oldValue", self.value);			}

		}else{
        	self.value = comboLastValue(id);
        	comboShowList(id);
        }
     }
   }
   return r; }

 //on key down
 function _onComboKeyDown(self, id, event, IsKeyDown){ 	return comboKeyPress(self, id, event, IsKeyDown); }

 //on key press
 function _onComboKeyPress(self, id, event, IsKeyDown){
 	return comboKeyPress(self, id, event, IsKeyDown);
 }

 /** Combo inner methods  **/

 // filter
 function comboFilter(id){

   // set default
   for(var i=0; i<comboCount(id); i++){ comboItem(id,i).className = "element"+comboCSS(id); }
   var s = comboInput(id).value.toLowerCase();
   if (!s){ comboItemSelect(id, 0); return comboCount(id); }

   var sel = false;
   var visualCount = 0;
   for(var i=0; i<comboCount(id); i++){
	 var itemS = comboItem(id,i).getAttribute("contentTitle").toLowerCase();

	 if ((itemS.length >= s.length)&&(  itemS.substring(0,s.length) == s.substring(0,s.length)  )){

	 	visualCount++;

	 	if(!sel){
            comboItemSelect(id, i);
	 		sel = true;	 	}

     }	 else{
	 	comboItem(id,i).className = "combo-hidden";
	 }
   }


   // visibility
   if (visualCount == 0) {
   		if (comboOtherValue(id)) { comboHideList(id); }
   }else{   		if (!comboListVisible(id)) { comboShowList(id); }   }

   // return new count
   return visualCount;
 }
 // show
 function comboShowList(id){
   if (comboContainer(id)){
   		if (comboAutoSelect(id)){
   			comboItemSelect(id, 0);
   		}
   		else{   			comboItemSelect(id, -1);   		}

   		comboImg(id).className       = "drop"+comboCSS(id);     	comboContainer(id).className = "combo-container"+comboCSS(id);
     	comboInput(id).focus();   }
   else { alert("_comboShowList: Element 'container-"+id+"' not found."); } }
 // hide
 function comboHideList(id){
   if (comboContainer(id)){
     comboContainer(id).className = "combo-hidden";
     comboImg(id).className       = "no-drop"+comboCSS(id);
   }
   else { alert("_comboHideList: Element 'container-"+id+"' not found."); }
 }
 // send data to form element and set title to input
 function comboInsertContent(id, contentValue, contentTitle){
   comboInput(id).value = contentTitle;
   if (comboFormElement(id)){ comboFormElement(id).value = contentValue; }
   setLastValue(id, contentTitle); }
 // set data to attribute
 function setLastValue(id, value){ 	getTag(id).setAttribute("lastValue", value); }
 // set data to attribute
 function setHideNow(id, value){
 	getTag(id).setAttribute("hideNow", value);
 }
 // HideOrNot
 function comboHideOrNot(id){ 	if (comboHideNow(id)){  comboHideList(id); }
 	return false; }
 // select item
 function comboItemSelect(id, Index){    for(var i=0; i<comboCount(id); i++){
      if (i==Index){
      	comboItem(id, i).className = "element-selected"+comboCSS(id);
      }
      else{      	if (comboItem(id, i).className!="combo-hidden"){ comboItem(id, i).className = "element"+comboCSS(id); }
      }
    }
    comboCurrentSelectedItem = Index; }
 // keyPress
 function comboKeyPress(self, id, event, isKeyDown) {

   if (isKeyDown) {
           comboKeyDownHandled = true;
   } else {
           if (comboKeyDownHandled) {
                   comboKeyDownHandled = false;
                   if (event.keyCode != 13)
                           return true;
                   else {
                           return false;
                   }
           }
   }
   var keyIgnore = false;
   comboKeyPressHandled = true;

   switch(event.keyCode)
   {
           case 13:
           		   if ((!comboListVisible(id))&&(comboForm(id))) { 
                     //comboForm(id).submit();
                     if (lookupInput(id).onPressEnter)
                        lookupInput(id).onPressEnter(); 
                     return false; 
                  }

                   if (comboCurrentSelectedItem > -1) {
                        comboInsertContent(id, comboItem(id,comboCurrentSelectedItem).getAttribute("contentValue"), comboItem(id,comboCurrentSelectedItem).getAttribute("contentTitle"));
                   }

                   comboHideList(id);

                   return true;
           case 9:
           		   comboHideList(id);
           	       self.focus();
                   keyIgnore = true;
                   return true;
           case 27:
                   self.focus();
                   setTimeout("comboInput('"+id+"').focus();", 300 );
                   comboHideList(id);
                   return false;
           case 38:
           		   // up
           		   if (comboCount(id) == 0) { break; }

                   if(!comboUseFilter(id)) {
	                   	   comboCurrentSelectedItem -= 1;
	                   	   if (comboCurrentSelectedItem <= -1) { comboCurrentSelectedItem = (comboCount(id)-1); }
                   }
                   else{
                   		   comboCurrentSelectedItem -= 1;
                   		   if (comboCurrentSelectedItem <= -1) { comboCurrentSelectedItem = (comboCount(id)-1); }
		                   while( comboItem(id,comboCurrentSelectedItem).className=="combo-hidden" ){
		                   		comboCurrentSelectedItem -= 1;
		                   		if (comboCurrentSelectedItem <= -1) { comboCurrentSelectedItem = (comboCount(id)-1); }
		                   }
				   }

                   comboItemSelect(id, comboCurrentSelectedItem);
                   comboUpdateScrollUp(id, comboCurrentSelectedItem);

                   keyIgnore = true;
                   break;
           case 40:
                   // down
                   if (comboCount(id) == 0) { break; }

                   if (!comboListVisible(id)){ comboShowList(id); return false; }

                   if(!comboUseFilter(id)) {                   		comboCurrentSelectedItem += 1;
                   		if (comboCurrentSelectedItem > (comboCount(id)-1)){ comboCurrentSelectedItem = 0; }
                   }
                   else{
                        comboCurrentSelectedItem += 1;
                        if (comboCurrentSelectedItem > (comboCount(id)-1)){ comboCurrentSelectedItem = 0; }
	                    while( comboItem(id,comboCurrentSelectedItem).className=="combo-hidden" ){	                   		comboCurrentSelectedItem += 1;
	                   		if (comboCurrentSelectedItem > (comboCount(id)-1)){ comboCurrentSelectedItem = 0; }
	                    }

				   }

                   comboItemSelect(id, comboCurrentSelectedItem);
                   comboUpdateScrollDown(id, comboCurrentSelectedItem);

                   keyIgnore = true;
                   break;
   }

   if (keyIgnore) { return false; }
   return true;

 }
 // update scroll position up
 function comboUpdateScrollUp(id, comboCurrentSelectedItem){    comboContainer(id).scrollTop = comboItem(id, comboCurrentSelectedItem).offsetTop; }
 // update scroll position down
 function comboUpdateScrollDown(id, comboCurrentSelectedItem){
    comboContainer(id).scrollTop = comboItem(id, comboCurrentSelectedItem).offsetTop  + comboItem(id, comboCurrentSelectedItem).scrollHeight - comboContainer(id).clientHeight;
 }
 // set default value
 function comboSetDefaultValue(id){    comboInput(id).value = comboDefaultTitle(id);
 	if(comboFormElement(id)){ comboFormElement(id).value = comboDefaultValue(id); } }
 function clearFilter(id){    for(var i=0; i<comboCount(id); i++){ comboItem(id,i).className = "element"+comboCSS(id); } }

 /** Combobox Item Event **/

 // on click
 function _comboItemClick(self, id){
    comboInsertContent(id, self.getAttribute("contentValue"), self.getAttribute("contentTitle"));
    return false; }
 // on mouse over
 function _comboItemOver(id, Index){
    comboItemSelect(id, Index);
    return false;
 }
 // on mouse out
 function _comboItemOut(id, Index){
	comboItemSelect(id, Index);
	return false;
 }