
	/***********************************\
	|*	System.Xml.js				   *|
	|*  Functions for Working with XML *|
	\***********************************/
	
	this.Tag = function( NodeID )
	{
		return document.getElementById( NodeID );
	}
	
	this.TagsByName = function( Name )
	{
		return document.body.getElementsByTagName( Name ); //getElementsByTagName implemented in DOM Level 1 Core
	}
	//todo: consider making these functions accept the HtmlElement Obj itself,
	//sometimes you might want to delete a node that has no Id, perhaps when you get a ref to it inside of an event handler
	this.HideHtmlNode = function( NodeID )
	{
		Tag(NodeID).style.display = "none";
	}
	this.ShowHtmlNode = function( NodeID )
	{
		Tag(NodeID).style.display = "block";
	}
	this.DeleteHtmlNode = function( NodeID )
	{
		var Node = Tag(NodeID);
		Node.parentNode.removeChild( Node );
	}
	this.DeleteXmlNode	= this.DeleteHtmlNode;
	this.HideXmlNode	= this.HideHtmlNode;
	this.ShowXmlNode	= this.ShowHtmlNode;
	
	this.ToggleNodeVisibility = function( NodeID )
	{
		if( Tag(NodeID).style.display == "none" )
		{
			Tag(NodeID).style.display = "";			
		}
		else
		{
			Tag(NodeID).style.display = "none";
		}
	}
	
	/* XmlHttpClient */
	function XmlHttpClient()
	{
		var XmlObj;
		if( window.XMLHttpRequest ) // Create Firefox Object
		{
			XmlObj = new XMLHttpRequest();
			return XmlObj;
		}
		else if ( window.ActiveXObject ) // Create IE XMLHTTP Object
		{
			XmlObj = new ActiveXObject( "msxml2.XMLHTTP.3.0" );
			if ( XmlObj )
			{
				return XmlObj;
			}
		}
	}

	/* XmlClient Class */
	/* Cross Platform Xml/Http Functionality - Works for both IE and Firefox */
	//TODO: Reimplement using with for a more succinct implementation
	var XmlClientArray = new Array();
	function XmlClient( OnResponseComplete, OnResponseError )
	{
		//QueryString, OnResponseComplete
		var MyClient	= new XmlHttpClient();
		this.Index		= XmlClientArray.push( MyClient ) - 1;

		this.HttpTransferComplete = function()
		{
			if ( MyClient.readyState == 4 )
			{				
				if ( MyClient.status != null && MyClient.status == 200 )
				{
					if( OnResponseComplete )
					{
						OnResponseComplete();						
					}
				}
				else
				{
					if( OnResponseError )
					{
						OnResponseError();
					}
				}
			}
		}
		XmlClientArray[this.Index].onreadystatechange = this.HttpTransferComplete;
		//End of Object Initialization
		
		this.Abort = function()
		{
			XmlClientArray[this.Index].abort();
		}
		
		this.GetResponseText = function()
		{
			return XmlClientArray[this.Index].responseText;
		}

		this.GetResponseXml = function()
		{
			return XmlClientArray[this.Index].responseXML;
		}
		
		this.GetResponseXML = this.GetResponseXml;
		
		this.SendNVC = function( inNVC, optionalURL )
		{
			if( optionalURL )
			{
				XmlClientArray[this.Index].open( "POST", optionalURL, true );
			}
			else
			{
				XmlClientArray[this.Index].open( "POST", location.pathname, true );
			}
			XmlClientArray[this.Index].setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
			XmlClientArray[this.Index].send( inNVC.URLEncode() );
		}
	}//End XmlClient

	/* One time Xml over Http Request */
	function PostNVC( inNVC, optionalURL )
	{
		var httpClient = new XmlHttpClient();
		if( optionalURL )
		{
			httpClient.open( "POST", optionalURL, false );
		}
		else
		{
			httpClient.open( "POST", location.pathname, false );
		}
		httpClient.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
		httpClient.send( inNVC.URLEncode() );
		return httpClient.responseText;
	}
	
	function PostQueryString( QueryString, optionalURL )
	{
		var httpClient = new XmlHttpClient();
		if( optionalURL )
		{
			httpClient.open( "POST", optionalURL, false );
		}
		else
		{
			httpClient.open( "POST", location.pathname, false );
		}
		httpClient.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );
		httpClient.send( QueryString );
		return httpClient.responseText;
	}	
	SendNVC = PostNVC;
	SendQueryString = PostQueryString;

	/* Performs an HTTP Get of the document specified by the URL */
	function GetDocument( optionalURL )
	{
		var httpClient = new XmlHttpClient();
		if( optionalURL )
		{
			httpClient.open( "GET", optionalURL, false );
		}
		else
		{
			httpClient.open( "GET", location.pathname, false );
		}
		httpClient.send( null );
		return httpClient.responseText;
	}	

