//Last modified: Feburary 05, 2009

//feb 5, 2009: changed the timeout from 2000 to 3000 miliseconds for ContextMenu
//mar 17, 2008: added function GetAttrChkCount(attrName, attrValue)
//oct 18, 2007: Added function NPromptButtons(sMessage, sButtonText, sButtonFunction, sAreaID, sNonDisableList, oFocus)
//feb 6, 2007: added String.prototype.findAndReplace = function(sFind, sReplace)
//oct 11, 2006: added function SetDisplayOfElements(sTag, sAttrName, sAttrValue, sDisplay)
//sep 28, 2006: added function GetChkCount(attrName, attrValue)
//				added function GetChkAttrValues(attrName, attrValue, valueAttrName)
//aug 21, 2006: modified function MoveCBOItemWithAttributes(oFrom, oTo, bRemove)
//jul 27, 2006: modified function CopyCBOItem(oFrom, oTo)
//				modified function MoveCBOItemWithAttributes(oFrom, oTo, bRemove)
//				added function CountCBOSelectedItems(cbo)
//feb 2, 2006: added function FilePathIsValid(sFilepath)
//sep 23, 2005: added function CheckTyping(txt, iMax)
//sep 22, 2005: added function MoveItemArrayTop(arr, nPos)
//jul 18, 2005: added function CountDistinctItems(sList, sToken)
//jul 4, 2005: modified function Trim(s), function ltrim(s), function rtrim(s)
//feb 24, 2005: added function TokensAreSame(s1,s2,sSeparator)
//feb 21, 2005: modified function DisplayContextMenu(oSource,sMenuEntries,sActions)
//feb 14, 2005: added function SetReadOnlyBackgroundColor(obj,bReadonly,sBackgroundColor)
//jan 26, 2005: added function MoveCBOItemWithAttributes(oFrom,oTo,bRemove)
//sep 22, 2004: added functions to deal with sorting combo boxes
//sep 21, 2004: function ValueExistsInCBO(cbo,sValue), function CopyCBOItem(oFrom,oTo), function DeleteOptionByValue(cbo,sValue), function GetItemIndexInCBO(cbo,sItemValue,sAttribute)
//sep 20, 2004: added function ItemExistsInCBO(cbo,sItem), ltrim(s), rtrim(s)
//Modified: function ReplaceImage(sImgName,sImgFile, action)
//Added function GetCountOfCharInString(sSource,sChar)
//Added function GetListOfCBOAttribute(cbo,sAttribute)
//function ArrayToString(arr,sToken)
//Context Menu functions
//Function to detect OS
//Stylesheets

//Page: utilities.js

//Variables used in this include file.
var oContextMenuTimeout; //Timeout to remove the context menu automatically

//Table style for the "popup boxes"
//3D Look.

//Puts HTML in the message area of the page
function PopulateMessageArea(sMessage,sAreaID)
{
	try
	{
		obj=document.getElementById(sAreaID);
		obj.innerHTML=sMessage;
	}
	catch(e){}
}

// oct 18, 2007
//Creates a "display window" in the message area specified.
function NDisplay(sMessage,sAreaID)
{
	var h="";
	h="<br><table class='BackgroundApplicationColor TableMainFileUpload' cellpadding=0 cellspacing=0 align=center border=0>"
	h+="<tr>";
	h+="<td colspan=2 class='rpt TextBackgroundApplicationColor' style='color:white;' align=left>&nbsp;&nbsp;<b>Application Message</b></td>";
	h+="<td class='TextBackgroundApplicationColor' align='right'><input type=button class=submit onmouseover=className='submitON' onmouseout=className='submit' id=btn_NPromptButtons_x value=x onclick=RestoreAllPageElements('');EmptyMessageArea('" + sAreaID + "')></td>";
	h+="</tr>";	
	h+="<tr><td colspan=3>&nbsp;</td></tr>";
	h+="<tr>";
	h+="<td>&nbsp;</td>";
	h+="<td align='center' class='rpt'>";
	h+="<b>" + sMessage + "</b>";
	h+="</td>";
	h+="<td>&nbsp;</td>";
	h+="</tr>";
	h+="<tr><td colspan=3>&nbsp;</td></tr>";
	h+="</table>";
	PopulateMessageArea(h,sAreaID);
	//Set focus to the X button.
	document.getElementById("btn_NPromptButtons_x").focus();
	//Scroll a little bit up to make the whole frame of the window visible.
	window.scrollBy(0,-10);
	document.getElementById("btn_NPromptButtons_x").disabled=true;
}

// oct 18, 2007
//Creates a "window" in the message area specified, with an OK button to close it.
//It disables all input, button,select,etc. fields until the user click OK,
//then it returns them to their previous state.
//If oFocus specified, it sets focus to the object.
//If sFunction specified, it goes to the function after OK is clicked.
function NAlert(sMessage,sAreaID,oFocus,sFunction)
{
	var h="";
	s___ObjectFocus=oFocus; //Store the object to receive focus later.
	h="<br><table class='BackgroundApplicationColor TableMainFileUpload' cellpadding=0 cellspacing=0 align=center border=0>"
	h+="<tr>";
	h+="<td colspan=2 class='rpt TextBackgroundApplicationColor' style='color:white;' align=left>&nbsp;&nbsp;<b>Application Message</b>&nbsp;</td>";
	h+="<td class='TextBackgroundApplicationColor' valign=top align=right><input type=button class=submit onmouseover=className='submitON' onmouseout=className='submit' id=btn_NPromptButtons_x value=x onclick=RestoreAllPageElements('');EmptyMessageArea('" + sAreaID + "');" + sFunction + "></td>";
	h+="</tr>";
	h+="<tr><td colspan=3>&nbsp;</td></tr>";
	h+="<tr>";
	h+="<td>&nbsp;</td>";
	h+="<td align='center' class='rpt'>";
	h+="&nbsp;&nbsp;<b>" + sMessage + "</b>";
	h+="<br><br><input id=btn_NPromptButtons_OK type=button class=submit onmouseover=className='submitON' onmouseout=className='submit' value='   OK   ' onclick=RestoreAllPageElements('');EmptyMessageArea('" + sAreaID + "');" + sFunction + " >";
	h+="</td>";
	h+="<td>&nbsp;</td>";
	h+="</tr>";
	h+="<tr><td colspan=3>&nbsp;</td></tr>";
	h+="</table>";
	PopulateMessageArea(h,sAreaID);
	//Set focus to the X button.
	document.getElementById("btn_NPromptButtons_x").focus();
	//Scroll a little bit up to make the whole frame of the window visible.
	window.scrollBy(0,-10);
	DisableAllPageElements("");
}

