<!-- MasterServantSelectLists.js -->

/**
	MasterServantSelectLists
	
	Has code needed to join two select lists on a JSP in a Master-Servant
	relationship where the values chosen in the master will impact the 
	choices that appear in the servant select box. In addition to this code
	there is required code and initial formats that are needed on JSP in
	order for this process to work correctly.
	
	-----------------------------------------------------------------------
	04/27/04 created
/**
    Created on: 04/21/2004
    
    This is a Javascript implementation of the Java Hashtable object.
    
    Contructor(s):
     Hashtable()
              Creates a new, empty hashtable
    
    Method(s):
     void clear() 
              Clears this hashtable so that it contains no keys. 
     boolean containsKey(String key) 
              Tests if the specified object is a key in this hashtable. 
     boolean containsValue(Object value) 
              Returns true if this Hashtable maps one or more keys to this value. 
     Object get(String key) 
              Returns the value to which the specified key is mapped in this hashtable. 
     boolean isEmpty() 
              Tests if this hashtable maps no keys to values. 
     Array keys() 
              Returns an array of the keys in this hashtable. 
     void put(String key, Object value) 
              Maps the specified key to the specified value in this hashtable. A NullPointerException is thrown is the key or value is null.
     Object remove(String key) 
              Removes the key (and its corresponding value) from this hashtable. Returns the value of the key that was removed
     int size() 
              Returns the number of keys in this hashtable. 
     String toString() 
              Returns a string representation of this Hashtable object in the form of a set of entries, enclosed in braces and separated by the ASCII characters ", " (comma and space). 
     Array values() 
              Returns a array view of the values contained in this Hashtable. 
            
*/
function Hashtable(){
    this.clear = hashtable_clear;
    this.containsKey = hashtable_containsKey;
    this.containsValue = hashtable_containsValue;
    this.get = hashtable_get;
    this.isEmpty = hashtable_isEmpty;
    this.keys = hashtable_keys;
    this.put = hashtable_put;
    this.remove = hashtable_remove;
    this.size = hashtable_size;
    this.toString = hashtable_toString;
    this.values = hashtable_values;
    this.hashtable = new Array();
}

/*=======Private methods for internal use only========*/

function hashtable_clear(){
    this.hashtable = new Array();
}

function hashtable_containsKey(key){
    var exists = false;
    for (var i in this.hashtable) {
        if (i == key && this.hashtable[i] != null) {
            exists = true;
            break;
        }
    }
    return exists;
}

function hashtable_containsValue(value){
    var contains = false;
    if (value != null) {
        for (var i in this.hashtable) {
            if (this.hashtable[i] == value) {
                contains = true;
                break;
            }
        }
    }
    return contains;
}

function hashtable_get(key){
    return this.hashtable[key];
}

function hashtable_isEmpty(){
    return (parseInt(this.size()) == 0) ? true : false;
}

function hashtable_keys(){
    var keys = new Array();
    for (var i in this.hashtable) {
        if (this.hashtable[i] != null) 
            keys.push(i);
    }
    return keys;
}

function hashtable_put(key, value){
    if (key == null || value == null) {
        throw "NullPointerException {" + key + "},{" + value + "}";
    }else{
        this.hashtable[key] = value;
    }
}

function hashtable_remove(key){
    var rtn = this.hashtable[key];
    this.hashtable[key] = null;
    return rtn;
}

function hashtable_size(){
    var size = 0;
    for (var i in this.hashtable) {
        if (this.hashtable[i] != null) 
            size ++;
    }
    return size;
}

function hashtable_toString(){
    var result = "";
    for (var i in this.hashtable)
    {      
        if (this.hashtable[i] != null) 
            result += "{" + i + "},{" + this.hashtable[i] + "}\n";   
    }
    return result;
}

function hashtable_values(){
    var values = new Array();
    for (var i in this.hashtable) {
        if (this.hashtable[i] != null) 
            values.push(this.hashtable[i]);
    }
    return values;
}

// *** Global object types used in the MASTER-SERVANT processing  
//
// servantObject holds the master name, servan name and master display name
// the "display" is used in the select lists when more than one master value is selected
//
function servantObj( masterName, servantName, masterDesc )
{
	var quote = '\'';
	//this.masterValue = quote + masterName + quote;
	
	this.masterValue = masterName;
   	this.servantValue = servantName;
   	this.masterText = masterDesc;
}