// SELECT TAG - AUTHOR: James Wilson //
var SelectTag = 
{
	//    XmlNode SelectTagNode, string inValueToSelect
	SelectOption: function(SelectTagNode, inValueToSelect)
	{
		for(var i = 0; i < SelectTagNode.options.length; i++)
		{
			if(SelectTagNode.options[i].value == inValueToSelect)
			{
				SelectTagNode.selectedIndex = i;
				return true;
			}
		}
		return false;
	},
	
	//XmlNode SelectTagNode, string OptionValue, string OptionText, (bool Selected)
	AddOption: function(SelectTagNode, OptionValue, OptionText, Selected)
	{
		if(SelectTagNode == null)
			return SelectTag.AddOptionPrompt;
		var newOption = document.createElement("OPTION");
		SelectTagNode.options.add(newOption);
		newOption.innerText = OptionText;
		newOption.value = OptionValue;
		if(Selected != null) //optional
			newOption.selected = Selected;
	},

	AddOptionPrompt: function()
	{
		var NewOption=prompt('Enter new option:','');
		if(NewOption != null && NewOption.length > 0)
		{ 	SelectTag.AddOption(event.srcElement, NewOption, NewOption, true);
			//SelectTag.Sort();
		}
		else
		{
			event.srcElement.selectedIndex = 0;
		}
	},
	
	HandleOther: function()
	{
		var SelectedText = event.srcElement.options[event.srcElement.selectedIndex].innerText
		if(SelectedText == 'Other' || SelectedText == 'Other...')
			SelectTag.AddOptionPrompt();
	},
	
	//TODO: See if it can be reimplemented using F(M) framework
	Sort: function(select) 
	{
		compareFunction = compareText;
		var options = new Array(select.options.length);
		for (var i = 0; i < options.length; i++)
		{
			if(typeof(select.options[i].value) != 'nothing' && select.options[i].value != null && select.options[i].value != '')
			{
				options[i] = new Option (	select.options[i].text,				select.options[i].value,
											select.options[i].defaultSelected,	select.options[i].selected );
			}
		}
		options.sort(compareFunction);
		select.options.length = 0;
		for (var i = 0; i < options.length; i++)
		{
			try { select.options[i] = options[i]; }
			catch(e) { /*Nothing*/ }
		}
	}
};
	
	/*
	function SortTableByColumn()
	{
		var cols			= Tag("DivBugTable").getElementsByTagName("col");
		var rowsOne			= Tag("DivBugTable").getElementsByTagName( "tr" );
		var slSpanValues	= new Array( rowsOne.length );
		for( var i = 0; i < rowsOne.length; i++ )
		{
			ArrSpans = rowsOne[i].getElementsByTagName("span");
			for( var j = 0; j < ArrSpans.length; j++ )
			{
				if ( ArrSpans[j].getAttribute("id") == "BugShortDesc" )
				{
					slSpanValues.push( ArrSpans[j].innerText );
				}
			}
		}
		var ResultXml	= new String();
		var ResultCols	= new String();
		
		for( var i = 0; i < cols.length; i++ )
		{
			ResultCols = ResultCols + cols[i].outerHTML;
		}
		Tag("DivBugTable").innerHTML = "";
		alert( "BoutToChange" );
		try
		{
			Tag("DivBugTable").innerHTML = "<table id=\"BugTable\" cellspacing=\"0\" cellpadding=\"0\" width=\"100%\" border=\"0\">" + ResultCols + ResultXml + "</table>";
		}
		catch( e )
		{
			alert(e);
		}
		return;
	}*/
	
	
