// Date Entry Masking Library
// Last Updated: 5-16-05
// Last Updated by: Jeff Bramlett
//
// Description:
// Provides character masking functions
//
// Notes:
//

//  Mask Codes
var MASK_ALPHA = 1;
var MASK_SMALLCURRENCY = 3;
var MASK_CURRENCY = 2;
var MASK_PERCENT = 4;
var MASK_NUMERIC = 5;
var MASK_NUMBERONLY = 15;
var MASK_PHONE = 6;
var MASK_SMALLPHONE = 7;

//  Code Filters
var CODEFILTER_NAV = 1;
var CODEFILTER_NUMBERS = 2;
var CODEFILTER_DECIMAL = 4; 
var CODEFILTER_HYPHEN = 8;
var CODEFILTER_LETTERS = 16;
var CODEFILTER_SPACE = 32;
var CODEFILTER_DELBKSP = 64;

//Date Formats
var FORMAT_MM_DD_YYYY = 1;
var FORMAT_MMM_DD_YYYY = 2;

//Popup Calendar Units
var UNITS_MONTH = 1;
var UNITS_YEAR = 12;

//Style used in building Calendars
var STYLE_CALHEADER = "tdCalendarTitle";
var STYLE_CALDAY = "tdCalDay1";
var STYLE_TODAY = "tdCalToday";
var STYLE_CURRENTDATE = "tdCalendarTitle";
var STYLE_CALTABLE = "tdCalendarBody";

//Event Names
var EVENTS_ONCLICK = "onclick";

//Member Vars and Objects
var m_oOrigDate = null; //Global to Store Origingal Date
var m_sOrigTime; //Global to Store Origingal Time
var m_oTheFormElement = null; //Set as te current form element (input the date or time go to)
var m = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");

var m_oCalPopup = null;
var m_oTimePopup = null;
	

//Mask Functions

//ValidateKey Function - Called on event "keydown" it test for a valid key code based on the nCodeFilter
// and retuns a true if allowed or false if not.
//ffEvent, an event object, must be passed in order to make this function work on firefox
function ValidateKey(oFormEle, nCodeFilter, ffEvent){ //1 Nav(Tab, enter, arrows, etc.), 2 Numbers, 4 decimal, 8 hypen, 16 letters, 32 space

	//var nKeyCode = event.keyCode;
	var nKeyCode = window.event ? event.keyCode : ffEvent.which;
	var sFormEleValue = oFormEle.value;
	
	if((nCodeFilter & CODEFILTER_NAV) == CODEFILTER_NAV){
		if(
			(nKeyCode == 9) || // Tab
			(nKeyCode == 13) || // Return
			(nKeyCode == 16) || // Shift
			(nKeyCode >= 37 && nKeyCode <= 40) || //Arrows
			(nKeyCode == 45) || //
			(nKeyCode >= 112 && nKeyCode <= 123) //Function Keys
		   ) 
		  return true;
	}
	if((nCodeFilter & CODEFILTER_DELBKSP) == CODEFILTER_DELBKSP){ 
		if((
			(nKeyCode == 8) || // Delete
			(nKeyCode == 46) // Backspace
		   )) 
		  return true;
	}
	if((nCodeFilter & CODEFILTER_NUMBERS) == CODEFILTER_NUMBERS){ 
		if( ( (nKeyCode >= 48 && nKeyCode <= 57) || (nKeyCode >= 96 && nKeyCode <= 105) ) && !(window.event ? event.shiftKey : ffEvent.shiftKey) )//Numbers
		
			return true;
	}
	if((nCodeFilter & CODEFILTER_DECIMAL) == CODEFILTER_DECIMAL){ 
		if((nKeyCode == 110 || nKeyCode == 190) && sFormEleValue.search(/\./) < 0)//Decimal
			return true ;
	}
	if((nCodeFilter & CODEFILTER_HYPHEN) == CODEFILTER_HYPHEN){
		if(nKeyCode == 109 || nKeyCode == 189){//Hypen
			oFormEle.value = oFormEle.value.replace(/^.*-.*/gi, "-");
			return true;
		}
	}
	if((nCodeFilter & CODEFILTER_LETTERS) == CODEFILTER_LETTERS){
		if(nKeyCode >= 65 && nKeyCode <= 90) //Letters
			return true;
	}
	if((nCodeFilter & CODEFILTER_SPACE) == CODEFILTER_SPACE){
		if(nKeyCode == 32) //Space
			return true;
	}
	return false; // Return false when key code not in above list
}