// oct 18, 2007
//Creates a "prompt window" in the message area specified,
//with Yes and No buttons, and the buttons will call the specified function
//when they are clicked.
//All input,button,reset,submit,select elements are disabled and then
//set back to their previous state once a button is clicked.
//If the sNonDisableList (comma-delimited) contains element ids, these will not be
//disabled.
//If the oFocus is specified, this object will get the focus later.
//function NPromptYesNo(sMessage,sFunctionYes,sFunctionNo,sAreaID,bDisableAll)
function NPromptYesNo(sMessage,sFunctionYes,sFunctionNo,sAreaID,sNonDisableList,oFocus)
{
	var h="";
	s___AreaID=sAreaID; //Keep in page variable.
	s___NonDisableList=sNonDisableList; //Keep in page variable.
	s___ObjectFocus=oFocus; //Store the object to receive focus later.	
	h="<br><table class='BackgroundApplicationColor TableMainFileUpload' cellpadding=0 cellspacing=0 align=center border=0>"
	h+="<tr>";
	h+="<td colspan=2 class='rpt TextBackgroundApplicationColor' style='color:white;' align=left>&nbsp;&nbsp;<b>Application Prompt</b></td>";
	h+="<td class='TextBackgroundApplicationColor' align=right><input type=button class=submit onmouseover=className='submitON' onmouseout=className='submit' id=btn_NPromptButtons_x value=x onclick=RestoreAllPageElements(s___NonDisableList);EmptyMessageArea(s___AreaID);" + sFunctionNo + " ></td>";
	h+="</tr>";	
	h+="<tr><td colspan=3>&nbsp;</td></tr>";
	h+="<tr>";
	h+="<td>&nbsp;</td>";
	h+="<td align='center' class='rpt'>";
	h+="&nbsp;&nbsp;<b>" + sMessage + "</b>";
	h+="<br><br><input type=button class=submit onmouseover=className='submitON' onmouseout=className='submit' id=btn_NPromptButtons_yes value='   YES   ' onclick=RestoreAllPageElements(s___NonDisableList);EmptyMessageArea(s___AreaID);" + sFunctionYes + " >";
	h+="&nbsp;<input type=button class=submit onmouseover=className='submitON' onmouseout=className='submit' id=btn_NPromptButtons_no value='   NO   ' onclick=RestoreAllPageElements(s___NonDisableList);EmptyMessageArea(s___AreaID);" + sFunctionNo + " >";
	h+="</td>";
	h+="<td>&nbsp;</td>";
	h+="</tr>";
	h+="<tr><td colspan=3>&nbsp;</td></tr>";
	h+="</table><br>";
	PopulateMessageArea(h,sAreaID);
	//Set focus to the X button.
	document.getElementById("btn_NPromptButtons_x").focus();
	//Scroll a little bit up to make the whole frame of the window visible.
	window.scrollBy(0,-10);	
	DisableAllPageElements(s___NonDisableList);
}

// oct 18, 2007
// Creates a "prompt window" in the message area specified,
// with the specified buttons, and the buttons will call the specified function when they are clicked.
// All input,button,reset,submit,select elements are disabled and then
// set back to their previous state once a button is clicked.
// If the sNonDisableList (comma-delimited) contains element ids, these will not be disabled.
// If the oFocus is specified, this object will get the focus later.
// sMessage = message displayed
// sButtonText = comma-delimited button labels
// sButtonFunction = comma-delimited button functions to call when clicked
//function NPromptButtons(sMessage, sFunctionYes, sFunctionNo, sAreaID, sNonDisableList, oFocus)
function NPromptButtons(sMessage, sButtonText, sButtonFunction, sAreaID, sNonDisableList, oFocus)
{
	var h="";
	var n;
	var arrBText = sButtonText.split(",");
	var arrBFunction = sButtonFunction.split(",");
	s___AreaID=sAreaID; //Keep in page variable.
	s___NonDisableList=sNonDisableList; //Keep in page variable.
	s___ObjectFocus=oFocus; //Store the object to receive focus later.	
	h="<br><table class='BackgroundApplicationColor TableMainFileUpload' cellpadding=0 cellspacing=0 align=center border=0>"
	h+="<tr>";
	h+="<td colspan=2 class='rpt TextBackgroundApplicationColor' style='color:white;' align=left>&nbsp;&nbsp;<b>Application Prompt</b></td>";
	h+="<td class='TextBackgroundApplicationColor' align=right><input type=button class=submit onmouseover=className='submitON' onmouseout=className='submit' id=btn_NPromptButtons_x value=x onclick=RestoreAllPageElements(s___NonDisableList);EmptyMessageArea(s___AreaID); ></td>";
	h+="</tr>";	
	h+="<tr><td colspan=3>&nbsp;</td></tr>";
	h+="<tr>";
	h+="<td>&nbsp;</td>";
	h+="<td align='center' class='rpt'>";
	h+="&nbsp;&nbsp;<b>" + sMessage + "</b>";
	h+="</td>";
	h+="<td>&nbsp;</td>";
	h+="</tr>";
	h+="<tr><td colspan=3>&nbsp;</td></tr>";
	// Buttons
	h+="<tr><td colspan=3 align='center'>&nbsp;";
	for(n = 0; n < arrBText.length; n++)
	{
		h+= "<input type=button class=submit onmouseover=className='submitON' onmouseout=className='submit' id=_btn_NPromptButtons_" + n + " value='" + arrBText[n] + "' onclick=RestoreAllPageElements(s___NonDisableList);EmptyMessageArea(s___AreaID);" + arrBFunction[n] + " >";
		if(n < arrBText.length - 1) h+= "&nbsp;&nbsp;";
	}	
	h+= "&nbsp;</td></tr>";
	h+="<tr><td colspan=3>&nbsp;</td></tr>";
	h+="</table><br>";
	PopulateMessageArea(h,sAreaID);
	//Set focus to the X button.
	document.getElementById("btn_NPromptButtons_x").focus();
	//Scroll a little bit up to make the whole frame of the window visible.
	window.scrollBy(0,-10);	
	DisableAllPageElements(s___NonDisableList);
}

