var dropdowns = new Array() ;
var mobjThis = null ;

var foundElement;
function getObj(name)
{
	foundElement = null ;
  if (document.getElementById)
  {
  	foundElement = document.getElementById(name);
  }
  else if (document.all)
  {
	foundElement = document.all[name];
  }
  else if (document.layers)
  {
	getObjNN4(document.forms[0],name);
  }
  return foundElement ;
}
function getObjNN4(obj,name)
{
	if (document.forms[0].name == name)
	{
		foundElement = document.forms[0];
		return ;
	}
	var x = obj.elements;
	for (var i=0;i<x.length;i++)
	{
		if (x[i] == null) continue ;
		if (x[i].name == name)
		 	foundElement = x[i];
	}
}

function JVEditableDropDown() 
{
	this.id = dropdowns.length ;
	dropdowns[this.id] = this ;
	this.createDropDown = createDropDown ;
	this.setSize = setSize ;
	this.setTarget = setTarget ;
	this.readTarget = readTarget ;
	this.newItem = newItem ;

}
function createDropDown()
{
	this.name = 'jvdd_' + this.id ;
//alert("this.name = " + this.name) ;
	var dropdownHtml = '<a href="javascript:hideList(' + this.id + ')">Hide</a>&nbsp;|&nbsp;';
	dropdownHtml+= '<a href="javascript:showList(' + this.id + ')">Show</a>&nbsp;|&nbsp;';
	dropdownHtml+= '<a href="javascript:insertItem(\'\',' + this.id + ')">Insert</a>&nbsp;|&nbsp;';
	dropdownHtml+= '<a href="javascript:removeSelectedItem(' + this.id + ')">Remove</a>&nbsp;|&nbsp;';
	dropdownHtml+= '<a href="javascript:moveSelectedItemUp(' + this.id + ')">Up</a>&nbsp;|&nbsp;';
	dropdownHtml+= '<a href="javascript:moveSelectedItemDown(' + this.id + ')">Down</a>';
	dropdownHtml+= '<br/><select name="' + this.name + '" onKeyDown="fnKeyDownHandler(this, event);" onKeyPress = "return fnKeyPressHandler_A(this, event);" ></select>' ;
	document.write(dropdownHtml) ;
	this.obj = getObj(this.name) ;
this.obj.targetid = this.id ;
//alert("this.obj = " + this.obj) ;
}
function setTarget(target)
{
//alert("setTarget target = " + target) ;
	this.target = getObj(target) ;
}
function readTarget()
{
//alert("this.target = " + this.target) ;
//alert("this.target.value = " + this.target.value) ;
	var items = this.target.value.split("|") ;
  	for (var i = 0 ; i < items.length ; i++) 
	{
//alert("1 items[i] = " + items[i]) ;
    		this.newItem(items[i]) ;
//alert("after newItem") ;
	} 
}
function loadTarget(id)
{
//alert("loadTarget id = " + id) ;
	thisid = getThis(id) ;
//alert("this = " + this) ;
	if (thisid == null) return ;
	mobjThis = thisid.obj ;
	var value = "" ;
  	for (var i = 0 ; i < mobjThis.options.length ; i++) 
	{
    		value += "|" + mobjThis.options[i].value ;
	} 
	thisid.target.value = value.substring(1) ;
}
function getThis(id)
{
	if (id == undefined) return null ;
	if (id != null) return dropdowns[id] ;
	return null ;
}
function getThisObject(id)
{
	var thisobj = getThis(id) ;
	if (thisobj != null)
		return thisobj.obj ;
	else
		return null ;
}
function newItem(item) 
{
//alert("newItem") ;
//alert("newItemthis.obj  = " + this.obj ) ;
	mobjThis = this.obj ;
//alert("newItemmobjThis = " + mobjThis) ;
	if (mobjThis == null) return ;
	var theCount = mobjThis.options.length ;
//alert("theCount = " + theCount ) ;
	mobjThis.options[theCount] = new Option();
	mobjThis.options[theCount].text = item;
	mobjThis.options[theCount].value = item;
}
function insertItem(item, id) 
{
//alert("insertItem item = " + item + " id = " + id) ;
	mobjThis = getThisObject(id) ;
//alert("mobjThis = " + mobjThis) ;
	if (mobjThis == null) return ;
	var theCount = mobjThis.options.length ;
	mobjThis.options[theCount] = new Option();
	if (mobjThis.selectedIndex != -1)
	{
  		for (var i=theCount; i>mobjThis.selectedIndex; i--) 
		{
    			mobjThis.options[i].text = mobjThis.options[i-1].text ;
    			mobjThis.options[i].value = mobjThis.options[i-1].value ;
		}
		mobjThis.options[mobjThis.selectedIndex].text = item;
		mobjThis.options[mobjThis.selectedIndex].value = item;
	}
	else
	{
		mobjThis.options[theCount].text = item;
		mobjThis.options[theCount].value = item;
	}
	showList(id) ;
	loadTarget(id) ;
}
function removeLastItem(id) 
{
	mobjThis = getThisObject(id) ;
	if (mobjThis == null) return ;
	mobjThis.options.length-- ;
}
function removeSelectedItem(id) 
{
	mobjThis = getThisObject(id) ;
	if (mobjThis == null) return ;
  	for (var i=mobjThis.selectedIndex; i<mobjThis.options.length-1; i++) 
	{
    		mobjThis.options[i].text = mobjThis.options[i+1].text ;
    		mobjThis.options[i].value = mobjThis.options[i+1].value ;
	}
	removeLastItem(id) ;
	showList(id) ;
	loadTarget(id) ;
}
function moveSelectedItemUp(id) 
{
	mobjThis = getThisObject(id) ;
	if (mobjThis == null) return ;
	if (mobjThis.selectedIndex == 0) return ;
    	var text = mobjThis.options[mobjThis.selectedIndex - 1].text ;
    	var value = mobjThis.options[mobjThis.selectedIndex - 1].value ;
    	mobjThis.options[mobjThis.selectedIndex - 1].text 
		= mobjThis.options[mobjThis.selectedIndex].text ;
    	mobjThis.options[mobjThis.selectedIndex - 1].value 
		= mobjThis.options[mobjThis.selectedIndex].value ;
    	mobjThis.options[mobjThis.selectedIndex].text = text ;
    	mobjThis.options[mobjThis.selectedIndex].value = value ;
	mobjThis.selectedIndex-- ;
	showList(id) ;
	loadTarget(id) ;
}
function moveSelectedItemDown(id) 
{
	mobjThis = getThisObject(id) ;
	if (mobjThis == null) return ;
	if (mobjThis.selectedIndex == mobjThis.options.length-1) return ;
    	var text = mobjThis.options[mobjThis.selectedIndex + 1].text ;
    	var value = mobjThis.options[mobjThis.selectedIndex + 1].value ;
    	mobjThis.options[mobjThis.selectedIndex + 1].text 
		= mobjThis.options[mobjThis.selectedIndex].text ;
    	mobjThis.options[mobjThis.selectedIndex + 1].value 
		= mobjThis.options[mobjThis.selectedIndex].value ;
    	mobjThis.options[mobjThis.selectedIndex].text = text ;
    	mobjThis.options[mobjThis.selectedIndex].value = value ;
	mobjThis.selectedIndex++ ;
	showList(id) ;
	loadTarget(id) ;
}
function setSize(size)
{
	this.obj.size = size ;
}
function hideList(id)
{
	mobjThis = getThisObject(id) ;
	if (mobjThis == null) return ;
	mobjThis.size = 1 ;
}
function showList(id)
{
	mobjThis = getThisObject(id) ;
	if (mobjThis == null) return ;
	mobjThis.size = mobjThis.options.length ;
}