//FormatValue Function - Called on event "keyup" it pre and post processes the oFormEle based on the sMask and calles the FormatString function.
//ffEvent, an event object, must be passed in order to make this function work on firefox
function FormatValue(oFormEle, sMask, iPrecision, ffEvent){
	var nKeyCode = window.event ? event.keyCode : ffEvent.which;

	switch (sMask){
		case MASK_ALPHA:
			StripElementToAlpha(oFormEle);
			break; // case MASK_ALPHA
		case MASK_NUMERIC:
			StripElementToNumber(oFormEle, iPrecision);
			break;
		case MASK_CURRENCY:
			FormatToCurrency(oFormEle);
			break;
		case MASK_SMALLCURRENCY:
			FormatToCurrency(oFormEle, iPrecision);
			break;
		case MASK_PERCENT:
			if(ValidateKey(oFormEle, CODEFILTER_NUMBERS + CODEFILTER_DECIMAL + CODEFILTER_HYPHEN + CODEFILTER_DELBKSP, ffEvent) || nKeyCode == 0){ //Test if keycode is a Number
				//Clean up non-numbers
				var sNumberStr = new String(oFormEle.value.replace(/[\$%,]/ig,"")); //Clean out Dollar Sign, Commas and Percent Sign then  set RealValue Attribute
			
				//Set RealValue
				if(sMask == MASK_PERCENT && sNumberStr != ""){
					var nValue = new Number(sNumberStr) * 0.01;
					oFormEle.RealValue = nValue.toString();				
				}
				else{
					oFormEle.RealValue = sNumberStr;
				}
				
				//Call FormatString				
				oFormEle.value = FormatString(sNumberStr, sMask)
				
				//Add % sign and move cursor in front of it
				if(sMask == MASK_PERCENT && oFormEle.value != ""){ // For MASK_PERCENT Only
				//Add % sign and move cursor in front of it
					var oRange = oFormEle.createTextRange ( );
					oRange.moveStart("character", oFormEle.value.length - 1);
					oRange.moveEnd("character", -1);
					oRange.select();
				}
			}	
			break;// case MASK_NUMERIC, MASK_CURRENCY, MASK_SMALLCURRENCY, MASK_PERCENT
		
		case MASK_NUMBERONLY: //When you want only whole number data(i.e without decimals or hiphens)
			if(ValidateKey(oFormEle, CODEFILTER_NUMBERS + CODEFILTER_DELBKSP, ffEvent) || nKeyCode == 0){ //Test if keycode is a Number
				//Clean up non-numbers
				var sNumberStr = new String(oFormEle.value.replace(/[\$%,]/ig,"")); //Clean out Dollar Sign, Commas and Percent Sign then  set RealValue Attribute

				oFormEle.RealValue = sNumberStr;
				
				//Call FormatString				
				oFormEle.value = FormatString(sNumberStr, sMask)
			}
			break;
		
		case MASK_PHONE:
			if(ValidateKey(oFormEle, CODEFILTER_NUMBERS, ffEvent)){ //Only reformat if a number 
				var sPhoneStr = new String(oFormEle.value.replace(/[\D]/ig,"")); //Clean out hyphen and parens
				var sNewPhoneString = sPhoneStr;
				if(sPhoneStr.length > 2){ //add area code parens
					sNewPhoneString = "(" + sPhoneStr.substr(0,3) + ") " + sPhoneStr.substr(3);
				}
				if(sPhoneStr.length > 5){ //add hyphen
					sNewPhoneString = sNewPhoneString.substr(0,6) + sPhoneStr.substr(3,3) + "-" + sPhoneStr.substr(6);
				}
				if(sPhoneStr.length > 10){ //add optional extention if more then 10 digits
					sNewPhoneString = sNewPhoneString.substr(0,14) + " x" + sPhoneStr.substr(10);
					//alert(sPhoneStr);
				}
				oFormEle.value = sNewPhoneString;
			}
			
			break;
		case MASK_SMALLPHONE:
			if(ValidateKey(oFormEle, CODEFILTER_NUMBERS, ffEvent)){ //Only reformat if a number 
				var sPhoneStr = new String(oFormEle.value.replace(/[\D]/ig,"")); //Clean out hyphen and parens
				var sNewPhoneString = sPhoneStr;
				
				if(sPhoneStr.length > 3){ //add hyphen
					sNewPhoneString = sPhoneStr.substr(0,3) + "-" + sPhoneStr.substr(3);
				}
				
				oFormEle.value = sNewPhoneString;
			}
			
			break;
		default:
			break;
	}
}
//Color Negative - Incases where values my be negtive and not in form field
function ColorNegativeValue(sValue, sMask, bFixed, oFormEle){
	var sRetVal = FormatString(sValue, sMask, bFixed);
	var nNumber = new Number(new String(sRetVal.replace(/[\$%,]/ig,"")));
	if(!oFormEle){
		if(nNumber < 0){
			return "<span class='spRedTxt'>" + sRetVal + "</span>";
		}
		return "<span style='color:'>" + sRetVal + "</span>";
	}
	else{
		
		if(nNumber < 0){
			oFormEle.style.color="red";
			return sRetVal
		}
		oFormEle.style.color="";
		return sRetVal
		
	}

}

// Summary: Gets the value attribute of the element, strips non-essential characters
// rounds it to two decimals and formats it to currency with commas and the dollar 
// sign as needed.  The element value will be filled with the formatted number.
// Parameter: oElement - the HTML element containing the number.
// returns: void
// Example: <input type="text" onBlur="FormatToCurrency(this)"></input>
function FormatToCurrency(oElement, iPrecision)
{
	var sNumber = oElement.value;
	
	var sFormatted = FormatStringToCurrency(sNumber, iPrecision);
	
	oElement.value = sFormatted;
	oElement.VerifyCurrency = true;
}

// Summary: Takes the input string and strips anyting but digits and 
// anything for numbers(".", "-").  Then rounds the result to 2 digits.
// Then formats the result to currency ($xxx,xxx.xx);
// Parameter: sInput - the string to convert to currency.
// returns: the formatted string.
// Example: var sFormatted = FormatStringToCurrency(sNumber);
function FormatStringToCurrency(sInput, iPrecision)
{
	// Strip user entered value to number.
	var sStripped = StripToNumber(sInput, iPrecision);
	var sFormatted = sStripped;
	var varPrecision = 4;
	
	if(iPrecision)
		varPrecision = iPrecision
		
	// Round value to two digits
	var sConverted = "" + NumberConversion.ConvertNumber(sFormatted, varPrecision);
	
	var sWhole = sConverted;
	var sRemain = ".00";

  if(sConverted.indexOf(".") != -1)
  {
    var iDot = sConverted.indexOf(".");
    sWhole = sConverted.substr(0, iDot);
    sRemain = sConverted.substr(iDot);
  }

  if(sWhole.length > 3)
  {
    var sCommasAdded = "";
    var iLeft = sWhole.length % 3;
    if(iLeft > 0)
    {
      iLeft = 3 - iLeft;
    }

    for(var i = 0; i < sWhole.length; i++)
    {
      sCommasAdded += sWhole.charAt(i);
      iLeft++;
      if(iLeft == 3 && i < sWhole.length - 1)
      {
        sCommasAdded += ",";
        iLeft = 0;
      }
    }
    sFormatted = sCommasAdded;
  }
  else
  {
     sFormatted = sWhole;
  }
  return "$" + sFormatted + sRemain;
}