// oct 18, 2007
//Used after calling ASP Sub SetMessageArea(sAreaID)
//Disables all document elements such as input, combos, buttons.
//Preserves the previous state in arrAllInputElements[], arrAllSelectElements[],
//arrAllButtonElements[],arrAllSubmitElements[], arrAllResetElements[]
function DisableAllPageElements(sNonDisableList)
{
	var n;
	var arr=sNonDisableList.split(",");
	//Disable Input tags.
	var colE=document.getElementsByTagName("input");
	for(n=0;n<colE.length;n++)
	{
		if(colE[n].id.indexOf("btn_NPromptButtons")==-1)
		{
			if(!ItemExists(arr,colE[n].id))
			{
				arrAllInputElements[n]=colE[n].disabled;
				colE[n].disabled=true;
			}
		}
	}
	//Disable Select tags.
	colE=document.getElementsByTagName("select");
	for(n=0;n<colE.length;n++)
	{
		if(colE[n].id.indexOf("btn_NPromptButtons")==-1)
		{
			if(!ItemExists(arr,colE[n].id))
			{
				arrAllSelectElements[n]=colE[n].disabled;
				colE[n].disabled=true;
			}
		}
	}	
	//Disable Button tags.
	colE=document.getElementsByTagName("button");
	for(n=0;n<colE.length;n++)
	{
		if(colE[n].id.indexOf("btn_NPromptButtons")==-1)
		{
			if(!ItemExists(arr,colE[n].id))
			{
				arrAllButtonElements[n]=colE[n].disabled;
				colE[n].disabled=true;
			}
		}
	}
	//Disable Submit tags.
	colE=document.getElementsByTagName("submit");
	for(n=0;n<colE.length;n++)
	{
		if(colE[n].id.indexOf("btn_NPromptButtons")==-1)
		{
			if(!ItemExists(arr,colE[n].id))
			{
				arrAllSubmitElements[n]=colE[n].disabled;
				colE[n].disabled=true;
			}
		}
	}	
	//Disable Reset tags.
	colE=document.getElementsByTagName("reset");
	for(n=0;n<colE.length;n++)
	{
		if(colE[n].id.indexOf("btn_NPromptButtons")==-1)
		{
			if(!ItemExists(arr,colE[n].id))
			{
				arrAllResetElements[n]=colE[n].disabled;
				colE[n].disabled=true;
			}
		}
	}	
}

//Context Menu Functions
/*
feb 21, 2005
Creates menu with the passed options
oSource=element firing the oncontextmenu event
sMenuEntries=|-separated list of labels for each menu entry
sActions=|-separated list of actions to perform for each menu entry (functions to call)

Examples of how to send sActions parameter:
var q="'";
sActions="ViewDocRef(" +q+ strPath +q+ "," +q+ strDocID +q+ "," +q+ strRefPath +q+ ")";
This will execute:
ViewDocRef(strPath,strDocID,strRefPath);

*/
function DisplayContextMenu(oSource,sMenuEntries,sActions)
{
	var oMenu;
	var arrMenuEntries,arrActions; //Hold all the menu labels and actions.
	var h=""; //HTML for the oMenu
	var n; //loops
	var x,y; //Coords
	var q='"';
	try{window.clearTimeout(oContextMenuTimeout);} catch(e){}
	try
	{
		oMenu=document.getElementById("divContextMenu");
		//Remove menu if already present
		if(oMenu!=null)
		{
			document.body.removeChild(oMenu);
		}
		oMenu=document.createElement("div");
		oMenu.id="divContextMenu";
		document.body.appendChild(oMenu);
		//Build the HTML that goes inside the oMenu object
		arrMenuEntries=sMenuEntries.split("|");
		arrActions=sActions.split("|");
		if(arrMenuEntries.length>=0)
		{
			h+="<table class='BackgroundApplicationColor TableContextMenu TableMainFileUpload' style='cursor:pointer;cursor:hand' cellspacing=0 cellpadding=2>";
			for(n=0; n<arrMenuEntries.length; n++)
			{
				h+="<tr><td nowrap class='rpt BackgroundApplicationColor' ";
				h+="onmouseover='this.className=" + q + "rpt TextBackgroundApplicationColor" + q + "; try{window.clearTimeout(oContextMenuTimeout);} catch(e){}' ";
				h+="onmouseout='this.className=" + q + "rpt BackgroundApplicationColor" + q + "; StartRemoveContextMenuTimeout();' ";
				h+="onclick=" +q+ arrActions[n] + "; RemoveContextMenu();" +q+ " ";
				h+=">";
				h+="&nbsp;&nbsp;&nbsp;&nbsp;<b>" + arrMenuEntries[n] + "</b>&nbsp;&nbsp;&nbsp;&nbsp;";
				h+="</td></tr>";
			}
			h+="</table>";
		}
		oMenu.innerHTML=h;
		//Position the Context Menu in the exact place where the user right-clicked
		oMenu.style.position="absolute";
		x=event.clientX + document.body.scrollLeft;
		y=event.clientY + document.body.scrollTop;
		oMenu.style.left=x;
		oMenu.style.top=y;
		//Make the screen scroll if necessary so the whole menu shows
		if(document.body.clientHeight<event.clientY+oMenu.offsetHeight)
		{
			window.scrollBy(0,((event.clientY+oMenu.offsetHeight)-document.body.clientHeight));
		}
		window.setTimeout("StartRemoveContextMenuTimeout()",3000);
		try{event.cancelBubble=true;} catch(e){}
	}catch(e){}
}

//function DisplayContextMenu(oSource,sMenuEntries,sActions,sMenuAbilities)
//{
//	var oMenu;
//	var arrMenuEntries,arrActions,arrMenuAbilities; //Hold all the menu labels and actions.
//	var h=""; //HTML for the oMenu
//	var n; //loops
//	var x,y; //Coords
//	var q='"';
//	try{window.clearTimeout(oContextMenuTimeout);} catch(e){}
//	try
//	{
//		oMenu=document.getElementById("divContextMenu");
//		//Remove menu if already present
//		if(oMenu!=null)
//		{
//			document.body.removeChild(oMenu);
//		}
//		oMenu=document.createElement("div");
//		oMenu.id="divContextMenu";
//		document.body.appendChild(oMenu);
		//Build the HTML that goes inside the oMenu object
//		arrMenuEntries=sMenuEntries.split("|");
//		arrActions=sActions.split("|");
//		arrMenuAbilities=sMenuAbilities.split("|");
///		if(arrMenuEntries.length>=0)
//		{
///			h+="<table class='BackgroundApplicationColor TableContextMenu TableMainFileUpload' style='cursor:pointer;cursor:hand' cellspacing=0 cellpadding=2>";
//			for(n=0; n<arrMenuEntries.length; n++)
//			{
//				if (arrMenuAbilities[n]=="+"){
//				h+="<tr><td nowrap class='rpt BackgroundApplicationColor' ";
//				h+="onmouseover='this.className=" + q + "rpt TextBackgroundApplicationColor" + q + "; try{window.clearTimeout(oContextMenuTimeout);} catch(e){}' ";
//				h+="onmouseout='this.className=" + q + "rpt BackgroundApplicationColor" + q + "; StartRemoveContextMenuTimeout();' ";
//				h+="onclick=" +q+ arrActions[n] + "; RemoveContextMenu();" +q+ " ";
////				h+=">";
//				h+="&nbsp;&nbsp;&nbsp;&nbsp;<b>" + arrMenuEntries[n] + "</b>&nbsp;&nbsp;&nbsp;&nbsp;";
//				h+="</td></tr>";
//				}
//			}
//			h+="</table>";
//		}
//		oMenu.innerHTML=h;
////		//Position the Context Menu in the exact place where the user right-clicked
//		oMenu.style.position="absolute";
//		x=event.clientX + document.body.scrollLeft;
//		y=event.clientY + document.body.scrollTop;
//		oMenu.style.left=x;
//		oMenu.style.top=y;
		//Make the screen scroll if necessary so the whole menu shows
