//**************************************************************************************
// Filename:	DynamicListBox.js
// Version:		3.5
// Purpose:		This library allows a "master" select object to dynamically change the 
//				content of a "slave" select object depending on the "masters" currently
//				selected value.
// Features: 	- Create a chain of master / slave select objects where a slave select object
//				can also be a master for another slave.
//				- A master select object may have many slave select objects.
//				- Master and slave(s) can be synchronized when the webpage loads.
//
// Usage:		This library should be referenced in the header.  In order
//		    	to use a dynamic list box. 
//
//				Steps:
//				1)	The following needs to be added after the end of the slave
//		 	    	select object:
//					<script type="text/javascript">
//						dlb_InitDynamicListBox(strMasterSelectID, strSlaveSelectID);
//					</script>
//				2)	To add a group container enter the following:
//					<script type="text/javascript">
//						dlb_AddGroup(strSlaveSelectID, strGroupValue);
//					</script>
//					Note: The strGroupValue parameter should be equivalent to the "masters" 
//						  option values in order to properly synchronize the master / slave
//						  objects.
//				3)	To add content to the last group added enter the following:
//					<script type="text/javascript">
//						dlb_AddContent(strSlaveSelectID, strContentValue, strContentText);
//					</script>
//
//				Optional Steps:
//  	    	4)	To Synchronize the master with all or only 1 slave once the webpage
//					is loaded enter the following (strSlaveID is optional):
//					<script type="text/javascript">
//						dlb_Synchronize(strMasterSelectID, strSlaveID);
//					</script>
//
//**************************************************************************************

//**************************************************************************************
// PUBLIC FUNCTIONS
//**************************************************************************************

function dlb_InitDynamicListBox(strMasterSelectID, strSlaveSelectID) {	
	var objMasterSelect = document.getElementById(strMasterSelectID);
	var objSlaveSelect = document.getElementById(strSlaveSelectID);
	
	if (!objMasterSelect.strSlaveSelectIDs) {
		objMasterSelect.strSlaveSelectIDs = new Array(); 
	}
	
	objSlaveSelect.arrGroup = new Array(); 
	objSlaveSelect.arrContentValue = new Array(); 
	objSlaveSelect.arrContentText = new Array();	
	
	objMasterSelect.strSlaveSelectIDs[objMasterSelect.strSlaveSelectIDs.length] = objSlaveSelect.id;		
	dlb_AppendEvent(objMasterSelect, "onchange", dlb_ChangeSlaveSelect);
}

function dlb_AddGroup(strSelectID, strGroupValue) {
	var objSelect = document.getElementById(strSelectID);
	objSelect.arrGroup[objSelect.arrGroup.length] = strGroupValue;
	objSelect.arrContentValue[objSelect.arrGroup.length-1] = new Array();
	objSelect.arrContentText[objSelect.arrGroup.length-1] = new Array();
}

function dlb_AddContent(strSelectID, strContentValue, strContentText) { 
	var objSelect = document.getElementById(strSelectID); 
	objSelect.arrContentValue[objSelect.arrGroup.length-1][objSelect.arrContentValue[objSelect.arrGroup.length-1].length] = strContentValue;
	objSelect.arrContentText[objSelect.arrGroup.length-1][objSelect.arrContentText[objSelect.arrGroup.length-1].length] = strContentText;
}

function dlb_Synchronize(strMasterSelectID, strSlaveID) {
	var objMasterSelect = document.getElementById(strMasterSelectID);
	
	for(var i=0; i<objMasterSelect.strSlaveSelectIDs.length; i++) {
		if (dlb_IsUndefined(strSlaveID) || i == strSlaveID) {
			if (objMasterSelect.selectedIndex) {
				dlb_DisplayGroup(objMasterSelect.strSlaveSelectIDs[i], objMasterSelect.options[objMasterSelect.selectedIndex].value);
			}
			else {
				dlb_DisplayGroup(objMasterSelect.strSlaveSelectIDs[i], objMasterSelect.options[0].value);
			}
		}
	}
}

//**************************************************************************************
// PRIVATE FUNCTIONS
//**************************************************************************************