//---------------------------------------------------------------------------------------------


  function fnKeyDownHandler(getdropdown, e)
  {
    if (getdropdown == null) return ;
    fnSanityCheck(getdropdown);

    // Press [ <- ] and [ -> ] arrow keys on the keyboard to change alignment/flow.
    // ...go to Start : Press  [ <- ] Arrow Key
    // ...go to End : Press [ -> ] Arrow Key
    // (this is useful when the edited-text content exceeds the ListBox-fixed-width)
    // This works best on Internet Explorer, and not on Netscape

    var vEventKeyCode = FindKeyCode(e);

    // Press left/right arrow keys
    if(vEventKeyCode == 37)
    {
    	fnLeftToRight(getdropdown);
    }
    if(vEventKeyCode == 39)
    {
    	fnRightToLeft(getdropdown);
    }

    // Delete key pressed
    if(vEventKeyCode == 46)
    {
    	fnDelete(getdropdown);
	loadTarget(getdropdown.targetid) ;
    }

    // backspace key pressed
    if(vEventKeyCode == 8 || vEventKeyCode==127)
    {
    	if(e.which) //Netscape
    	{
	      //e.which = ''; //this property has only a getter.
    	}
    	else //Internet Explorer
    	{
      		//To prevent backspace from activating the -Back- button of the browser
      		e.keyCode = '';
      		if(window.event.keyCode)
      		{
      			window.event.keyCode = '';
      		}
    	}
	loadTarget(getdropdown.targetid) ;
    	return true;
    }
  }

  function fnLeftToRight(getdropdown)
  {
    getdropdown.style.direction = "ltr";
  }

  function fnRightToLeft(getdropdown)
  {
    getdropdown.style.direction = "rtl";
  }

  function fnDelete(getdropdown)
  {
    if(getdropdown.options.length != 0)
    // if dropdown is not empty
    {
    if (getdropdown.options.selectedIndex == vEditableOptionIndex_A)
    // if option the Editable field
    {
      getdropdown.options[getdropdown.options.selectedIndex].text = '';
      getdropdown.options[getdropdown.options.selectedIndex].value = '';
    }
    }
  }

  function FindKeyCode(e)
  {
    if(e.which)
    {
    keycode=e.which;  //Netscape
    }
    else
    {
    keycode=e.keyCode; //Internet Explorer
    }

    //alert("FindKeyCode"+ keycode);
    return keycode;
  }

  function FindKeyChar(e)
  {
    keycode = FindKeyCode(e);
    if((keycode==8)||(keycode==127))
    {
    	character="backspace"
    }
    else if((keycode==46))
    {
    	character="delete"
    }
    else
    {
    	character=String.fromCharCode(keycode);
    }
    //alert("FindKey"+ character);
    return character;
  }

  function fnSanityCheck(getdropdown)
  {
    if(vEditableOptionIndex_A>(getdropdown.options.length-1))
    {
    	alert("ERROR: The value of variable vEditableOptionIndex_... cannot be greater than (length of dropdown - 1)");
    	return false;
    }
  }

  var vEditableOptionIndex_A = 0 ;
  var vEditableOptionText_A = "";
  var vPreviousSelectIndex_A = 0;
  // Contains the Previously Selected Index, set to 0 by default

  var vSelectIndex_A = 0;
  // Contains the Currently Selected Index, set to 0 by default

  function fnKeyPressHandler_A(getdropdown, e)
  {
    fnSanityCheck(getdropdown);

    keycode = FindKeyCode(e);
    keychar = FindKeyChar(e);

    if ((keycode>47 && keycode<59)||(keycode>62 && keycode<127) ||(keycode==32))
    {
      var vAllowableCharacter = "yes";
    }
    else
    {
      var vAllowableCharacter = "no";
    }

    //alert(window); alert(window.event);

	vEditableOptionIndex_A = getdropdown.options.selectedIndex ;

    if(getdropdown.options.length != 0)
    // if dropdown is not empty
      if (getdropdown.options.selectedIndex == (vEditableOptionIndex_A))
      // if selected option the Editable option of the dropdown
      {

        var vEditString = getdropdown[vEditableOptionIndex_A].value;

        // make Editable option Null if it is being edited for the first time
        if((vAllowableCharacter == "yes")||(keychar=="backspace"))
        {
          if (vEditString == vEditableOptionText_A)
            vEditString = "";
        }
        if (keychar=="backspace")
        // To handle backspace - Subrata Chakrabarty
        {
          vEditString = vEditString.substring(0,vEditString.length-1);
          // Decrease length of string by one from right

          vSelectChange_A = 'MANUAL_CLICK';
          // Indicates that the Change in dropdown selected
          // option was due to a Manual Click

        }
        //alert("EditString2:"+vEditString);

        if (vAllowableCharacter == "yes")
        // To handle addition of a character - Subrata Chakrabarty
        {
          vEditString+=String.fromCharCode(keycode);
          // Concatenate Enter character to Editable string

          // The following portion handles the "automatic Jump" bug
          // The "automatic Jump" bug (Description):
          //   If a alphabet is entered (while editing)
          //   ...which is contained as a first character in one of the read-only options
          //   ..the focus automatically "jumps" to the read-only option
          //   (-- this is a common property of normal dropdowns
          //    ..but..is undesirable while editing).

          var i=0;
          var vEnteredChar = String.fromCharCode(keycode);
          var vUpperCaseEnteredChar = vEnteredChar;
          var vLowerCaseEnteredChar = vEnteredChar;


          if(((keycode)>=97)&&((keycode)<=122))
          // if vEnteredChar lowercase
            vUpperCaseEnteredChar = String.fromCharCode(keycode - 32);
            // This is UpperCase


          if(((keycode)>=65)&&((keycode)<=90))
          // if vEnteredChar is UpperCase
            vLowerCaseEnteredChar = String.fromCharCode(keycode + 32);
            // This is lowercase

          if(e.which) //For Netscape
          {
            // Compare the typed character (into the editable option)
            // with the first character of all the other
            // options (non-editable).

            // To note if the jump to the non-editable option was due
            // to a Manual click (i.e.,changed on purpose by user)
            // or due to System properties of dropdown
            // (i.e.,user did not change the option in the dropdown;
            // instead an automatic jump happened due to inbuilt
            // dropdown properties of browser on typing of a character )

            for (i=0;i<=(getdropdown.options.length-1);i++)
            {
              if(i!=vEditableOptionIndex_A)
              {
                var vReadOnlyString = getdropdown[i].value;
                var vFirstChar = vReadOnlyString.substring(0,1);
                if((vFirstChar == vUpperCaseEnteredChar)||(vFirstChar == vLowerCaseEnteredChar))
                {
                  vSelectChange_A = 'AUTO_SYSTEM';
                  // Indicates that the Change in dropdown selected
                  // option was due to System properties of dropdown
                  break;
                }
                else
                {
                  vSelectChange_A = 'MANUAL_CLICK';
                  // Indicates that the Change in dropdown selected
                  // option was due to a Manual Click
                }
              }
            }
          }
        }
        // Set the new edited string into the Editable option
        getdropdown.options[vEditableOptionIndex_A].text = vEditString;
        getdropdown.options[vEditableOptionIndex_A].value = vEditString;
	loadTarget(getdropdown.targetid) ;

        return false;
      }
	loadTarget(getdropdown.targetid) ;

    return true;
  }