//		if(document.body.clientHeight<event.clientY+oMenu.offsetHeight)
//		{
//			window.scrollBy(0,((event.clientY+oMenu.offsetHeight)-document.body.clientHeight));
//		}
//		window.setTimeout("StartRemoveContextMenuTimeout()",2000);
//		try{event.cancelBubble=true;} catch(e){}
//	}catch(e){}
//}



//Starts the timeout to remove the Context Menu automatically
function StartRemoveContextMenuTimeout()
{
	try{window.clearTimeout(oContextMenuTimeout);} catch(e){}
	oContextMenuTimeout=window.setTimeout("RemoveContextMenu();",1000);
}

//Called from the Menu itself, to remove himself from the page
function RemoveContextMenu()
{
	var oMenu;
	try{window.clearTimeout(oContextMenuTimeout);} catch(e){}
	oMenu=document.getElementById("divContextMenu");
	if(oMenu!=null)
	{
		document.body.removeChild(oMenu);
	}	
}
//End of Context Menu Functions

//Oct 3, 2003
//Helper function returns TRUE if the string exists in the passed array
function ItemExists(arr,item)
{
	var n;
	//Check if arr is empty in which case return FALSE for it does not exist.
	if(arr.length==1)
		if(arr[0]=="") return false;
	for(n=0; n<arr.length; n++)
		if(arr[n]==item) return true;
	return false;
}

//Array functions

//May 7, 2004
//Returns a tokenized list from the array
function ArrayToString(arr,sToken)
{
	var n;
	var sAux="";
	for(n=0;n<arr.length;n++)
		sAux+=arr[n]+sToken;
	//Kill extra tokens
	if(sAux.charAt(sAux.length-1)==sToken)
		sAux=sAux.substring(0,sAux.length-1);
	return sAux;
}

//feb 24, 2005
//Returns true if the 2 passed token-separated strings contain the same tokens
//(no matter in what order)
function TokensAreSame(s1,s2,sSeparator)
{
	var a1=s1.split(sSeparator);
	var a2=s2.split(sSeparator)
	var s;
	var bFound;
	
	if(a1.length!=a2.length) return false;
	for(var n=0; n<a1.length; n++)
	{
		bFound=false;
		for(var i=0; i<a1.length; i++)
		{
			if(a1[n]==a2[i])
			{
				bFound=true;
				break;
			}
			
		}
		if(!bFound) return false;
	}
	return true;
}

//End of Array functions


// oct 18, 2007
//Used after calling ASP Sub SetMessageArea(sAreaID)
//Restores all elements state for input,reset,submit,select, except those
//specified in the comma-delimited sNonDisableList
function RestoreAllPageElements(sNonDisableList)
{
	var n;
	var arr=sNonDisableList.split(",");
	//Enable Input tags.
	var colE=document.getElementsByTagName("input");
	for(n=0;n<colE.length;n++)
	{
		if(colE[n].id.indexOf("btn_NPromptButtons")==-1)
			if(!ItemExists(arr,colE[n].id))
				colE[n].disabled=arrAllInputElements[n].disabled;
	}
	//Enable Select tags.
	colE=document.getElementsByTagName("select");
	for(n=0;n<colE.length;n++)
	{
		if(colE[n].id.indexOf("btn_NPromptButtons")==-1)
			if(!ItemExists(arr,colE[n].id))
				colE[n].disabled=arrAllSelectElements[n].disabled;
	}	
	//Enable Button tags.
	colE=document.getElementsByTagName("button");
	for(n=0;n<colE.length;n++)
	{
		if(colE[n].id.indexOf("btn_NPromptButtons")==-1)
			if(!ItemExists(arr,colE[n].id))
				colE[n].disabled=arrAllButtonElements[n].disabled;
	}
	//Enable Submit tags.
	colE=document.getElementsByTagName("submit");
	for(n=0;n<colE.length;n++)
	{
		if(colE[n].id.indexOf("btn_NPromptButtons")==-1)
			if(!ItemExists(arr,colE[n].id))
				colE[n].disabled=arrAllSubmitElements[n].disabled;
	}	
	//Enable Reset tags.
	colE=document.getElementsByTagName("reset");
	for(n=0;n<colE.length;n++)
	{
		if(colE[n].id.indexOf("btn_NPromptButtons")==-1)
			if(!ItemExists(arr,colE[n].id))
				colE[n].disabled=arrAllResetElements[n].disabled;
	}
	//Tries to set focus to the object specified in the global variable
	try{s___ObjectFocus.focus();} catch(e){}
}

//Sep 30, 2003
//Cleans the message area
function EmptyMessageArea(sAreaID)
{
	try
	{
		obj=document.getElementById(sAreaID);
		obj.innerHTML="";
	}
	catch(e){}
}

//August 27, 2004
//Replaces images, rollovers, etc.
function ReplaceImage(sImgName,sImgFile, action)
{
	try
	{
		document.images[sImgName].src = sImgFile;
	}catch(e){}
}

//feb 14, 2005
//Sets the readOnly and backgroundColor attributes
function SetReadOnlyBackgroundColor(obj,bReadonly,sBackgroundColor)
{
	obj.readOnly=bReadonly;
	obj.style.backgroundColor=sBackgroundColor
}