function dlb_DisplayGroup(strSelectID, strGroupValue) {	
	var objSelect = document.getElementById(strSelectID);	
	
	dlb_ClearSelectOptions(strSelectID);
	
	for(var i=0; i<objSelect.arrGroup.length; i++) {
		if (objSelect.arrGroup[i] == strGroupValue) {						
			for(var j=0; j<objSelect.arrContentValue[i].length; j++) {
				objSelect.options[j] = new Option(objSelect.arrContentText[i][j],objSelect.arrContentValue[i][j]); 
			}
			objSelect.selectedIndex = 0;
			break;
		}	
	}	
}

function dlb_ClearSelectOptions(strSelectID) {
	var lngOptionsLength = 0;
	var objSelect = document.getElementById(strSelectID);	
	
	lngOptionsLength = objSelect.options.length;
	for(var k=lngOptionsLength-1; k>-1; k--) {
		objSelect.options[k] = null;
	}
}

function dlb_ChangeSlaveSelect(e) {
	var objMasterSelect = dlb_GetEventSource(e);
	
	for(var i=0; i<objMasterSelect.strSlaveSelectIDs.length; i++) { 
		dlb_DisplayGroup(objMasterSelect.strSlaveSelectIDs[i], objMasterSelect.options[objMasterSelect.selectedIndex].value);
		dlb_ChangeSlaveSelectRecur(objMasterSelect.strSlaveSelectIDs[i]);
	}
}

function dlb_ChangeSlaveSelectRecur(strSelectID) {
	var objMasterSelect = document.getElementById(strSelectID);
	
	if (objMasterSelect.strSlaveSelectIDs) {
		for(var i=0; i<objMasterSelect.strSlaveSelectIDs.length; i++) { 
			if (objMasterSelect.options.length != 0) {			
				dlb_DisplayGroup(objMasterSelect.strSlaveSelectIDs[i], objMasterSelect.options[objMasterSelect.selectedIndex].value);
			}
			else {
				dlb_ClearSelectOptions(objMasterSelect.strSlaveSelectIDs[i]);
			}
			dlb_ChangeSlaveSelectRecur(objMasterSelect.strSlaveSelectIDs[i]);
		}
	}
}

//**************************************************************************************
//                              THESE ARE GENERIC FUNCTIONS                           //
//**************************************************************************************

// Dependencies: dlb_GetFunctionBody(objFunction)
function dlb_AppendEvent(objElement, strEvent, objEventFunction) {
	var strPrefix = (strEvent.substring(0,2)).toLowerCase();	
	strEvent = strEvent.toLowerCase();
	if (objElement.addEventListener) {
		if (strPrefix == "on") strEvent = strEvent.substring(2,strEvent.length);
		objElement.addEventListener(strEvent, objEventFunction, false);
	}
	else if (objElement.attachEvent) {		
		if (strPrefix != "on") strEvent = "on" + strEvent;		
		objElement.attachEvent(strEvent, objEventFunction);
	}
	else {
		if (strPrefix != "on") strEvent = "on" + strEvent;
		if(objElement[strEvent]){
			//we have to combine it.
			objElement[strEvent] = new Function("e", dlb_GetFunctionBody(objEventFunction) + "\n" + dlb_GetFunctionBody(objElement[strEvent]));
		} else {
			objElement[strEvent] = objEventFunction;
		}
	}
}

function dlb_GetFunctionBody(objFunction) {
	var intFoundIndex;
	var strCurrentFunction;
	strCurrentFunction=objFunction.toString();
	intFoundIndex=strCurrentFunction.indexOf('{');
	if(intFoundIndex>=0){
		strCurrentFunction=strCurrentFunction.substring(intFoundIndex+1);
		strCurrentFunction=strCurrentFunction.substring(0, strCurrentFunction.length-2);		
	}
	return strCurrentFunction;
}

function dlb_GetEventSource(e) {
	var targ;
	if (!e) var e = window.event;
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	if (targ.nodeType == 3) // defeat Safari bug
		targ = targ.parentNode;
	return targ;
}

function dlb_IsUndefined(obj) {
	if (typeof(obj) == "undefined" || ""+obj == "undefined" || ""+obj == "")
		return (true);
	else return (false);
}