// Summary: Strips anything but a digit, a ".", and a "-" and sets the value of the
// element to the stripped characters.
// characters in a string.
// Parameter: oElement - the HTML element containing the number.
// returns: void
// Example: <input type="text" onChange="StripElementToNumber(this)"></input>
function StripElementToNumber(oElement, iPrecision)
{
	var sNumber = oElement.value;
	var sStripped = StripToNumber(sNumber, iPrecision);
	oElement.value = sStripped;
}

// Summary: Strips anything but a digit, a ".", and a "-" and returns the stripped
// characters in a string.
// Parameter: sNumber - the string to strip.
//				iPrecision - number of digits after the decimal point to keep
// returns: The number in the string
// Example: StripToNumber("$1,000,000.00") returns 1000000.00.
function StripToNumber(sNumber, iPrecision)
{
	var sStripped = "";
	var sPrecision = 5;
	
	if(iPrecision)
		sPrecision = iPrecision;
		
	for(var c = 0; c < sNumber.length; c++)
	{
		if(sNumber.indexOf(".") != -1) { 
			sNumber = sNumber.substring(0,(sNumber.indexOf(".") + 1 + sPrecision));	//+1 to include the decimal point
		}
		var ch = sNumber.charAt(c);
		if(ch == "0" || ch == "1" ||
		   ch == "2" || ch == "3" ||
		   ch == "3" || ch == "4" ||
		   ch == "5" || ch == "6" ||
		   ch == "7" || ch == "8" ||
		   ch == "9" || ch == "." ||
		   ch == "-")
		{
			sStripped += ch;
		}
	}

	return sStripped;
}

// Summary: Strips anything but an alpha character and sets the value of the
// element to the stripped characters.
// Parameter: oElement - the HTML element containing the string.
// returns: void
// Example: <input type="text" onChange="StripElementToAlpha(this)"></input>
function StripElementToAlpha(oElement)
{
	var sAlpha = oElement.value;
	var sStripped = StripToAlpha(sAlpha);
	oElement.value = sStripped;
}

// Summary: Strips anything but alphabet and returns the stripped
// characters in a string.
// Parameter: sText - the string to strip.
// returns: The alpha characters in the string
// Example: StripToAlpha(123abc) returns abc.
function StripToAlpha(sText)
{
	var sStripped = "";
	var sToLower = sText.toLower();
	
	for(var c = 0; c < sText.length; c++)
	{
		var ch = sToLower.charAt(c);
		var cOk = sText.charAt(c);
		if(ch == "a" || ch == "b" ||
		   ch == "c" || ch == "d" ||
		   ch == "e" || ch == "f" ||
		   ch == "g" || ch == "h" ||
		   ch == "i" || ch == "j" ||
		   ch == "k" || ch == "l" ||
		   ch == "m" || ch == "n" ||
		   ch == "o" || ch == "p" ||
		   ch == "q" || ch == "r" ||
		   ch == "s" || ch == "t" ||
		   ch == "u" || ch == "v" ||
		   ch == "w" || ch == "x" ||
		   ch == "y" || ch == "z")
		{
			sStripped += cOk;
		}
	}
	return sStripped;
}


function FormatPhone(oElement)
{
	var sValue = oElement.value;
	var sNew = NumberConversion.FormatStringToPhone(sValue);
	oElement.value = sNew;
}