//Popup windows
//Creates a popup to tell user to wait while the files are uploaded
function ShowWaitPopup()
{
	var oPopupBody=oPopup.document.body;
	oPopupBody.style.border="solid black 2px";
	oPopupBody.style.backgroundColor="#FFE000";      /*yellow*/
	h="<table bgcolor='#FFE000' width='100%' height='100%'>";
	h+="<tr>";
	h+="<td align='center'>";
	h+="<b>Please wait while the files are being uploaded...</b><br><br>";
	h+="<input type='button' value='Click to close this window' onclick='parent.ClosePopup()'>";
	h+="</td>";
	h+="</tr>";
	h+="</table>";
	oPopupBody.innerHTML=h;
	tOut=window.setTimeout("KeepPopupAlive()",10);
}
function KeepPopupAlive()
{
	var h;
	var x,y, w, h;
	w=400; //Popup width
	h=200; //Popup height
	x=window.screen.availWidth;
	y=window.screen.availHeight;
	x=(x/2)-(w/2);
	y=(y/2)-(h/2);
	oPopup.show(x,y,w,h);
	//oPopup.show(0,0,w,h);
	tOut=window.setTimeout("KeepPopupAlive()",1);
}
//Closes the popup and prevents it from opening again.
function ClosePopup()
{
	try
	{
		window.clearTimeout(tOut);
		oPopup.hide();
	}catch(e){}
}
//End of Popup windows

//File validations
//Validate the file name, returns TRUE if it is valid, FALSE otherwise.
function ValidFileName(sFileName,sInvalid)
{
	var n,i;
	var cName,cInv;
	var q='"';
	
	sInvalid+=q;
	
	for(n=0; n<sFileName.length; n++)
	{
		cName=sFileName.charAt(n);
		for(i=0; i<sInvalid.length; i++)
		{
			cInv=sInvalid.charAt(i);
			if(cName==cInv)
				return false;
		}
	}
	//Valid filename
	return true;
}

//feb 2, 2006
//Returns the file name from the path
function GetFileNameFromPath(sPath)
{
	var iPos = sPath.lastIndexOf("\\");
	if(iPos==-1) return sPath;
	return sPath.substring(iPos+1);
}

//feb 2, 2006
//Validates the full file path
function FilePathIsValid(sFilepath)
{
	var iPos = sFilepath.length;
	if(iPos < 1) return false;
	var s = sFilepath.substring(iPos - 1, iPos);
	if(s == "\\" || s == "//") return false;
	if(ValidateExcluding(sFilepath, "\\")) return false;
	if(sFilepath.indexOf("\\\\") != -1) return false;
	return true;
}

//End of file validations

//General validations
//If nothing from sExcluding is present in sString, it returns TRUE.
function ValidateExcluding(sString,sExcluding)
{
	var n,x;
	for(n=0;n<sString.length;n++)
	{
		for(x=0;x<sExcluding.length;x++)
			if(sString.charAt(n)==sExcluding.charAt(x)) return false;
	}
	return true;
}
//If every value in sString exists in sExcluding, it returns TRUE.
function ValidateIncluding(sString,sExcluding)
{
	var n,x,bFoundl
	for(n=0;n<sString.length;n++)
	{
		bFound=false;
		for(x=0;x<s.sExcluding;x++)
			if(sString.charAt(n)==s.charAt(x)) bFound=true;
		if(!bFound) return false;
	}
	return true;
}

//Validates numeric values.
function IsValidPositiveInteger(sValue)
{
	var s="0123456789";
	var n,x,bFound;
	for(n=0;n<sValue.length;n++)
	{
		bFound=false;
		for(x=0;x<s.length;x++)
			if(sValue.charAt(n)==s.charAt(x)) bFound=true;
		if(!bFound) return false; //Invalid value
	}
	return true; //Valid value
}

//Validates SQL compliant values.
function IsValidSQL(sValue)
{
	var inv="';";
	return ValidateExcluding(sValue,inv);
}

//Validates HTML safe values
function IsSafeHTML(sValue)
{
	var sStr=sValue + "";
	sStr=sStr.toLowerCase();
	//if(sStr.indexOf("<script")!=-1) return false; //Unsafe HTML!
	//if(sStr.indexOf("</script")!=-1) return false; //Unsafe HTML!
	if(sStr.indexOf("<")!=-1) return false; //Unsafe HTML!
	if(sStr.indexOf(">")!=-1) return false; //Unsafe HTML!
	return true; //Safe HTML
}

//Returns the count of the specified character in the passed string (CASE SENSITIVE!!!)
function GetCountOfCharInString(sSource,sChar)
{
	var i=0;
	for(var n=0; n<sSource; n++)
		if(sSource.charAt(n)==sChar) i++;
	return i;
}

//jul 18, 2005
//Returns the count of distinct items separated by the token
function CountDistinctItems(sList, sToken)
{
	if(sList=="") return 0;
	var arr=sList.split(sToken);
	var sNew=sToken;
	
	for(var n=0; n<arr.length; n++)
	{
		if(sNew.indexOf(sToken + arr[n] + sToken)==-1)
		{
			sNew+=arr[n] + sToken;
		}
	}
	if(sNew=="") return 0;
	//Remove first and last ","
	sNew=sNew.substr(1);
	sNew=sNew.substr(0,sNew.length - 1);
	arr=sNew.split(sToken);
	return arr.length;
}

//jul 4, 2005
//Returns the passed string stripped of blank spaces at both ends
function Trim(s)
{
	if(s.length<1) return "";
	return ltrim(rtrim(s));	
}

//jul 4, 2005
//Returns the passed string left trimmed
function ltrim(s)
{
	var bFlag=false;
	if(s.length<1) return "";
	for(var n=0; n<s.length; n++)
		if(s.charAt(n)!=" ")
		{
			bFlag=true;
			break;
		}
	if(!bFlag) return "";
	var lpatt=new RegExp( "^ *(.*)$" );
	var parse=s.match(lpatt);
	return parse[1];
}

//jul 4, 2005
//Returns the passed string right trimmed
function rtrim(s)
{
	var bFlag=false;
	if(s.length<1) return "";
	for(var n=0; n<s.length; n++)
		if(s.charAt(n)!=" ")
		{
			bFlag=true;
			break;
		}
	if(!bFlag) return "";
	if(s.length<1) return "";
	var rpatt=new RegExp( "^(.*[^ ]) *$" );
	var parse=s.match(rpatt);
	return parse[1];
}

//feb 6, 2007
//Find and replace method for the string object
String.prototype.findAndReplace = function(sFind, sReplace)
{
	return this.replace(new RegExp(sFind, "g"), sReplace);
}



//CHECKBOXES chk

//sep 28, 2006
//Returns the count of checked checkboxes of the specified attribute name and attribute value
function GetChkCount(attrName, attrValue)
{
	var oCol = document.getElementsByTagName("input");
	var count = 0;
	var obj;
	for(var n = 0; n < oCol.length; n++)
	{
		eval("obj = oCol[n]." + attrName);
		if(obj == attrValue && oCol[n].checked) count++;
	}
	return count;
}