/*
function LoadScriptTags( SourceText )
{
	var TempSpan = document.createElement("span");
	TempSpan.innerHTML = SourceText;
	var ScriptTags = TempSpan.getElementsByTagName("script");
	for( var i = 0; i < ScriptTags.length; i++ )
	{
		TempSpan.appendChild( ScriptTag[i] );
	}
	var HeadTags = TagsByName( "head" ); //like there will be more than one...
	HeadTags[0].innerHTML += TempSpan.innerHTML;
	return;
}
*/

	/*	
	this.AddRow = function( TableNodeID, inNVC )
	{
		var TableObj	= Tag( TableNodeID );
		var Rows		= TableObj.getElementsByTagName( "tr" );
		var RowOne;		//I will have to use this row as a template...Kinda assumes that there is at least one row...
		for( var i = 0; i < Rows.length; i++ )
		{
			if( Rows[i].getAttribute("id") == "TemplateRow" )
			{
				RowOne = Rows[i];
			}
		}
		var NewRow	= RowOne.cloneNode( true );
		var SpanCol = NewRow.getElementsByTagName("span");
		
		for( var i = 0; i < SpanCol.length; i++ )
		{
			var KeyIndex = inNVC.IndexOfKey( SpanCol[i].getAttribute("id") );
			if( KeyIndex != -1 )
			{
				SpanCol[i].innerText = inNVC.GetValueAt(KeyIndex);
			}
			else
			{
				SpanCol[i].innerHTML = "&#160;"; //Nothing inside the cell...
			}
		}
		NewRow.style.display = "";
		NewRow.id = Math.random();
		TableObj.appendChild( NewRow );
	}*/
	
	function compareText (option1, option2)
	{
		return option1.text < option2.text ? -1: option1.text > option2.text ? 1 : 0;
	}
	
	var dtCh	=	"/";
	var minYear	=	1900;
	var maxYear	=	2100;

function isInteger(s){
	var i;
    for (i = 0; i < s.length; i++)
	 {
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    return true;
}

function stripCharsInBag(s, bag) {
	var i;
	var returnString = "";	
	for (i = 0; i < s.length; i++)
	{
		var c = s.charAt(i);
		if (bag.indexOf(c) == -1)
			returnString += c;
	}
	return returnString;
}

function daysInFebruary( year )
{
    return ( ( ( year % 4 == 0 ) && ( ( !( year % 100 == 0 )) || ( year % 400 == 0 ) ) ) ? 29 : 28 );
}
function DaysArray(n)
{
	for (var i = 1; i <= n; i++)
	{
		this[i] = 31;
		if (i==4 || i==6 || i==9 || i==11)
			this[i] = 30;		
		if (i==2)		
			this[i] = 29;
	}
	return this;
}

function IsDate(dtStr)
{
	var daysInMonth = DaysArray(12);
	var pos1=dtStr.indexOf(dtCh);
	var pos2=dtStr.indexOf(dtCh,pos1+1);
	var strMonth=dtStr.substring(0,pos1);
	var strDay=dtStr.substring(pos1+1,pos2);
	var strYear=dtStr.substring(pos2+1)
	strYr = strYear;
	if (strDay.charAt(0)=="0" && strDay.length>1)
	{	strDay=strDay.substring(1);	}
	if (strMonth.charAt(0)=="0" && strMonth.length>1)
	{	strMonth=strMonth.substring(1);	}
	
	for (var i = 1; i <= 3; i++)
	{
		if (strYr.charAt(0)=="0" && strYr.length>1)
			strYr=strYr.substring(1);
	}
	month=parseInt(strMonth)
	day=parseInt(strDay)
	year=parseInt(strYr)
	if (pos1==-1 || pos2==-1){
		//alert("The date format should be : mm/dd/yyyy")
		return false
	}
	if (strMonth.length<1 || month<1 || month>12)
	{
		//alert("Please enter a valid month")
		return false;
	}
	if( strDay.length < 1 || day < 1 || day > 31 || ( month == 2 && day > daysInFebruary( year ) ) || day > daysInMonth[month] )
	{
		//alert("Please enter a valid day");
		return false;
	}
	if( strYear.length != 4 || year == 0 || year < minYear || year > maxYear )
	{
		//alert("Please enter a valid 4 digit year between "+minYear+" and "+maxYear);
		return false;
	}
	if( dtStr.indexOf( dtCh, pos2+1 ) != -1 || isInteger( stripCharsInBag( dtStr, dtCh ) ) == false )
	{
		//alert("Please enter a valid date");
		return false;
	}
	return true;
}