//FormatString Function - Formats the string sValue based on the sMask. Called from scripts that fill innerHTML and FormatValue
function FormatString(sValue, sMask, bFixed){
	bFixed = bFixed==true ? bFixed : false;
	sValue = new String(sValue);
	switch (sMask){
		case MASK_ALPHA:
			//Do Nothing Here fro now
		break; //Alpha
		case MASK_NUMERIC:
		case MASK_SMALLCURRENCY:
		case MASK_CURRENCY:
		case MASK_PERCENT:
				//Clean up Non numbers
				var sNumberStr = new String(sValue.replace(/[\$%,]/ig,"")); //Clean out Dollar Sign, Commas and Percent Sign then  set RealValue Attribute
				
				
				
				var nRealValue = new Number(sNumberStr);
				//Set RealValue
				if(sMask == MASK_SMALLCURRENCY && sNumberStr != ""){
					sNumberStr = bFixed ? nRealValue.toFixed(0) : sNumberStr;
					sNumberStr = (sNumberStr.length - sNumberStr.indexOf(".") > 3 && sNumberStr.indexOf(".") > 0)? sNumberStr.substring(0, sValue.indexOf(".") + 3) : sNumberStr;
				}
				if(sMask == MASK_CURRENCY && sNumberStr != ""){
					sNumberStr = bFixed ? nRealValue.toFixed(2) : sNumberStr;
					sNumberStr = (sNumberStr.length - sNumberStr.indexOf(".") > 3 && sNumberStr.indexOf(".") > 0)? sNumberStr.substring(0, sValue.indexOf(".") + 3) : sNumberStr;
				}
				if(sMask == MASK_PERCENT && sNumberStr != ""){
					sNumberStr = (sNumberStr.length - sNumberStr.indexOf(".") > 5 && sNumberStr.indexOf(".") > 0)? sNumberStr.substring(0, sValue.indexOf(".") + 5) : sNumberStr;
						
				}
				//Reform number
				var y = 0; //Current Position in String
				var sNewString = new String("");
				var nDecimalPos = (sNumberStr.indexOf("."));
				var bUseComma = true;
				if(nDecimalPos > -1){
					bUseComma=false ;
				}	

				for(x = sNumberStr.length-1; x >= 0 ;x--){
					//alert("x=" + x + " char=" + sNumberStr.charAt(x) + " nDecimalPos=" + nDecimalPos)
					if ( x == nDecimalPos){
						bUseComma=true;
						y = -1;
					}
					if(y%3 == 0 && y!=0 && bUseComma && sNumberStr.charAt(x)!="-" && sNumberStr.charAt(x)!="$" )
					sNewString = "," + sNewString;
					if(sNumberStr.charAt(x)!="-" || x==0 || sNumberStr.charAt(x)!="$"){
						sNewString = sNumberStr.charAt(x) + sNewString;
						y++;
					}
				}
				//Set in form
					
				sValue = sNewString;
				
				//alert("sValue: " + sValue);
				//Add % or Dollar sign
				if(sMask == MASK_PERCENT && sValue != ""){ // specail to Pecent
					sValue = sValue + "%";
				}
				if((sMask == MASK_CURRENCY  || sMask ==  MASK_SMALLCURRENCY)&& sValue != ""){ // specail to MASK_CURRENCY
					sValue = "$" + sValue;
				}
				y = null;	
			break;
		case MASK_PHONE:
			var sPhoneStr = new String(sValue.replace(/[\D]/ig,"")); //Clean out Hyphen and paren
				var sNewPhoneString = sPhoneStr;
				if(sPhoneStr.length > 2){ //add area code
					sNewPhoneString = "(" + sPhoneStr.substr(0,3) + ") " + sPhoneStr.substr(3);
				}
				if(sPhoneStr.length > 5){ //add Hyphen
					sNewPhoneString = sNewPhoneString.substr(0,6) + sPhoneStr.substr(3,3) + "-" + sPhoneStr.substr(6);
				}
				if(sPhoneStr.length > 10){ //add optional Extention
					sNewPhoneString = sNewPhoneString.substr(0,14) + " x" + sPhoneStr.substr(10);
					//alert(sPhoneStr);
				}
				sValue = sNewPhoneString;
			break;
		case MASK_SMALLPHONE:
				var sSmallPhoneStr = new String(sValue.replace(/[\D]/ig,"")); //Clean out Hyphen and paren
				var sNewSmallPhoneString = sSmallPhoneStr;
				if(sSmallPhoneStr.length > 4){ //add Hyphen
					sNewSmallPhoneString = sNewSmallPhoneString.substr(0,6) + sSmallPhoneStr.substr(3,3) + "-" + sSmallPhoneStr.substr(6);
				}
				sValue = sNewPhoneString;
			break;
		default:
			break;
	}
	return sValue
}


//MakePhone Function - Formats value of oFormEle to look like a phone number with areacode
// and optional extension (AreaCode) PreFix-PostFix [xExtension]
function MakePhone(oFormEle)
{
	if(oFormEle.readOnly != true)
	{
		var sOldValue = oFormEle.value;
		var sPhoneStr = new String(sOldValue.replace(/[\D]/ig,"")); //Clean out hyphen and parens

		if (sOldValue != "")
		{
			var sNewPhoneString = sPhoneStr;
			if (sPhoneStr.length >= 10)
			{
				if(sPhoneStr.length > 2){ //add area code parens, and a space after closing paren
					sNewPhoneString = "(" + sPhoneStr.substr(0,3) + ") " + sPhoneStr.substr(3);
				}
				if(sPhoneStr.length > 5){ //add hyphen
					sNewPhoneString = sNewPhoneString.substr(0,6) + sPhoneStr.substr(3,3) + "-" + sPhoneStr.substr(6);
				}
				if(sPhoneStr.length > 10){ //add optional extention if more then 10 digits
					sNewPhoneString = sNewPhoneString.substr(0,14) + " x" + sPhoneStr.substr(10);
					//alert(sPhoneStr);
				}
				oFormEle.value = sNewPhoneString;
			}	//end if sPhoneStr.length >= 10
			else
			{
				//GPRTL00000555 defect
				alert("Please enter the full ten(10) digit phone number\n\ni.e (123) 555-4321");
				// oFormEle.focus();
				// oFormEle.select();
				//end GPRTL00000555 defect
				
			}	//end else
		}	//end if sOldValue
	}	//end if !.readOnly
}	//end MakePhone