// mar 17, 2008
// Returns the count of checkboxes of the specified attribute name and attribute value,
// whether they are checked or not (total count)
function GetAttrChkCount(attrName, attrValue)
{
	var oCol = document.getElementsByTagName("input");
	var count = 0;
	var obj;
	for(var n = 0; n < oCol.length; n++)
	{
		eval("obj = oCol[n]." + attrName);
		if(obj == attrValue) count++;
	}
	return count;
}

//sep 28, 2006
//Returns comma-delimited list of values for valueAttrName of CHECKED checkboxes of the specified attribute name and attribute value
//Returns "" if nothing found
function GetChkAttrValues(attrName, attrValue, valueAttrName)
{
	var oCol = document.getElementsByTagName("input");
	var list = "";
	var obj;
	for(var n = 0; n < oCol.length; n++)
	{
		eval("obj = oCol[n]." + attrName);
		if(obj == attrValue && oCol[n].checked)
		{
			if(list != "") list += ",";
			eval("obj = oCol[n]." + valueAttrName);
			list += obj;
		}
	}
	return list;
}

//COMBO BOXES cbo DROPDOWNS

//Makes the item with value property=sValue selected.
//If it does not find it, it tries also the text property.
function SelectItemInComboBox(cbo,sValue)
{
	var n;
	//Try value property first.
	for(n=0; n<cbo.length; n++)
		if(cbo.item(n).value==sValue)
		{
			cbo.selectedIndex=n;
			return;
		}
	//Try the text property now.
	for(n=0; n<cbo.length; n++)
		if(cbo.item(n).text==sValue)
		{
			cbo.selectedIndex=n;
			return;
		}		
}

//Returns comma-delimited list of the specified attribute for the specified combo box
function GetListOfCBOAttribute(cbo,sAttribute)
{
	var s="";
	var n;
	for(n=0;n<cbo.length;n++)
	{
		eval("s+=cbo.item(n)." + sAttribute + ";");
		if(n<cbo.length-1) s+=",";
	}
	return s;
}

//sep 20, 2004
//Returns true if the item exists in the text field of the combo box
//Case insensitive
function ItemExistsInCBO(cbo,sItem)
{
	var s=sItem.toUpperCase();
	for(var n=0;n<cbo.length;n++)
		if(cbo.item(n).text.toUpperCase()==s) return true;
	return false;
}

//sep 21, 2004
//Returns true if the value exists in the value field of the combo box
function ValueExistsInCBO(cbo,sValue)
{
	for(var n=0;n<cbo.length;n++)
		if(cbo.item(n).value==sValue) return true;
	return false;
}

//sep 21, 2004
//Gets the item index by the passed attribute
//Returns -1 if not found
function GetItemIndexInCBO(cbo,sItemValue,sAttribute)
{
	var n,s
	
	for(n=0;n<cbo.length;n++)
	{
		eval("s=cbo.item(n)." + sAttribute + ";");
		if(s==sItemValue) return n; //Returns the index
	}
	return -1; //not found
}

//jul 27, 2006
//Copies the specified item(s) from one combo box to another
//The oFrom combo box must have at least one item already selected.
function CopyCBOItem(oFrom, oTo)
{
	if(oFrom.selectedIndex < 0) return;
	var n;
	var option
	for(n = 0; n < oFrom.length; n++)
	{
		if(oFrom.item(n).selected)
		{
			option = document.createElement("option");
			oTo.add(option);
			option.value = oFrom.item(n).value;
			option.text = oFrom.item(n).text;
		}
	}
}

//aug 21, 2006
//Copies the selected item(s) from one combo to another,
//including ALL attributes
//Removes the original item(s) if specified 
function MoveCBOItemWithAttributes(oFrom, oTo, bRemove)
{
	if(oFrom.selectedIndex == -1) return;
	CopyCBOItem(oFrom, oTo);
	var i;
	for(var n = 0; n < oFrom.length; n++)
	{
		if(oFrom.item(n).selected)
		{
			//Get index of destination item
			i = oTo.length - 1;
			CopyAttributes(oFrom.item(n), oTo.item(i));
		}
	}
	//Remove if needed
	if(bRemove)
	{
		while(CountCBOSelectedItems(oFrom) > 0)
		{
			for(var n = 0; n < oFrom.length; n++)
			{
				if(oFrom.item(n).selected) oFrom.remove(n);
			}
		}
	}
}

//jul 27, 2006
//Returns the count of selected items, 0 if nothing selected
function CountCBOSelectedItems(cbo)
{
	var c = 0;
	for(var n = 0; n < cbo.length; n++)
	{
		if(cbo.item(n).selected) c++;
	}
	return c;
}

//sep 21, 2004
//Delete all the option objects with the specified value.
function DeleteOptionByValue(cbo,sValue)
{
	for(var n=0;n<cbo.length;n++)
		if(cbo.item(n).value==sValue) cbo.remove(n);
}

//sep 22, 2004
//Sorts a combo box alphabetically by text attribute
function SortCBO(cbo)
{
	var oPrev,oActual;
	var bSwapped=false;
	while(true)
	{
		bSwapped=false;
		for(n=1;n<cbo.length;n++)
		{
			oPrev=cbo.item(n-1);
			oActual=cbo.item(n);
			if(oPrev.text>oActual.text)
			{
				//Swap
				bSwapped=true;
				SwapOptionsCBO(cbo,oPrev,oActual);
			}
		}
		if(!bSwapped) break; //No swapping occurred, finished.
	}
}

//sep 22, 2004
//Swaps the opt1 and opt2 in the cbo combo box
//opt1 is placed AFTER opt2
function SwapOptionsCBO(cbo,opt1,opt2)
{
	var sPreserve=opt1.innerHTML;
	var oNew=document.createElement("option");
	
	cbo.add(oNew,opt2.index+1);
	oNew.innerHTML=sPreserve;
	CopyAttributes(opt1,oNew)
	opt1.removeNode(true);
}

//sep 22, 2004
//Copies the whole attribute collection from one object to another
function CopyAttributes(oSource,oDest)
{
	var oColl=oSource.attributes;
	for(var n=0;n<oColl.length;n++)
	{
		oDest.setAttribute(oColl[n].nodeName,oColl[n].nodeValue);
	}
}

//End of COMBO BOXES cbo DROPDOWNS

//Hide / Show elements or group of elements

