/*
URPM_AJAX.js Version 1.1

Changes Log:

Mar 2008:	Removed eval(). Potentially unsafe.
Apr 2008:	Added toCamelCase() and setListValues() functions
		to allow lists to send description to server
		instead of value.
*/



var DEFAULT_URL	= "getListItems.asp";
var IS_SAFARI 	= ( navigator.userAgent.toLowerCase().indexOf('safari') != -1 );


function initialize()
{
	setOptionalProperties();
	
	//This is only done the first time loading so that the lists will retain
	//their values when using the back and forward buttons on the browser.
	//The only side effect is that using the refresh button will not reset the
	//lists in IE.  Instead, you have to use the "Reset" button on the form
	//or highlight the URL in the address field and hit enter to force a page reload.
	
	if(initLists(arguments) && !window.BASE_LIST.options.length) window.BASE_LIST.callServer();
}

	
function setOptionalProperties()
{
	var getHiddenFieldValue = function( fieldId )
	{
		var field = document.getElementById(fieldId);

		return field ? field.value : false;
	}

	var convertToBoolean = function( str )
	{
		var booleanValue = false;

		try
		{
			//this works on true and false and numbers such as 0 and 1, and blank strings
			booleanValue = eval(str);

			booleanValue = Boolean(booleanValue);
		}
		catch (e)
		{
			booleanValue = Boolean(str);
		}

		return booleanValue;
	}
	
	window.BLANK_ENTRY = convertToBoolean( getHiddenFieldValue("showBlank") );
	
	window.PROMPT_TEXT = getHiddenFieldValue("promptText");
	if ( window.PROMPT_TEXT ) window.BLANK_ENTRY = true;
	
	window.URL = getHiddenFieldValue("url");
	if ( ! window.URL ) { window.URL = window.DEFAULT_URL; }
	
	window.FILE_DSN = getHiddenFieldValue("FileDSN");
	
}

String.prototype.toCamelCase = function()
{
    var str = this;
    
    if (str != null && str.length > 1)
        str = str.charAt(0).toUpperCase() + str.substring(1).toLowerCase();
        
    return str;
}


function setListValues()
{
    var list = window.BASE_LIST;
    var hiddenField;
    
    do
    {
    	hiddenField = document.getElementById("send" + list.id.toCamelCase() + "Description");
    	if ( hiddenField && list.selectedIndex)
	{
	 	//use the description instead of the value
	        list.options[list.selectedIndex].value = list.options[list.selectedIndex].text;
        
        	//remove the hidden field
        	//hiddenField.parentNode.removeChild(hiddenField);
        }
           
 	list = list.next;
    } while (list);
    
    return true;
}