function tmpOption( value, text, selected )
{
   this.value = value;
   this.text = text;
   this.selected = selected;
}


//
// Take Select list as input and load a hashtable with the value and text for each row
// in select list. In Master-Servant processing this will load the master into a hashtable
// where the "key" values will be used to access the servant data in the servant hash
//
function loadSelectListToHash(selectList) 
{
	var rHash = new Hashtable();
	
	for(var i = 0; i < selectList.options.length; i++ ) {
    	rHash.put( selectList.options[i].value, selectList.options[i].text );
    }

	return rHash;
	
} // end of loadSelectListToHash


//
// Take Select list as input and load a hashtable with the value and text for each row
// in select list. In Master-Servant processing this will load the master into a hashtable
// where the "key" values will be used to access the servant data in the servant hash
//
function loadServantHash(masterHash, servantArray) 
{
	var rHash = new Hashtable();
   	var masterValue = '';
   	var bFirstTime = true;
   	
	for( var i = 0; i < servantArray.length; i ++ )
	{
		if( masterHash.get(servantArray[i]) != null) {
        	if ( bFirstTime) {
        		masterValue = servantArray[i]; 
        	} 
        	else {
        		rHash.put(masterValue, tempArray);
        		masterValue = servantArray[i];
        		tempArray = new Array();
        	}
        }
        else {
        	tempArray.push(arr[i]);
        }
	}

	return rHash;
	
} // end of loadServantHash


//
//loadServantArray 
//
// receives an array of pipe-delimted values (master|servant) and loads into
// the servantObj
function loadServantArray(servantArray, masterHash) 
{
	var rArray = new Array();
   	var county = '';
   	var sWork	= '';
   	var sMaster	= '';
   	var sServant	= '';
   	
   	for( var i = 0; i < servantArray.length; i ++ )
   	{
    	sWork = servantArray[i];
        sMaster = sWork.substring(0, sWork.indexOf("|"));
        sServant = sWork.substring(sWork.indexOf("|")+1);
      
      	//alert("sWork/sMaster/sServant>>" + sWork +"<>" + sMaster + "<>" + sServant + "<");
    	rArray[rArray.length] = new servantObj( sMaster, sServant, masterHash.get(sMaster) );
   	}

	return rArray;
	
} // end of loadServantArray

function initialselect()
{
   return '<select name="City" id="City" size="5" multiple>\n';
}


// `#-- county_select is the select object that contains selected counties --#
//  #-- if initial is true, then the box is preselected with values from before. --#`

function syncMasterServant( pageMaster, pageServantName, servantArray, initial )
{
	var preselected = new Array();
	var quote = '\"';
	var newOptions = new Array();

   //if( initial )
   //  load_preselect();

	//
   	// have any values in the Master list been selected?
   	//
   	if( pageMaster.selectedIndex > -1 ) 
   	{
    	// if this is not the initial population of servant select list, determine which values are 
    	// selected coming into this function to ensure that they remain selected after processing -
      	// if corresponding Master value is still chosen in it's select list. 
      	if( !initial )
      	{
         	preselected.length = 0;
         	var servant = document.getElementById(pageServantName);
         
      		for( var i = 0; i < servant.options.length; i++ ) {
        		if( servant.options[i].selected ) {
            		preselected[preselected.length] = servant.options[i].value;
            	}
            }      
      	}

	
		var selectedMaster = new Array();
    	for( var i = 0; i < pageMaster.options.length; i++ )
		{    	
	    	if( pageMaster.options[i].selected ) {
	    		//crtemp alert("county:>" + pageMaster.options[i].value +"<");
	            selectedMaster[ selectedMaster.length ] = pageMaster.options[i].value;
	        }
		}
		
		for( var i = 0; i < selectedMaster.length; i++ )
    	{
        	for( var j = 0; j < servantArray.length; j++ )
         	{
            	if( selectedMaster[i] == servantArray[j].masterValue )
            	{
               		var selected = false;
               		for( var k = 0; k < preselected.length; k++ )
               		{
               			//alert("preselctd>>" + preselected[k] + "<<");
               		   	//if( preselected[k] == (quote + C[j].name + quote) ) {
               		   	if( preselected[k] == servantArray[j].servantValue) {
                    		selected = true;
                     		break;
                  		}
               		}
               		
               		// add option to servant SELECT statement
				  	newOptions[newOptions.length] = new tmpOption(servantArray[j].servantValue, servantArray[j].servantValue + (( selectedMaster.length > 1 ) ?  (' (' + servantArray[j].masterText + ')') : ''), selected );
				   
            	} // end if selectedMaster = servantArray.MasterValue
         	
         	} // end for all servants loaded
         	
      	} //end for selectedMaster
   	
   	} // end if any master options selected
   
   
	var newOptionList = document.getElementById(pageServantName);
	newOptionList.options.length = 0;
	for( var i = 0; i < newOptions.length; i++ )
	{
		newOptionList.options.length++;
		newOptionList.options[i].value = newOptions[i].value;
		newOptionList.options[i].text = newOptions[i].text;
		
		if( newOptions[i].selected )
			newOptionList.options[i].selected = true;
	}
}