//GPRTL00000570
//MakePhoneWithNoExtension Function - Formats value of oFormEle to look like a phone number with areacode
// (AreaCode) PreFix-PostFix 
function MakePhoneWithNoExtension(oFormEle)
{
	if(oFormEle.readOnly != true)
	{
		var sOldValue = oFormEle.value;
		var sPhoneStr = new String(sOldValue.replace(/[\D]/ig,"")); //Clean out hyphen and parens

		if (sOldValue != "")
		{
			var sNewPhoneString = sPhoneStr;
			if (sPhoneStr.length >= 10)
			{
				if(sPhoneStr.length > 2){ //add area code parens, and a space after closing paren
					sNewPhoneString = "(" + sPhoneStr.substr(0,3) + ") " + sPhoneStr.substr(3);
				}
				if(sPhoneStr.length > 5){ //add hyphen
					sNewPhoneString = sNewPhoneString.substr(0,6) + sPhoneStr.substr(3,3) + "-" + sPhoneStr.substr(6);
				}
				if(sPhoneStr.length > 10){ //add optional extention if more then 10 digits
					sNewPhoneString = sNewPhoneString.substr(0,14);
					//alert(sPhoneStr);
				}
				oFormEle.value = sNewPhoneString;
			}	//end if sPhoneStr.length >= 10
			else
			{
				//GPRTL00000555 defect
				alert("Please enter the full ten(10) digit phone number\n\ni.e (123) 555-4321");
				// oFormEle.focus();
				// oFormEle.select();
				//end GPRTL00000555 defect
				
			}	//end else
		}	//end if sOldValue
	}	//end if !.readOnly
}	//end MakePhoneWithNoExtension


function MakeSmallPhone(oFormEle){
	if(oFormEle.readOnly != true)
	{
		var nLen = oFormEle.value.length;
		if(nLen > 0 && nLen < 8){
			alert("Please enter the full seven(7) digit phone number\n\ni.e 555-4321");
			oFormEle.focus();
			oFormEle.select();
		}
	}
}

//isEmail Function - Checks to see if the Form Element contains a valid Email
function isEmail(oFormEle){
	if(oFormEle.value == "")
		return true;

	var sEMail = oFormEle.value;
	if(!CheckEmail(sEMail)){
		alert("Please Enter a Valid Email Address.\n\n" + sEMail + " is not valid.");
		oFormEle.select();
	}
}

//CheckEmail Function -  This function checks if sEmail is a valid emailaddress
function CheckEmail(sEmail)
{
	var reSpeacial = /[\._\-@]{2}/;	// an emailadress may not contain two of these next to eachother
	var reStart = /^[\._\-]/;		// an emailadress may not start with these
	var reEmail = /^[A-Za-z0-9_\.\-]{1,}@[A-Za-z0-9_\.\-]{1,}\.[A-Za-z]{2,}$/;
	var reEnd = /[\._\-]$/;		// an username may not end with these
	return (!reSpeacial.test(sEmail) && !reStart.test(sEmail) && reEmail.test(sEmail))
}


//PickDate Function -  This function Pops up a calendar under the oFormEle.
function PickDate(oFormEle){
	m_oTheFormElement = oFormEle;

	if(oFormEle.readOnly != true)
	{
		if(isNaN(new Date(oFormEle.value).getMonth())){
			m_oOrigDate = new Date();
		}	
		else{
			m_oOrigDate = new Date(oFormEle.value);
		}
		
		//use popup
		if(m_oCalPopup == null){
			m_oCalPopup = window.createPopup();
			var oDocStyleSheets = document.styleSheets;
			for (i=0; i < oDocStyleSheets.length; i++)
			{
				m_oCalPopup.document.createStyleSheet(oDocStyleSheets[i].href);
			}	//end for i
		}
		//alert("here")	

		m_oCalPopup.document.body.innerHTML =  CreatePopupCalendarHTML(m_oOrigDate);;
		m_oCalPopup.show(0, 20, 165, 170, oFormEle)
	
	}
	
}