//oct 11, 2006
//sets the display.style of ALL elements of specified attribute with specified value
//bCheckWholeValue default = true
//Example: SetDisplayOfElements("tr", "japiType", "fileid_445", "inline");
function SetDisplayOfElements(sTag, sAttrName, sAttrValue, sDisplay, bCheckWholeValue)
{
	var bCheck = false;
	bCheck = bCheckWholeValue;
	if(bCheckWholeValue == null) bCheck = true;
	var oCol = document.getElementsByTagName(sTag);
	var attrValue;
	for(var n = 0; n < oCol.length; n++)
	{
		try
		{
			attrValue = oCol[n].getAttribute(sAttrName);
			if(bCheckWholeValue)
			{
				if(attrValue == sAttrValue)
					oCol[n].style.display = sDisplay;
			}
			else
			{
				if(attrValue.indexOf(sAttrValue) == 0)
					oCol[n].style.display = sDisplay;
			}
		}catch(e){}
	}
}

//End of Hide / Show elements or group of elements

//Checks email, returns FALSE if it does not seem valid.
function CheckEmail(email)
{
	if (window.RegExp)
	{
		filterstr1 = "(@.*@)|(\\.\\.)|(@\\.)|(\\.@)|(^\\.)";
		filterstr2 = "^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$";
		filter1 = new RegExp(filterstr1);
		filter2 = new RegExp(filterstr2);
		if (!filter1.test(email) && filter2.test(email)) return true;
		return false;
	}
	else
	{
		if (email.indexOf("@") >= 0)return true;
		return false;
	}
}

//End of General validations

//Transform text

//Returns a string with carriage returns replaced by "<br>"
function ConvertCRToHTML(sString)
{
	return sString.replace(/\n/gi,"<br>");
}