function loadInitialServant( pageMaster, pageServantName, servantArray, preselected )
{
	var quote = '\"';
	var newOptions = new Array();


	//
   	// have any values in the Master list been selected?
   	//
   	if( pageMaster.selectedIndex > -1 ) 
   	{
    	// if this is not the initial population of servant select list, determine which values are 
    	// selected coming into this function to ensure that they remain selected after processing -
      	// if corresponding Master value is still chosen in it's select list. 
	
		var selectedMaster = new Array();
    	for( var i = 0; i < pageMaster.options.length; i++ )
		{    	
	    	if( pageMaster.options[i].selected ) {
	    		//crtemp alert("county:>" + pageMaster.options[i].value +"<");
	            selectedMaster[ selectedMaster.length ] = pageMaster.options[i].value;
	        }
		}
		
		for( var i = 0; i < selectedMaster.length; i++ )
    	{
        	for( var j = 0; j < servantArray.length; j++ )
         	{
            	if( selectedMaster[i] == servantArray[j].masterValue )
            	{
               		var selected = false;
               		for( var k = 0; k < preselected.length; k++ )
               		{
               			//alert("preselctd>>" + preselected[k] + "<<");
               		   	//if( preselected[k] == (quote + C[j].name + quote) ) {
               		   	if( preselected[k] == servantArray[j].servantValue) {
                    		selected = true;
                     		break;
                  		}
               		}
               		
               		// add option to servant SELECT statement
				  	newOptions[newOptions.length] = new tmpOption(servantArray[j].servantValue, servantArray[j].servantValue + (( selectedMaster.length > 1 ) ?  (' (' + servantArray[j].masterText + ')') : ''), selected );
				   
            	} // end if selectedMaster = servantArray.MasterValue
         	
         	} // end for all servants loaded
         	
      	} //end for selectedMaster
   	
   	} // end if any master options selected
   
   
	var newOptionList = document.getElementById(pageServantName);
	newOptionList.options.length = 0;
	for( var i = 0; i < newOptions.length; i++ )
	{
		newOptionList.options.length++;
		newOptionList.options[i].value = newOptions[i].value;
		newOptionList.options[i].text = newOptions[i].text;
		
		if( newOptions[i].selected )
			newOptionList.options[i].selected = true;
	}
}



/************************************************************************************/
// functions not in initial run of it
//
//
//loadServantArray 
//
// receives an array of pipe-delimted values (master|servant) and loads into
// the servantObj
function chrloadServantArray(servantArray, masterHash) 
{
	var rArray = new Array();
   	var county = '';
   	var sWork	= '';
   	var sMaster	= '';
   	var sServant	= '';
   	
   	for( var i = 0; i < servantArray.length; i ++ )
   	{
    	sWork = servantArray[i];
        sMaster = sWork.substring(0, sWork.indexOf("|"));
        sServant = sWork.substring(sWork.indexOf("|")+1);
      
      	//alert("sWork/sMaster/sServant>>" + sWork +"<>" + sMaster + "<>" + sServant + "<");
    	rArray[rArray.length] = new servantObj( sMaster, sServant, masterHash.get(sMaster) );
   	}

	return rArray;
	
} // end of loadServantArray

// end of master-servant