//CreatePopupCalendarHTML Function -  This Builds the html for the popup calendar.
function CreatePopupCalendarHTML(sDate){
	var oDate = new Date(sDate); //Date object of passed in date
	oDate.setHours(0,0,0);
	var oCalDate = oDate; // Create CalendarDate
	oCalDate.setDate(1); // Set the the first of the month;
	
			
	var oTable = document.createElement("table");
	oTable.className = STYLE_CALTABLE ;
	var oHeaderRow = oTable.insertRow();
	oHeaderRow.setAttribute(EVENTS_ONCLICK, "parent.m_oCalPopup.hide()");
	oHeaderRow.style.cursor = "hand";
	oHeaderRow.className = STYLE_CALHEADER;
	var oHeaderCell = oHeaderRow.insertCell()
	oHeaderCell.setAttribute("colspan", 6);
	oHeaderCell.innerText = m[oDate.getMonth()] + " " + oDate.getFullYear();
	oHeaderCell.align = "center";
	
	var oXCell = oHeaderRow.insertCell()
	oXCell.setAttribute(EVENTS_ONCLICK, "parent.m_oCalPopup.hide()");
	oXCell.setAttribute("colspan", 3);
	oXCell.align = "center";
	oXCell.style.cursor = "hand";
	oXCell.innerText = "X"
	
	var oNavRow = oTable.insertRow();
	oNavRow.className = STYLE_CALHEADER; 
	
//	var UNITS_MONTH = 1;
//var UNITS_YEAR = 12;

	
	var oNavCellBackYear = oNavRow.insertCell();
	oNavCellBackYear.setAttribute(EVENTS_ONCLICK, "parent.MoveCalendar(\"" + oCalDate + "\", -parent.UNITS_YEAR)");
	oNavCellBackYear.style.cursor = "hand";
	oNavCellBackYear.innerText = "<<"
	
	var oNavCellBackMonth = oNavRow.insertCell();
	oNavCellBackMonth.setAttribute(EVENTS_ONCLICK, "parent.MoveCalendar(\"" + oCalDate + "\", -parent.UNITS_MONTH)");
	oNavCellBackMonth.style.cursor = "hand";
	oNavCellBackMonth.innerText = "<"
	
	var oNavCellClose = oNavRow.insertCell();
	//oNavCellClose.setAttribute(EVENTS_ONCLICK, "parent.m_oCalPopup.hide()");
	oNavCellClose.setAttribute("colspan", 3);
	oNavCellClose.align = "center";
	//oNavCellClose.style.cursor = "hand";
	//oNavCellClose.innerText = "close"
	
	var oNavCellForwardMonth = oNavRow.insertCell();
	oNavCellForwardMonth.setAttribute(EVENTS_ONCLICK, "parent.MoveCalendar(\"" + oCalDate + "\", parent.UNITS_MONTH)");
	oNavCellForwardMonth.style.cursor = "hand";
	oNavCellForwardMonth.innerText = ">"
	
	var oNavCellBackYear = oNavRow.insertCell();
	oNavCellBackYear.setAttribute(EVENTS_ONCLICK, "parent.MoveCalendar(\"" + oCalDate + "\", parent.UNITS_YEAR)");
	oNavCellBackYear.style.cursor = "hand";
	oNavCellBackYear.innerText = ">>"
	
	var oDayHeaderRow = oTable.insertRow();
	var oDayArray = new Array("S","M","T","W","T","F","S");
	oDayHeaderRow.className = STYLE_CALHEADER; 
	for(x=0; x<oDayArray.length; x++){
		var oDayHeaderCell  = oDayHeaderRow.insertCell();
		oDayHeaderCell.style.cursor = "default";
		oDayHeaderCell.innerText = oDayArray[x];
		oDayHeaderCell.style.width = (100/7) + "%";
	}
	
	var nFirstDayOfMonth = oCalDate.getDay();
	oCalDate.setMonth(oCalDate.getMonth()+1);
	oCalDate.setDate(oCalDate.getDate()-1);
	var nLastDateOfMonth = oCalDate.getDate();
	var date = ""

	var oToday = new Date();
	oToday.setHours(0,0,0,0);
	var nWeek = 0;
	var oWeekRow;
	var oDayCell;
	for(nDay =1-nFirstDayOfMonth; nDay<=nLastDateOfMonth; nDay++){
		if(nWeek % 7 == 0){
			oWeekRow = oTable.insertRow();
		}
		oDayCell = oWeekRow.insertCell();
		oDayCell.style.cursor = "default";
		if(nDay > 0){
			var oDayCalDate = new Date(oCalDate.setDate(nDay));
			oDayCell.style.cursor = "hand";
			oDayCell.innerText = nDay;
			oDayCell.className = STYLE_CALDAY;
			oDayCell.setAttribute(EVENTS_ONCLICK, "parent.ChooseDate(\"" + oDayCalDate + "\")");
			
			if(oDayCalDate.valueOf() == m_oOrigDate.valueOf()){
				oDayCell.className = STYLE_TODAY;
			}
			if(oDayCalDate.valueOf() == oToday.valueOf()){
				oDayCell.style.backgroundColor = "#eeeeee";
			}
		}				
		nWeek++;
	}		
	return oTable.outerHTML;
}

//ChooseDate Function -  Is called from the popcalendar and place the date into the current m_oTheFormElement.
function ChooseDate(sDate){
	oDate = new Date(sDate);
	SDate = m[oDate.getMonth()] + " " + oDate.getDate() + " " + oDate.getFullYear();
	m_oTheFormElement.value= m[oDate.getMonth()] + " " + oDate.getDate() + " " + oDate.getFullYear();
	isDate(m_oTheFormElement,1)
	m_oCalPopup.hide();
	m_oTheFormElement.focus();
}

//MoveCalendar Function -  Cycles the calndar forward or back by nAmount of months.
function MoveCalendar(sDate, nAmount){
	oDate = new Date(sDate);
	oDate.setMonth(oDate.getMonth() + nAmount);
	m_oCalPopup.document.body.innerHTML = CreatePopupCalendarHTML(oDate);
}

//PickTime Function -  This function Pops up a list of Times under the oFormEle.
function PickTime(oFormEle){
	m_oTheFormElement = oFormEle;
	m_sOrigTime = oFormEle.value;
	if(m_oTimePopup == null){
		m_oTimePopup = window.createPopup();
		var oDocStyleSheets = document.styleSheets;
		for (i=0; i < oDocStyleSheets.length; i++)
		{
			m_oTimePopup.document.createStyleSheet(oDocStyleSheets[i].href);
		}	//end for i
	} // end if
	m_oTimePopup.document.body.innerHTML = MakeTimePicker(m_sOrigTime);
	m_oTimePopup.show(0, 20, 100, 200, m_oTheFormElement)
	
	// Scoll to good spot
	if(m_oTimePopup.document.all.ScrollHere != null){
		m_oTimePopup.document.all.ScrollHere.scrollIntoView();
	}
	else{
		m_oTimePopup.document.all.TimeDiv.scrollTop = m_oTimePopup.document.all.TimeDiv.scrollHeight/4;
	}
}	//end PickTime