//Returns a string unsafe SQL characters such as single-quote, from "`"
function GetUnsafeSQLString(sString)
{
	return sString.replace(/`/gi,"'");
}
//End of Transform text

//Start of Getting parts of text strings

//Returns the text in position iPos, using sSearch as position marker.
//The first position is 0.
//For example in this text: "20%,34px,abc,345"
//sSearch could be "," and iPos=0 would return 20%
function GetToken(sFrom,sSearch,iPos)
{  
	if(sFrom.length<1) return "";
	var splitString = sFrom.split(sSearch);
	if(splitString[iPos]!=null) return(splitString[iPos]);
	else return "";
}

//sep 22, 2005
//Moves the nStart item to the top of the array [0]
//Moves everything else one position up the array
function MoveItemArrayTop(arr, nPos)
{
	var s=arr[nPos];
	for(var n=0; n<arr.length; n++)
	{
		if(n!=nPos)
		{
			if(s!="") s+=",";
			s+=arr[n];
		}
	}
	s=s.split(",");
	for(n=0; n<arr.length; n++)
		arr[n]=s[n];
}

//sep 23, 2005
//Alerts when the text object goes over the maximum characters, does not allow further typing
function CheckTyping(txt, iMax)
{
	if(txt.value.length>iMax)
	{
		alert("You have exceeded the maximum of " + iMax + " characters.");
		txt.value=txt.value.substr(0,iMax);
		return;
	}
}

//End of Getting parts of text strings

//Detection functions
//Returns true if the OS is XP
function OSIsXP()
{
	var s=navigator.userAgent.toUpperCase();
	var i=s.indexOf("WINDOWS NT 5.");
	if(i==-1) return false;
	s=s.substring(i,i+16);
	i=s.indexOf(".");
	s=s.charAt(i+1);
	i=parseInt(s);
	if(i<1) return false;
	return true;
}
//End of Detection functions

//Date functions

// ------------------------------------------------------------------
// These functions use the same 'format' strings as the 
// java.text.SimpleDateFormat class, with minor exceptions.
// The format string consists of the following abbreviations:
// 
// Field        | Full Form          | Short Form
// -------------+--------------------+-----------------------
// Year         | yyyy (4 digits)    | yy (2 digits), y (2 or 4 digits)
// Month        | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
//              | NNN (abbr.)        |
// Day of Month | dd (2 digits)      | d (1 or 2 digits)
// Day of Week  | EE (name)          | E (abbr)
// Hour (1-12)  | hh (2 digits)      | h (1 or 2 digits)
// Hour (0-23)  | HH (2 digits)      | H (1 or 2 digits)
// Hour (0-11)  | KK (2 digits)      | K (1 or 2 digits)
// Hour (1-24)  | kk (2 digits)      | k (1 or 2 digits)
// Minute       | mm (2 digits)      | m (1 or 2 digits)
// Second       | ss (2 digits)      | s (1 or 2 digits)
// AM/PM        | a                  |
//
// NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm!
// Examples:
//  "MMM d, y" matches: January 01, 2000
//                      Dec 1, 1900
//                      Nov 20, 00
//  "M/d/yy"   matches: 01/20/00
//                      9/2/00
//  "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
// ------------------------------------------------------------------

var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
function LZ(x) {return(x<0||x>9?"":"0")+x}

// ------------------------------------------------------------------
// isDate ( date_string, format_string )
// Returns true if date string matches format of format string and
// is a valid date. Else returns false.
// It is recommended that you trim whitespace around the value before
// passing it to this function, as whitespace is NOT ignored!
// ------------------------------------------------------------------
function isDate(val,format) {
	var date=getDateFromFormat(val,format);
	if (date==0) { return false; }
	return true;
	}

// -------------------------------------------------------------------
// compareDates(date1,date1format,date2,date2format)
//   Compare two date strings to see which is greater.
//   Returns:
//   1 if date1 is greater than date2
//   0 if date2 is greater than date1 of if they are the same
//  -1 if either of the dates is in an invalid format
// -------------------------------------------------------------------
function compareDates(date1,dateformat1,date2,dateformat2) {
	var d1=getDateFromFormat(date1,dateformat1);
	var d2=getDateFromFormat(date2,dateformat2);
	if (d1==0 || d2==0) {
		return -1;
		}
	else if (d1 > d2) {
		return 1;
		}
	return 0;
	}

// ------------------------------------------------------------------
// formatDate (date_object, format)
// Returns a date in the output format specified.
// The format string uses the same abbreviations as in getDateFromFormat()
// ------------------------------------------------------------------
function formatDate(date,format) {
	format=format+"";
	var result="";
	var i_format=0;
	var c="";
	var token="";
	var y=date.getYear()+"";
	var M=date.getMonth()+1;
	var d=date.getDate();
	var E=date.getDay();
	var H=date.getHours();
	var m=date.getMinutes();
	var s=date.getSeconds();
	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
	// Convert real date parts into formatted versions
	var value=new Object();
	if (y.length < 4) {y=""+(y-0+1900);}
	value["y"]=""+y;
	value["yyyy"]=y;
	value["yy"]=y.substring(2,4);
	value["M"]=M;
	value["MM"]=LZ(M);
	value["MMM"]=MONTH_NAMES[M-1];
	value["NNN"]=MONTH_NAMES[M+11];
	value["d"]=d;
	value["dd"]=LZ(d);
	value["E"]=DAY_NAMES[E+7];
	value["EE"]=DAY_NAMES[E];
	value["H"]=H;
	value["HH"]=LZ(H);
	if (H==0){value["h"]=12;}
	else if (H>12){value["h"]=H-12;}
	else {value["h"]=H;}
	value["hh"]=LZ(value["h"]);
	if (H>11){value["K"]=H-12;} else {value["K"]=H;}
	value["k"]=H+1;
	value["KK"]=LZ(value["K"]);
	value["kk"]=LZ(value["k"]);
	if (H > 11) { value["a"]="PM"; }
	else { value["a"]="AM"; }
	value["m"]=m;
	value["mm"]=LZ(m);
	value["s"]=s;
	value["ss"]=LZ(s);
	while (i_format < format.length) {
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		if (value[token] != null) { result=result + value[token]; }
		else { result=result + token; }
		}
	return result;
	}
	
// ------------------------------------------------------------------
// Utility functions for parsing in getDateFromFormat()
// ------------------------------------------------------------------
function _isInteger(val) {
	var digits="1234567890";
	for (var i=0; i < val.length; i++) {
		if (digits.indexOf(val.charAt(i))==-1) { return false; }
		}
	return true;
	}
function _getInt(str,i,minlength,maxlength) {
	for (var x=maxlength; x>=minlength; x--) {
		var token=str.substring(i,i+x);
		if (token.length < minlength) { return null; }
		if (_isInteger(token)) { return token; }
		}
	return null;
	}
	
// ------------------------------------------------------------------
// getDateFromFormat( date_string , format_string )
//
// This function takes a date string and a format string. It matches
// If the date string matches the format string, it returns the 
// getTime() of the date. If it does not match, it returns 0.
// ------------------------------------------------------------------
function getDateFromFormat(val,format) {
	val=val+"";
	format=format+"";
	var i_val=0;
	var i_format=0;
	var c="";
	var token="";
	var token2="";
	var x,y;
	var now=new Date();
	var year=now.getYear();
	var month=now.getMonth()+1;
	var date=1;
	var hh=now.getHours();
	var mm=now.getMinutes();
	var ss=now.getSeconds();
	var ampm="";
	
	while (i_format < format.length) {
		// Get next token from format string
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		// Extract contents of value based on format token
		if (token=="yyyy" || token=="yy" || token=="y") {
			if (token=="yyyy") { x=4;y=4; }
			if (token=="yy")   { x=2;y=2; }
			if (token=="y")    { x=2;y=4; }
			year=_getInt(val,i_val,x,y);
			if (year==null) { return 0; }
			i_val += year.length;
			if (year.length==2) {
				if (year > 70) { year=1900+(year-0); }
				else { year=2000+(year-0); }
				}
			}
		else if (token=="MMM"||token=="NNN"){
			month=0;
			for (var i=0; i<MONTH_NAMES.length; i++) {
				var month_name=MONTH_NAMES[i];
				if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
					if (token=="MMM"||(token=="NNN"&&i>11)) {
						month=i+1;
						if (month>12) { month -= 12; }
						i_val += month_name.length;
						break;
						}
					}
				}
			if ((month < 1)||(month>12)){return 0;}
			}
		else if (token=="EE"||token=="E"){
			for (var i=0; i<DAY_NAMES.length; i++) {
				var day_name=DAY_NAMES[i];
				if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
					i_val += day_name.length;
					break;
					}
				}
			}
		else if (token=="MM"||token=="M") {
			month=_getInt(val,i_val,token.length,2);
			if(month==null||(month<1)||(month>12)){return 0;}
			i_val+=month.length;}
		else if (token=="dd"||token=="d") {
			date=_getInt(val,i_val,token.length,2);
			if(date==null||(date<1)||(date>31)){return 0;}
			i_val+=date.length;}
		else if (token=="hh"||token=="h") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>12)){return 0;}
			i_val+=hh.length;}
		else if (token=="HH"||token=="H") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>23)){return 0;}
			i_val+=hh.length;}
		else if (token=="KK"||token=="K") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>11)){return 0;}
			i_val+=hh.length;}
		else if (token=="kk"||token=="k") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>24)){return 0;}
			i_val+=hh.length;hh--;}
		else if (token=="mm"||token=="m") {
			mm=_getInt(val,i_val,token.length,2);
			if(mm==null||(mm<0)||(mm>59)){return 0;}
			i_val+=mm.length;}
		else if (token=="ss"||token=="s") {
			ss=_getInt(val,i_val,token.length,2);
			if(ss==null||(ss<0)||(ss>59)){return 0;}
			i_val+=ss.length;}
		else if (token=="a") {
			if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
			else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
			else {return 0;}
			i_val+=2;}
		else {
			if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
			else {i_val+=token.length;}
			}
		}
	// If there are any trailing characters left in the value, it doesn't match
	if (i_val != val.length) { return 0; }
	// Is date valid for month?
	if (month==2) {
		// Check for leap year
		if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
			if (date > 29){ return 0; }
			}
		else { if (date > 28) { return 0; } }
		}
	if ((month==4)||(month==6)||(month==9)||(month==11)) {
		if (date > 30) { return 0; }
		}
	// Correct hours value
	if (hh<12 && ampm=="PM") { hh=hh-0+12; }
	else if (hh>11 && ampm=="AM") { hh-=12; }
	var newdate=new Date(year,month-1,date,hh,mm,ss);
	return newdate.getTime();
	}

// ------------------------------------------------------------------
// parseDate( date_string [, prefer_euro_format] )
//
// This function takes a date string and tries to match it to a
// number of possible date formats to get the value. It will try to
// match against the following international formats, in this order:
// y-M-d   MMM d, y   MMM d,y   y-MMM-d   d-MMM-y  MMM d
// M/d/y   M-d-y      M.d.y     MMM-d     M/d      M-d
// d/M/y   d-M-y      d.M.y     d-MMM     d/M      d-M
// A second argument may be passed to instruct the method to search
// for formats like d/M/y (european format) before M/d/y (American).
// Returns a Date object or null if no patterns match.
// ------------------------------------------------------------------
function parseDate(val) {
	var preferEuro=(arguments.length==2)?arguments[1]:false;
	generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');
	monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');
	dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');
	var checkList=new Array('generalFormats',preferEuro?'dateFirst':'monthFirst',preferEuro?'monthFirst':'dateFirst');
	var d=null;
	for (var i=0; i<checkList.length; i++) {
		var l=window[checkList[i]];
		for (var j=0; j<l.length; j++) {
			d=getDateFromFormat(val,l[j]);
			if (d!=0) { return new Date(d); }
			}
		}
	return null;
	}



//End of Date functions