function initLists( args )
{
	var bindOnChangeHandlerToList = function( changeHandler )
	{
		var CAPTURING_PHASE = true, BUBBLING_PHASE = false;
		
		var getEventHandler = function()
		{
			return function(e) { changeHandler.call(e.target ? e.target : event.srcElement); };
		}

		if( this.addEventListener ) 
		{
			this.addEventListener( 'change', getEventHandler(), BUBBLING_PHASE );
		} 
		else if( this.attachEvent ) 
		{
			this.attachEvent( 'onchange', getEventHandler() );
		}
		else
		{
			alert( "Could not bind onchange event handlers to list.  Aborting." );	
			
			return;
		}
	
		return true;
	}

	var initBaseList = function()
	{	
		var getFireEventFunction = function()
		{	
			var BUBBLES = true, CANCELABLE = true;
			
			return 	( this.fireEvent	//IE
					  ? function() { this.fireEvent("onchange"); }
					  : function() 		//Non-IE
					  	{
							var	evt = document.createEvent("HTMLEvents");
								evt.initEvent("change", BUBBLES, CANCELABLE);
					  		
					  		this.dispatchEvent(evt); 
					  	}
					);
		}

		this.reset = function()
		{
			this.selectedIndex = this.DEFAULT_INDEX; 

			fireOnChangeEvent.call(this); 
		}

		this.setDefaultIndex = function( optionsLength )
		{
			var defaultIndexField = document.getElementById("defaultIndex");

			if (defaultIndexField)
			{
				var defaultIndex = parseInt(defaultIndexField.value);

				if (! isNaN(defaultIndex)
				   && defaultIndex >= 0
				   && defaultIndex < optionsLength - window.BLANK_ENTRY )
				{	
					this.selectedIndex = this.DEFAULT_INDEX = (defaultIndex + window.BLANK_ENTRY);
				}
			}

			this.setDefaultIndex = function() {};
		}

		window.BASE_LIST = this;
		
		window.BASE_LIST.callServer = callServer;
		
		return getFireEventFunction.call(window.BASE_LIST);
	}

	var callServer = function( selection )
	{
		//Static class using JavaScript Object Notation (JSON)
		var XmlHttpObjectManager = (function()
		{	
			var xmlHttpObject 	 = null;
			var interface		 = 
			{
				getXmlHttpInstance:function()
				{	
					interface.getXmlHttpInstance = function() { return xmlHttpObject; };
					
					return new XmlHttpObject();
				}
				,
				state_change:function(xmlhttp, callBackFunction, READY_STATE, STATUS)
				{
					if (xmlhttp.readyState == READY_STATE._DONE_LOADING)
					{	
						try
						{
							callBackFunction.call(this, xmlhttp, STATUS );
						}
						catch (e)
						{
							alert( "An error occurred in the AJAX call back method:"
								 + "\nNumber:\t" + e.number
								 + "\nName:\t" + e.name
								 + "\nMessage:\t" + e.message );
						}
					}
				}	//public constants
				,
				RUN: { _ASYNCHRONOUSLY:true }
				,
				READY_STATE: { _DONE_LOADING:4 }
				,
				STATUS: { _OK:200 }
			};

			//constructor
			var XmlHttpObject = function()
			{
				try
				{
					xmlHttpObject = new ActiveXObject('Msxml2.XMLHTTP');
				}
				catch (e)
				{
					  try
					  {
							xmlHttpObject = new ActiveXObject('Microsoft.XMLHTTP');
					  }
					  catch (E)
					  {
							xmlHttpObject = false;
					  }
				}

				if (! xmlHttpObject && typeof(XMLHttpRequest) != 'undefined')
				{
					xmlHttpObject = new XMLHttpRequest();

					if ( ! xmlHttpObject )
					{
						alert("Your browser does not support the XMLHttpRequest object.");
						return false;
					}
				}
				
				return (xmlHttpObject);
			}

			Function.prototype.bind = function(object) 
			{	
				var method = this;

				arguments.slice = Array.prototype.slice;

				var oldArguments = arguments.slice(1);

				return function() { return method.apply(object, oldArguments); };
			}

			return interface;
		})();
		
		var xmlhttp = XmlHttpObjectManager.getXmlHttpInstance();
		
		if ( xmlhttp )
		{
			var url	= window.URL + "?list=" + this.id;

			if (arguments.length)	url += ( "&code=" + selection );

			if (window.FILE_DSN) 	url += ( "&FileDSN=" + window.FILE_DSN );

			try
			{
				with ( XmlHttpObjectManager )
				{
					xmlhttp.open("GET", encodeURI(url), RUN._ASYNCHRONOUSLY);

					xmlhttp.onreadystatechange = state_change.bind(	this, 
																	xmlhttp, 
																	fillListCallBack,
																	READY_STATE,
																	STATUS );
				}
				xmlhttp.send(null);
			}
			catch (e)
			{
				alert( "Couldn't establish an AJAX connection:"
					 + "\nNumber:\t" + e.number
					 + "\nName:\t" + e.name
					 + "\nMessage:\t" + e.message );
			}
			
		}
	}

	var fillListCallBack = function( xmlhttp, STATUS )
	{
		var list = this;
		
		if ( xmlhttp.status == STATUS._OK )
		{
			//confirm that there are linked items
			if ( !xmlhttp.responseText || xmlhttp.responseText == "N/A" )
			{
				list.options[0] = new Option("N/A", "");
			}
			else
			{
				if ( xmlhttp.responseText.match(/^alert\("(.+)"/) )
				{
					alert(RegExp.lastParen);		
				}
				else
				{
					//Safari 3 bug workaround
					if (window.IS_SAFARI) list.style.display='none';

					if ( window.BLANK_ENTRY ) list.options[0] = new Option(window.PROMPT_TEXT, "");

					//dangerous
					//eval(xmlhttp.responseText);
					var aOptions = xmlhttp.responseText.split("\n");

					for (var i=0; i < aOptions.length - 1; i++)
					{
						var aValues = aOptions[i].split('\t');

						list.options[list.options.length] = new Option( aValues[0], aValues[1] ); 
					}

					//Safari 3 bug workaround
					if (window.IS_SAFARI) list.style.display='block';
						
					//this initialization code has to run here
					//because ajax is running asynchronously.
					window.BASE_LIST.setDefaultIndex( list.options.length );

					fireOnChangeEvent.call(list);
				}
			}
		}
		else
		{
			list.options[0] = new Option("Ajax Error", "");

			alert( "The XMLHttpRequest object returned a status of '" + xmlhttp.status
				 + ": " + xmlhttp.statusText + "'.");
		}	
		list = null;
	}

	var setSublist = function setSublist()
	{
		var sublist = this.next;

		//safari 3 bug workaround
		if (window.IS_SAFARI)
		{
			if (! this.lastIndex
			   || this.lastIndex != this.selectedIndex)
			{
				this.lastIndex = this.selectedIndex;
			}
			else
			{
				return;
			}
		}
		//clear the list's contents
		with (sublist) { if( options.length > 0 ) while(options.length) options[0] = null; }
		
		if ( this.selectedIndex >= window.BLANK_ENTRY )
		{	
			callServer.call( sublist, this.options[this.selectedIndex].value );
		}
		else
		{
			fireOnChangeEvent.call(sublist);  //clears the next sublist
		}
	}
	
	//initLists() function body starts here**********************************************
	
	var list, last, fireOnChangeEvent;
	
	for (var i=0; i<args.length; i++)
	{
		list = document.getElementById(args[i]);

		if ( list )
		{	
			if (last) last.next = list;        
    			last = list;

			if ( i == 0 ) fireOnChangeEvent = initBaseList.call(list);
			
			if (i < args.length - 1 && !bindOnChangeHandlerToList.call(list, setSublist)) return;
		}
		else
		{
			alert("'" + args[i] + "' is not a valid ID. Unable to link the lists.");

			return;
		}
	}	
	 
	return true;
}
	
//call the list method
function resetLists() { if (window.BASE_LIST) window.BASE_LIST.reset() }