//MakeTimePicker Function -  Create the HTML for the TimePicker
function MakeTimePicker(m_sOrigTime)
{
	try{
		var nStartTime = 25;
		var oCurrentCell = null;
		//Check if Endtime then compare Starttime
		if(m_oTheFormElement.name == "EndTime" && m_oTheFormElement.form.StartTime != null){
			var nStartTime = Date.parse("1/1/1970 " + m_oTheFormElement.form.StartTime.value);
			if(!isNaN(nStartTime) && 
			m_oTheFormElement.form.StartDate.value == m_oTheFormElement.form.EndDate.value && 
			m_oTheFormElement.form.StartTime.value != ""){
				oStartTime = new Date(nStartTime);
				nStartTime = oStartTime.getHours() + oStartTime.getMinutes()/60;
				m_ScrollPos = 1;
			} //end if !isNaN...
		}
		
		//Make Table
		var oTimeDiv = document.createElement("div");
		oTimeDiv.className = STYLE_CALTABLE;
		oTimeDiv.style.overflow = "auto";
		oTimeDiv.style.width = "100%";
		oTimeDiv.style.height = "100%";
		oTimeDiv.id = "TimeDiv";
		
		var oTable = document.createElement("table");
		oTimeDiv.appendChild(oTable);
		
		//oTable.className = STYLE_CALTABLE ;
		for(nHour = 0; nHour < 24; nHour++){
			for(nMin = 0; nMin < 60; nMin+=30){
				var sTime = FormatTime(nHour, nMin);
				//alert(sTime);
				var sDiff = "";
				var bFilter = false;
				var nCurrTime = nHour + (nMin/60);
				if(nCurrTime >= nStartTime){
					var nDiff = nCurrTime - nStartTime;
					var sHour = Math.floor(nDiff);
					var sMin = Math.round((nDiff % 1)*60)
					sMin = (sMin < 10) ? "0" + sMin : sMin;
					sDiff = " +" + sHour + ":" + sMin + "";
					bFilter = true;
				}
				
				if(nStartTime > 24 || bFilter){   //Don't show invalid times
					var oTimeRow = oTable.insertRow();
					oTimeRow.style.cursor = "hand";
					oTimeRow.setAttribute(EVENTS_ONCLICK, "parent.ChooseTime(\""+ sTime + "\")");
					
					var oTimeCell = oTimeRow.insertCell();
					oTimeCell.className = "spLabel";
					oTimeCell.title = sTime;
					oTimeCell.align = "right";
					oTimeCell.innerHTML = sTime;
					if(m_sOrigTime == sTime){
						oTimeCell.id = "ScrollHere";
					}
					var oDiffCell = oTimeRow.insertCell()
					oDiffCell.style.cursor = "hand";
					oDiffCell.className = "spLabel";
					oDiffCell.innerText = sDiff;
				} //end if(sDiff..
			}	
		} // end for nHour	
		//alert(oTimeDiv.outerHTML)	
		
		return oTimeDiv.outerHTML;
	} // end try
	catch(e){
		throw e;
		alert(e + "\nTime picker is not working on your browser, please type in a time!")
	} // end catch
}	//end MakeTimePicker

//ChooseTime Function -  Is called from the popcalendar and place the date into the current m_oTheFormElement.
function ChooseTime(sTime)
{
	m_oTheFormElement.value = sTime;
	m_oTimePopup.hide();
	isTime(m_oTheFormElement);
}	//end ChooseTime

//FormatTime Function -  Formats the time given nHour and nMin
function FormatTime(nHour, nMin)
{
	var sHour = nHour;
	if(nHour == 0)
		sHour = "12";
	if(nHour > 12)
		sHour = nHour-12;	
	var sMin = nMin;
	if(nMin < 10)
		sMin = "0" + nMin;
	var sAMPM = " AM";
	if(nHour >= 12) 
		sAMPM = " PM";
	return sHour + ":" + sMin + sAMPM;
}	//end FormatTime


// ValidateDate Function.  Does some checks to ensure that date is OK.
//   We could do a few more checks, but we will put them in later if certain
//   business rules merit doing so.
// This code was added to force user choose the date instead of converting an inappropriate date 
//   to a calendar value.	
// There is only one caller for ValidateDate.  If an empty string is returned, the caller
//   knows that the date is not legitimate.  Otherwise, the function returns a legitimate 
//   JavaScript date string to the calling function.	

function ValidateDate(sDate){
	
	var arrDate;
	
	if(sDate.indexOf('/') != -1)
		arrDate = sDate.split('/');
	else if (sDate.indexOf ('-') != -1)
		arrDate = sDate.split('-');
	else 
		arrDate = sDate.split (' ');	
		
	var nMonth;
	
	if (isInteger (arrDate[0]))
		nMonth = arrDate[0];
	else
		nMonth = GetNumericMonthFromString (arrDate[0]);
	
	var nDay = arrDate[1];
	var nTestYear = arrDate[2];
	
	// It could very well be that we don't even have a three piece date...
	if (nTestYear == undefined)
		return '';
	
	// Fail if the month is not in the correct range
	if((nMonth > 12) || (nMonth < 1))
		return '';
	
	// Fail if the length of the year is not specified
	if(nTestYear.length != 4)
		return '';	
		
	// Fail if the day number is specified too high
	var maxDay = max_day(nMonth, nTestYear);
	if (nDay > maxDay)
		return '';	 
		
	var dTestDate = new Date(sDate);
	
	return dTestDate.toDateString();	
}


// This function accounts for the possibility of the three character date string format
//   from our standard calendar control, which is not an uncommon thing.
function GetNumericMonthFromString (monthString)
{
	if (monthString == 'Jan')
		return 1;
	
	if (monthString == 'Feb')
		return 2;
		
	if (monthString == 'Mar')
		return 3;
		
	if (monthString == 'Apr')
		return 4;
		
	if (monthString == 'May')
		return 5;
		
	if (monthString == 'Jun')
		return 6;
		
	if (monthString == 'Jul')
		return 7;
		
	if (monthString == 'Aug')
		return 8;
		
	if (monthString == 'Sep')
		return 9;
		
	if (monthString == 'Oct')
		return 10;
		
	if (monthString == 'Nov')
		return 11;
		
	if (monthString == 'Dec')
		return 12;
}


function isInteger(s)
{   
	var i;
	
    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);
        if ((c < "0") || (c > "9")) return false;
    }
    
    // All characters are numbers.
    return true;
}


// function for calculating maximum day 
	function max_day(mn, yr)
	{
		var mDay;
		if((mn == 4) || (mn == 6) || (mn == 9) || (mn == 11))
		{ 
			mDay = 30;
		}
		else if(mn == 2)
		{
			//calling leap year function 
			mDay = isLeapYear(yr) ? 29 : 28;    
		}
		else
		{
			mDay = 31;
		}
		return mDay; 
	}
	
	// function to check leap year
	function isLeapYear(yr)
	{
		if      (yr % 4 != 0)   return false;
		else if (yr % 400 == 0) return true;
		else if (yr % 100 == 0) return false;
		else                    return true;
	}

//isDate Function -  Formats the value of  oFormEle in to nFormat
function isDate(oFormEle, nFormat) {
	var sMonthName = "";								// Month Formatted
	var sFormatedDate = "";								// Date Formatted
	var sDateString = ValidateDate(oFormEle.value);   // Date Value
	var oNewDate = new Date(sDateString);
	var nMonth = 0;
	var oTheForm = oFormEle.form;
	if(oFormEle.value.length > 0){
		if(!isNaN(oNewDate.getDate())){
			if(oFormEle.name == "EndDate" && oTheForm.StartDate != null){
				var oStartDate = new Date(oTheForm.StartDate.value);
				if(oStartDate > oNewDate){
					oFormEle.value = oTheForm.StartDate.value;
					alert("The End Date must be after the Start Date");
					return false;
				}
			}	
			
			nMonth = oNewDate.getMonth();
			sMonthName = m[nMonth];
			switch(nFormat){
				case FORMAT_MM_DD_YYYY:
					var newMonth = nMonth + 1; var newDay = oNewDate.getDate();
					if(newMonth < 10) 
						newMonth = "0" + newMonth;
					if(newDay < 10) 
						newDay = "0" + newDay;
					sFormatedDate = newMonth + "/" + newDay + "/" + oNewDate.getFullYear(); 
					oFormEle.value = sFormatedDate;
					break;
				default: //FORMAT_MMM_DD_YYYY
					if (oNewDate.getDate() < 10){
						sFormatedDate = sMonthName + "  " + oNewDate.getDate() + " " + oNewDate.getFullYear(); 
						oFormEle.value = sFormatedDate;
					}
					else{
						sFormatedDate = sMonthName + " " + oNewDate.getDate() + " " + oNewDate.getFullYear(); 
						oFormEle.value = sFormatedDate;
					}
				break;
			}
			oFormEle.value = sFormatedDate;
			//oFormEle.focus();
			return true; // date is valid
		}
		else{
			oFormEle.value = "";
			alert("Please enter date in any of the following formats:\n\tmm/dd/yyyy (i.e. 5/25/2005)\n\tmm-dd-yyyy (i.e. 5-25-2005)");
			return false;
		}
		return true;		
	}//  end if(oFormEle.value.length > 0)
}

//isTime Function -  Formats the value of  oFormEle in to time
function isTime(oFormElement)
{
	var sTime = oFormElement.value;
	if(sTime == "") return true;
	var nTime = Date.parse("1/1/1970 " + sTime);
	if( isNaN(nTime) )
	{
		alert("Please Enter Valid Time in the following format:\n\thh:mm am/pm (i.e. 10:45 pm)\n\t  or\n\t HH:mm (i.e. 22:45)");
		oFormElement.value = "";
		return false;
	}
	var oTime = new Date(nTime)
	oFormElement.value = FormatTime(oTime.getHours(),oTime.getMinutes());
	if(oFormElement.name == "StartTime" && oFormElement.form.EndTime)
	{
		if(oFormElement.form.EndTime.value == "")
			oFormElement.form.EndTime.value = oFormElement.value;;
	}
	return true;
}	//end isTime

//PostProcess Form
function PostProcess(oTheForm){
	var oTheElements = oTheForm.elements
	for(nEleIndex=0; nEleIndex < oTheElements.length; nEleIndex++){// Remove Mask from all masked numeric values
		if(oTheElements[nEleIndex].RealValue != null){
			oTheElements[nEleIndex].value = oTheElements[nEleIndex].RealValue;
		}// end if
	}// end for
	return true;
}// end function PostProcess

//Pre Process Form
function PreProcess(oTheForm){ 
	var oTheElements = oTheForm.elements
	//alert(oTheElements.length);
	for(nEleIndex=0;nEleIndex < oTheElements.length;nEleIndex++){ // Add Mask to all masked numeric values by fireing the onKeyUp event
		if(oTheElements[nEleIndex].RealValue != null){
			oTheElements[nEleIndex].fireEvent("onKeyUp");
		}
	}
	return true;
}// end function PreProcess


function checkMaxLength(evt, oTextArea, iValue)
{
	
	var iCurrentLength = oTextArea.value.length;
	var nKeyCode = evt.keyCode;
	
	if(
			(nKeyCode == 9) || // Tab
			(nKeyCode == 13) || // Return
			(nKeyCode == 16) || // Shift
			(nKeyCode >= 37 && nKeyCode <= 40) || //Arrows
			(nKeyCode == 45) || //
			(nKeyCode >= 112 && nKeyCode <= 123) //Function Keys
		   ) 
		  return true;
		  
	if((
		(nKeyCode == 8) || // Delete
			(nKeyCode == 46) // Backspace
		   )) 
		  return true;
	
	if(iCurrentLength >= iValue)
		return false;
	
	return true;
}
