/***********************************************************************
	File Name: jsValidation.js
	Functions/Subs:  List of all client-side functions.
	Description: General validation 
	Comments: N/A
***********************************************************************/
//GLOBAL VARIABLES

function makeArray(n) {
//*** BUG: If I put this line in, I get two error messages:
//(1) Window.length can't be set by assignment
//(2) daysInMonth has no property indexed by 4
//If I leave it out, the code works fine.
//   this.length = n;
   for (var i = 1; i <= n; i++) {
      this[i] = 0
   } 
   return this
}

// whitespace characters
var whitespace = " \t\n\r";
//To add invalid characters, use the escape character "\" and the character
//Make sure you add (or delete) any character from the msgValidChar variable if you change pattenr
var rgPattern = /[^\w\s\!\@\#\$\%\^\&\*\(\)\+\=\_\-\,\.\?\/\'\:\;]/;
var msgValidChar = "A-Z, a-z, 0-9, !@#$%^&*()+=_-,.?/':;"
var defaultEmptyOK = false;
var daysInMonth = makeArray(12);
daysInMonth[1] = 31;
daysInMonth[2] = 29;   // must programmatically check this
daysInMonth[3] = 31;
daysInMonth[4] = 30;
daysInMonth[5] = 31;
daysInMonth[6] = 30;
daysInMonth[7] = 31;
daysInMonth[8] = 31;
daysInMonth[9] = 30;
daysInMonth[10] = 31;
daysInMonth[11] = 30;
daysInMonth[12] = 31;

/*  ================================================================
    FUNCTION:  isCreditCard(st)
 
    INPUT:     st - a string representing a credit card number

    RETURNS:  true, if the credit card number passes the Luhn Mod-10
		    test.
	      false, otherwise
    ================================================================ */

function isCreditCard(st) {
  // Encoding only works on cards with less than 19 digits
  if (st.length > 19)
    return (false);

  sum = 0; mul = 1; l = st.length;
  for (i = 0; i < l; i++) {
    digit = st.substring(l-i-1,l-i);
    tproduct = parseInt(digit ,10)*mul;
    if (tproduct >= 10)
      sum += (tproduct % 10) + 1;
    else
      sum += tproduct;
    if (mul == 1)
      mul++;
    else
      mul--;
  }
// Uncomment the following line to help create credit card numbers
// 1. Create a dummy number with a 0 as the last digit
// 2. Examine the sum written out
// 3. Replace the last digit with the difference between the sum and
//    the next multiple of 10.

//  document.writeln("<BR>Sum      = ",sum,"<BR>");
//  alert("Sum      = " + sum);

  if ((sum % 10) == 0)
    return (true);
  else
    return (false);

} // END FUNCTION isCreditCard()



/*  ================================================================
    FUNCTION:  isVisa()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid VISA number.
		    
	      false, otherwise

    Sample number: 4111 1111 1111 1111 (16 digits)
    ================================================================ */

function isVisa(cc)
{
  if (((cc.length == 16) || (cc.length == 13)) &&
      (cc.substring(0,1) == 4))
    return isCreditCard(cc);
  return false;
}  // END FUNCTION isVisa()




/*  ================================================================
    FUNCTION:  isMasterCard()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid MasterCard
		    number.
		    
	      false, otherwise

    Sample number: 5500 0000 0000 0004 (16 digits)
    ================================================================ */

function isMasterCard(cc)
{
  firstdig = cc.substring(0,1);
  seconddig = cc.substring(1,2);
  if ((cc.length == 16) && (firstdig == 5) &&
      ((seconddig >= 1) && (seconddig <= 5)))
    return isCreditCard(cc);
  return false;

} // END FUNCTION isMasterCard()





/*  ================================================================
    FUNCTION:  isAmericanExpress()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid American
		    Express number.
		    
	      false, otherwise

    Sample number: 340000000000009 (15 digits)
    ================================================================ */

function isAmericanExpress(cc)
{
  firstdig = cc.substring(0,1);
  seconddig = cc.substring(1,2);
  if ((cc.length == 15) && (firstdig == 3) &&
      ((seconddig == 4) || (seconddig == 7)))
    return isCreditCard(cc);
  return false;

} // END FUNCTION isAmericanExpress()


/*  ================================================================
    FUNCTION:  isDiscover()
 
    INPUT:     cc - a string representing a credit card number

    RETURNS:  true, if the credit card number is a valid Discover
		    card number.
		    
	      false, otherwise

    Sample number: 6011000000000004 (16 digits)
    ================================================================ */

function isDiscover(cc)
{
  first4digs = cc.substring(0,4);
  if ((cc.length == 16) && (first4digs == "6011"))
    return isCreditCard(cc);
  return false;

} // END FUNCTION isDiscover()


/*  ================================================================
    FUNCTION:  isCardMatch()
 
    INPUT:    cardType - a string representing the credit card type
	      cardNumber - a string representing a credit card number

    RETURNS:  true, if the credit card number is valid for the particular
	      credit card type given in "cardType".
		    
	      false, otherwise
    ================================================================ */

function isCardMatch (cardType, cardNumber)
{

	cardType = cardType.toLowerCase();
	//Visa
	if ((cardType == "visa") && (isVisa(cardNumber)))
      return true;
		
	//MasterCard
	if ((cardType == "mastercard") && (isMasterCard(cardNumber)))
      return true;

	//American Express
	if(cardType == 'amex' && (isAmericanExpress(cardNumber)))
      return true;

	
   //Discover
	if ((cardType == "discover") && (isDiscover(cardNumber)))
      return true;

   return false;

}  // END FUNCTION CardMatch()

/*  ================================================================
    FUNCTION:  MatchCard()
 
    INPUT:   cardNumber - a string representing a credit card number

    RETURNS: type of card.
		    
    ================================================================ */

function MatchCard (cardNumber)
{

	var cardType;

	//Visa
	if (isVisa(cardNumber))
		cardType = "V";
		
	//MasterCard
	if (isMasterCard(cardNumber))
		cardType ="M";
		
	//American Express
	if (isAmericanExpress(cardNumber))
      cardType = "X";

   //Discover
	if (isDiscover(cardNumber))
		cardType = "N";

	return cardType;

}  // END FUNCTION MatchCard()


/***********************************************************************
Name: setFocus()
Description: This function sets the focus on a given element on the page
Parameters:	oElement - Control to set focus to.
Returns: n/a
Version:	Date	Author	Comments
		1	11/30/1999	Torben Pedersen	Initial Creation
		2	mm/dd/yyyy	Developer Name	Description of Changes
***********************************************************************/
function setFocus(oElement) 
{
	if (oElement) 
	{
		oElement.focus();
		if ( (oElement.value.length > 0) && (oElement.type == 'text' || oElement.type == 'textarea') ) 
		{	
			oElement.select();
		}
	}
}


/***********************************************************************
Name: NotImplemented()
Description: This function returns an alert dialog notifying the user
			 that the functionality has not been implemented.
Returns: n/a
Version:	Date	Author	Comments
		1	12/21/1999	Torben Pedersen	Initial Creation
		2	mm/dd/yyyy	Developer Name	Description of Changes
***********************************************************************/
function NotImplemented() 
{
	alert('This functionality has not been implemented.');
}

/***********************************************************************
Name: ToolTip()
Description: This function shows/hides a tooltip for the submitted id.
Returns: n/a
Version:	Date	Author	Comments
		1	12/22/1999	Torben Pedersen	Initial Creation
		2	mm/dd/yyyy	Developer Name	Description of Changes
***********************************************************************/
function ToolTip(id)
{
	if(id.style.visibility == 'hidden')	{
		id.style.backgroundColor = 'lightyellow';
		id.style.borderBottomColor = 'black';
		id.style.borderBottomStyle = 'double';
		id.style.borderLeftColor = 'black';
		id.style.borderLeftStyle = 'double';
		id.style.borderRightColor = 'black';
		id.style.borderRightStyle = 'double';
		id.style.borderTopColor = 'black';
		id.style.borderTopStyle = 'double';
		id.style.left = '55px';
		id.style.width = '193px';
		id.style.position = 'absolute';
		id.style.top = window.event.srcElement.parentElement.offsetTop + 127;
		id.style.zIndex = 999;
		id.style.visibility = 'visible'
	} else {
		id.style.visibility = 'hidden'
	}
}


/***********************************************************************
Name: isEmail()
Description: This function validates an email address in the form of a@b.c
Returns: TRUE if valid, FALSE otherwise
Version:	Date	Author	Comments
		1	mm/dd/yyyy	Developer Name	Description of Changes
		2	04/12/2000	Torben Pedersen	Changed function to check for additional validity
***********************************************************************/
function isEmail(e)
{   
		// checks for a vaild email
		// returns false for invalid addresses
		var i = 1;
		var j;
		var sLength = e.length;

		// check length
		if (sLength < 5) {
			return false;
			// a@b.c is shortest email
		}

		// look for @
		while ((i < sLength) && (e.charAt(i) != "@")) { 
			i++;
		}

		if ((i >= sLength) || (e.charAt(i) != "@")) return false;
		else i += 2;

		j = i;

		// has no "_" after the "@"
		while ((i < sLength) && (e.charAt(i) != "_")) {
			i++;
		}
		if ((i < sLength - 1) || (e.charAt(i) == "_")) return false;
		
		// look for . after the "@"
		while ((j < sLength) && (e.charAt(j) != ".")) { 
			j++;
		}

		// there must be at least one character after the .
		if ((j >= sLength - 1) || (e.charAt(j) != ".")) return false;

		// has no more than 3 chars after last "."
		i = sLength;
		while ((i > 0) && (e.charAt(i) != ".")) {
			i--;
		}
		if ((i <= 0) || (e.charAt(i) != ".")) return false;
		else i += 1;
		
		if ((sLength - i) > 3) return false;
		
		// has only one "@"
		j = 0;
		i = 0;
		while (i < sLength) {
			if (e.charAt(i) == "@") {
				j++;
			}
			i++;
		}
		if (j > 1) return false;

		// Check each Char for validity
		i = 0;
		while (i < sLength) {
			if ((!isLetterOrDigit(e.charAt(i))) && (e.charAt(i) != "_") && (e.charAt(i) != ".") && (e.charAt(i) != "@")	&& (e.charAt(i) != "-")) {
				return false;
			}
			i++;
		}
		return true;
}



/***********************************************************************
Name: isWhitespace()
Description: Returns true if string s is empty or whitespace characters only.
Version:	Date	Author	Comments
		1	mm/dd/yyyy	Developer Name	Description of Changes
***********************************************************************/
function isWhitespace (s)
{   var i;

    // Is s empty?
    if ((s == null) || (s.length == 0)) return true;

    // Search through string's characters one by one
    // until we find a non-whitespace character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);

        if (whitespace.indexOf(c) == -1) return false;
    }

    // All characters are whitespace.
    return true;
}

/***********************************************************************
Name: isEmpty()
Description: Check whether string s is empty.
Version:	Date	Author	Comments
		1	mm/dd/yyyy	Developer Name	Description of Changes
***********************************************************************/
function isEmpty(s)
{   
	// is s whitespace?	
    if (isWhitespace(s)) return true;
    
	//return ((s == null) || (s.length == 0))
}

/***********************************************************************
Name: isNonnegativeInteger()
Description: Returns true if string s is an integer >= 0.
Version:	Date	Author	Comments
		1	mm/dd/yyyy	Developer Name	Description of Changes
***********************************************************************/
function isNonnegativeInteger (s)
{   var secondArg = defaultEmptyOK;

    if (isNonnegativeInteger.arguments.length > 1)
        secondArg = isNonnegativeInteger.arguments[1];

    // The next line is a bit byzantine.  What it means is:
    // a) s must be a signed integer, AND
    // b) one of the following must be true:
    //    i)  s is empty and we are supposed to return true for
    //        empty strings
    //    ii) this is a number >= 0

    return (isSignedInteger(s, secondArg)
         && ( (isEmpty(s) && secondArg)  || (parseInt (s) >= 0) ) );
}

/***********************************************************************
Name: isSignedInteger()
Description: Returns true if all characters are numbers; 
			 first character is allowed to be + or - as well.
Version:	Date	Author	Comments
		1	mm/dd/yyyy	Developer Name	Description of Changes
***********************************************************************/
function isSignedInteger (s)
{   if (isEmpty(s)) 
       if (isSignedInteger.arguments.length == 1) return defaultEmptyOK;
       else return (isSignedInteger.arguments[1] == true);

    else {
        var startPos = 0;
        var secondArg = defaultEmptyOK;

        if (isSignedInteger.arguments.length > 1)
            secondArg = isSignedInteger.arguments[1];

        // skip leading + or -
        if ( (s.charAt(0) == "-") || (s.charAt(0) == "+") )
           startPos = 1;    
        return (isInteger(s.substring(startPos, s.length), secondArg))
    }
}

/***********************************************************************
Name: isInteger()
Description: Returns true if all characters in string s are numbers.
Version:	 Date	Author	Comments
		1	mm/dd/yyyy	Developer Name	Description of Changes
***********************************************************************/
function isInteger (s)
{   var i;

    if (isEmpty(s)) 
       if (isInteger.arguments.length == 1) return defaultEmptyOK;
       else return (isInteger.arguments[1] == true);

    // Search through string's characters one by one
    // until we find a non-numeric character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character is number.
        var c = s.charAt(i);

        if (!isDigit(c)) return false;
    }

    // All characters are numbers.
    return true;
}

/***********************************************************************
Name: isDigit()
Description: Returns true if character c is a digit (0 .. 9).
Version:	 Date	Author	Comments
		1	mm/dd/yyyy	Developer Name	Description of Changes
***********************************************************************/
function isDigit (c)
{   return ((c >= "0") && (c <= "9"))
}

/***********************************************************************
Name: isLetter()
Description: Returns true if character c is a leter (A .. Z) or (a .. z).
Version:	 Date	Author	Comments
		1	mm/dd/yyyy	Developer Name	Description of Changes
***********************************************************************/
function isLetter (c)
{   return ( ((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")) )
}

/***********************************************************************
Name: isLetterOrDigit()
Description: Returns true if character c is a letter or digit.
Version:	 Date	Author	Comments
		1	mm/dd/yyyy	Developer Name	Description of Changes
***********************************************************************/
function isLetterOrDigit (c)
{   return (isLetter(c) || isDigit(c))
}


/***********************************************************************
Name: isValidText()
Description: Returns true if string s does not contain invalid characters.
			 The invalid charaters are defined at the top of this file
Version:	Date		Author			Comments
		1	6/7/00		Toby Rush		Creation
**********************************************************************/
function isValidText (s)
{  	var result
	result = rgPattern.exec(s)

	if (result == null)
		{return true}
	else
		{return result[0]}

}


/***********************************************************************
Name: isPositiveInteger()
Description: Returns true if string s is an integer > 0.
Version:	 Date	Author	Comments
		1	mm/dd/yyyy	Developer Name	Description of Changes
***********************************************************************/
function isPositiveInteger (s)
{   var secondArg = defaultEmptyOK;

    if (isPositiveInteger.arguments.length > 1)
        secondArg = isPositiveInteger.arguments[1];

    // The next line is a bit byzantine.  What it means is:
    // a) s must be a signed integer, AND
    // b) one of the following must be true:
    //    i)  s is empty and we are supposed to return true for
    //        empty strings
    //    ii) this is a positive, not negative, number

    return (isSignedInteger(s, secondArg)
         && ( (isEmpty(s) && secondArg)  || (parseInt (s) > 0) ) );
}

/***********************************************************************
Name: isTime()
Description: Returns true if string s is in the time format of HH:MM.
Version:	 Date		Author			Comments
		1	3/4/2000	Torben Pedersen	Initial Creation
***********************************************************************/
function isTime(s) 
{
	// is s empty?
	if (isEmpty(s)) return false;

	// is s whitespace?
	if (isWhitespace(s)) return false;

	// there must be a : to separate hours and minutes.
	var i = 1;
	var sLength = s.length;
		
	// look for :
	while ((i < sLength) && (s.charAt(i) != ":"))
	{ 
		i++;
	}

	if (i >= sLength) return false;
		
	// check that the hours fall between 00 and 23 and the minutes between 00 and 59
	var arTime = new Array();
	arTime = s.split(":");

	if (arTime[0].length != 2) return false;
	if (!isNonnegativeInteger(arTime[0])) return false;
	if (arTime[0] > 23) return false;
		
	// check minutes
	if (arTime[1].length != 2) return false;
	if (!isNonnegativeInteger(arTime[1])) return false;
	if (arTime[1] > 59) return false
		
	return true;
}

/***********************************************************************
Name: isDate()
Description: isDate returns true if string arguments year, month, and day 
			 form a valid date.
Version:	 Date		Author			Comments
		1	
***********************************************************************/
function isDate (year, month, day)
{   // catch invalid years (not 2- or 4-digit) and invalid months and days.
    if (! (isYear(year, false) && isMonth(month, false) && isDay(day, false))) return false;

    // Explicitly change type to integer to make code work in both
    // JavaScript 1.1 and JavaScript 1.2.
    var intYear = parseInt(year);
    var intMonth = parseInt(month);
    var intDay = parseInt(day);

    // catch invalid days, except for February
    if (intDay > daysInMonth[intMonth]) return false; 

    if ((intMonth == 2) && (intDay > daysInFebruary(intYear))) return false;

    return true;
}

/***********************************************************************
Name: isYear()
Description: isYear returns true if string s is a valid Year number.  
			 Must be 2 or 4 digits only.
Version:	 Date		Author			Comments
		1	
***********************************************************************/
function isYear (s)
{   if (isEmpty(s)) 
       if (isYear.arguments.length == 1) return defaultEmptyOK;
       else return (isYear.arguments[1] == true);
    if (!isNonnegativeInteger(s)) return false;
    return ((s.length == 2) || (s.length == 4));    
}

/***********************************************************************
Name: isMonth()
Description: isMonth returns true if string s is a valid month number 
			 between 1 and 12.
Version:	 Date		Author			Comments
		1	
***********************************************************************/
function isMonth (s)
{   if (isEmpty(s)) 
       if (isMonth.arguments.length == 1) return defaultEmptyOK;
       else return (isMonth.arguments[1] == true);
    return isIntegerInRange (s, 1, 12);
}

/***********************************************************************
Name: isDay()
Description: isDay returns true if string s is a valid day number between 
			 1 and 31.
Version:	 Date		Author			Comments
		1	
***********************************************************************/
function isDay (s)
{   
	if (isEmpty(s)) 
       if (isDay.arguments.length == 1) return defaultEmptyOK;
       else return (isDay.arguments[1] == true);   
    return isIntegerInRange (s, 1, 31);
}

/***********************************************************************
Name: isIntegerInRange()
Description: isIntegerInRange returns true if string s is an integer 
			 within the range of integer arguments a and b, inclusive.
Version:	 Date		Author			Comments
		1	
***********************************************************************/
function isIntegerInRange (s, a, b)
{   if (isEmpty(s)) 
       if (isIntegerInRange.arguments.length == 1) return defaultEmptyOK;
       else return (isIntegerInRange.arguments[1] == true);

    // Catch non-integer strings to avoid creating a NaN below,
    // which isn't available on JavaScript 1.0 for Windows.
    if (!isInteger(s, false)) return false;

    // Now, explicitly change the type to integer via parseInt
    // so that the comparison code below will work both on 
    // JavaScript 1.2 (which typechecks in equality comparisons)
    // and JavaScript 1.1 and before (which doesn't).
	
	// Torben Pedersen - 3/9/2000
	// In JavaScript placing a leading 0 in front of a number designates 
	// that number as octal. In octal, there is no 08 or 09. Therefore, 
	// these numbers are interpreted as 0 when calling parseInt. 
	// parseVal(val) resolves this from MSDN.
	
	s = parseVal(s)    
	var num = parseInt (s);
    return ((num >= a) && (num <= b));
}

/***********************************************************************
Name: parseVal()
Description: Strips leading zeros.  Workaround to calling parseInt for
			 08 and 09.
Version:	 Date		Author			Comments
		1	
***********************************************************************/
function parseVal(val)
{
   while (val.charAt(0) == '0')
      val = val.substring(1, val.length);
   return val;
} 

/***********************************************************************
Name: daysInFebruary()
Description: Given integer argument year, returns number of days in 
			 February of that year.
Version:	 Date		Author			Comments
		1	
***********************************************************************/
function daysInFebruary (year)
{   // February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (  ((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0) ) ) ? 29 : 28 );
}

/***********************************************************************
Name: getRadioButtonValue(radio)
Description: Radio button as an input, returns the radio buttons value.
Version:	 Date		Author			Comments
		1	
***********************************************************************/
function getRadioButtonValue (radio)
{   for (var i = 0; i < radio.length; i++)
    {   if (radio[i].checked) { break }
    }
    return radio[i].value}

/***********************************************************************
Name: replaceDQuote(f)
Description: Replaces Double Quotes with a single quote.
Version:	 Date		Author			Comments
		1	4/9/2000	Torben Pedersen	Initial Creation
***********************************************************************/
function replaceDQuote(f) {
	var i, ret;
	for (i=0;i<f.length;i++) {
		if (f[i].type == 'text') {
			ret = f[i].value.lastIndexOf('"');
			if (ret != -1) {
				f[i].value = f[i].value.replace('"', '\'');
				i--;
			}
		}
	}
}

/***********************************************************************
Name: formatDate(d)
Description: formats a date to mm/dd/yyy.
Version:	 Date		Author			Comments
		1	4/14/2000	Torben Pedersen	Initial Creation
***********************************************************************/
function formatDate(d) {
	var arDate = d.split("/");
	if (arDate[0].length == 1) {
		arDate[0] = 0 + arDate[0];
	}
		
	if (arDate[1].length == 1) {
		arDate[1] = 0 + arDate[1];
	}
		
	if (arDate[2].length == 2) {
		arDate[2] = 20 + arDate[2];
	}
	return arDate[0] + '/' + arDate[1] + '/' + arDate[2];
}

/***********************************************************************
Name: formatTime(t)
Description: formats a time to hh:mm.
Version:	 Date		Author			Comments
		1	4/14/2000	Torben Pedersen	Initial Creation
***********************************************************************/
function formatTime(t) {
	var strTime = t;
	var i, blnFound;
	switch (t.length) {
	case 1:	
		strTime = '0' + t + ':00';
		break;
	case 2:
		strTime = '00:' + t;
		break;
	case 3:
		strTime = '0' + t.substring(0,1) + ':' + t.substring(1,3);
		break;
	case 4:
		blnFound = false;
		for(i=0;i<t.length;i++) {
			if (t.charAt(i) == ':') {
				blnFound = true;
			}
		} 
		if (blnFound) {
			strTime = '0' + t;
		} else {
			strTime = t.substring(0,2) + ':' + t.substring(2,4);
		}
		break;
	}
	return strTime;
}

/***********************************************************************
Name: formatPhone(fldPN)
Description: formats a phone number to (###)###-#### #####
Version:	 Date		Author			Comments
		1	9/13/00		Toby Rush		Initial Creation
***********************************************************************/
function formatPhone(fldPN){
	var strippedPN
	var formattedPN
	strippedPN = ""

	if (!isEmpty(fldPN.value)){
		//Loop through phone number and strip out all non integers
		for (i = 0; i < fldPN.value.length; i++)
		{   
	        // Check that current character is number.
	        var c = fldPN.value.charAt(i);
			//Strip all characters that aren't integers
	        if (isInteger(c)){
				strippedPN = strippedPN + c;
	        }
		}
		
		//If user entered a 1 at the begining of the phone number, then take off
		if (strippedPN.charAt(0) == "1"){
			strippedPN = strippedPN.substring(1,strippedPN.length);
		}
		
		if (!isEmpty(strippedPN)){
			//Reformat number in (###)###-#### ###
			formattedPN = "("+ strippedPN.substring(0,3) + ")" + strippedPN.substring(3,6) + "-" + strippedPN.substring(6,10) + " " + strippedPN.substring(10,strippedPN.length);

			//Ensure that phone number is not longer than 20 characters
			if (formattedPN.length > 20){
				formattedPN = formattedPN.substring(0,20)					
			}
			
			fldPN.value = formattedPN;
		}else{
			fldPN.value = "";
		}
		
		return;
	}
}


/***********************************************************************
Name: formatMoney(val)
Description: formats a number to $###,###.## format
Version:	 Date		Author			Comments
		1	6/13/01		Evan Peterson	Initial Creation
		2   6/14/2001   Evan Peterson   Added check to allow a negative sign
***********************************************************************/
function formatMoney(val)
{
	var strAmt = new String(val);
	var strFormatted = new String('');
	var blnNegativeFound = false;	
	
	//strip dollar sign
	if (strAmt.charAt(0) == "$") {
		strAmt = strAmt.substring(1, strAmt.length);
	}
	
	//make sure value is valid money amount
	if (isMoney(strAmt)) {
		//format the currency.
		var j = 0;

		//remove commas		
		strAmt = strAmt.replace(/,/g, "");

		//count number of commas, if find a negative sign strip it and set flag to true
		for(i=0;i<strAmt.length;i++) {
			if (strAmt.charAt(i) == ".") {
				j++;
			}
			if (strAmt.charAt(i) == "-") {
				blnNegativeFound=true;
				strAmt = strAmt.replace(/-/g, "");
			}
		}
				
		//pad/strip the decimals
		if (j == 0) {
			strAmt = (strAmt + ".00");
		} else {
			j = (strAmt.length - strAmt.search(/\./g));
			if (j == 2) {
				strAmt = strAmt + "0";
			} else {
				strAmt = (strAmt.substring(0, (strAmt.length - (j - 3))));
			}
		}

		//add commas if number is over 999
		if(strAmt.length > 6) {
			var strlength=strAmt.length - 3;
			for(i=1;i<=strlength;i++) {
				if((strlength - i)%3==0 && i!=strlength) {
					strFormatted=strFormatted + strAmt.charAt(i - 1) + ',';
				}
				else {
					strFormatted=strFormatted + strAmt.charAt(i - 1);
				}
				
			}	
			strFormatted += strAmt.substring(strAmt.length - 3);
		} else {
			strFormatted = strAmt;
		}		
		
	}
	
	strFormatted='$' + strFormatted;
	
	if(blnNegativeFound) {
		strFormatted='-' + strFormatted;
	}
	
	return strFormatted
}

/***********************************************************************
Name: formatCurrency(val)
Description: formats a number to #.## format
Version:	 Date		Author			Comments
		1	3/14/01		Your name here	Initial Creation
***********************************************************************/
function formatCurrency(val)
{
	var strAmt = new String(val);
	
	//strip dollar sign
	if (strAmt.charAt(0) == "$") {
		strAmt = strAmt.substring(1, strAmt.length);
	}
	
	//make sure value is valid money amount
	if (isMoney(strAmt)) {
		//format the currency.
		var j = 0;

		//remove commas		
		strAmt = strAmt.replace(/,/g, "");

		for(i=0;i<strAmt.length;i++) {
			if (strAmt.charAt(i) == ".") {
				j++;
			}
		}
				
		//pad/strip the decimals
		if (j == 0) {
			strAmt = (strAmt + ".00");
		} else {
			j = (strAmt.length - strAmt.search(/\./g));
			if (j == 2) {
				strAmt = strAmt + "0";
			} else {
				strAmt = (strAmt.substring(0, (strAmt.length - (j - 3))));
			}
		}
	}
	
	return strAmt;
}


/***********************************************************************
Name: isMoney(c)
Description: Returns true if character c is a digit (0 .. 9) or a . or , .
Version:	 Date		Author			Comments
		1	4/17/2000	Matt Killian	Initial Creation
		2	3/5/2000	Kim Gentry		Added check for dollar sign
		3   6/13/2001   Evan Peterson	Added check for more than 2 digits to the right of a decimal
		4   6/14/2001   Evan Peterson   Added check to allow a negative sign
***********************************************************************/
function isMoney(c) {
	var blnMoney = true;
	var j = 0;
	
	for(i=0;i<c.length;i++) {
		if (!(((c.charAt(i) >= 0) && (c.charAt(i) <= 9)) || (c.charAt(i) == '-') || (c.charAt(i) == '$') || (c.charAt(i) == '.') || (c.charAt(i) == ','))) {			
			blnMoney = false;
			break;
		}
		// Count the .
		if (c.charAt(i) == '.') {
			j++;
			if (j > 1) {
				blnMoney = false;
				break;
			}
			if(c.length > (i + 3)) {
				blnMoney = false;
				break;
			}
		}
	}
	return blnMoney;
}

/***********************************************************************
Name: isFloat(c)
Description: Returns true if character c is a digit (0 .. 9) or a . 
Version:	 Date		Author			Comments
		1	11/27/2000	Toby Rush		Initial Creation
***********************************************************************/
function isFloat(c) {
	var blnFloat = true;
	var j = 0;

	//Trim all white spaces
	c = trimWhiteSpace(c)

	//Check that field is not empty
	if (isEmpty(c)){
		blnFloat = false;
	}


	//Check that each digit is a number or a period
	for(i=0;i<c.length;i++) {
		if (!(((c.charAt(i) >= 0) && (c.charAt(i) <= 9)) || (c.charAt(i) == '.'))) {			
			blnFloat = false;
			break;
		}
	}

	//Check to see if the value is only one digit and ensure that it is not a period
	if (c.length == 1 && c == '.'){
		blnFloat = false;
	}
	
	
	return blnFloat;
}

/***********************************************************************
Name: isDate2(d)
Description: Returns true if the date is valid.
Version:	 Date		Author			Comments
		1	4/18/2000	Torben Pedersen	Initial Creation
***********************************************************************/
function isDate2(d) {
	var j = 0;
	//contains /
	for(i=0;i<d.length;i++) {
		if(d.charAt(i) == '/') {
			j++;
		}
	}
	if(j!=2) {
		return false;
	}
	var arDate = d.split("/");
	return (isDate(arDate[2], arDate[0], arDate[1]));
}


/***********************************************************************
Name: trimWhiteSpace(s)
Description: Takes a string and strips white spaces
Version:	 Date		Author			Comments
		1	 8/1/00		Toby Rush		Initial Creation
***********************************************************************/
function trimWhiteSpace(s){
var s2
var re

//Define the regular expresion
re = /\s/g;
//Replace all white space characters with an emtpy string
s.replace(re,"");

return(s.replace(re,""));
}


/***********************************************************************
Name: ExternalSite
Description: Opens the URL in an external window.
Version:	 Date		Author			Comments
		1	8/3/2000	Torben Pedersen	Initial Creation
***********************************************************************/
function ExternalSite(url)
{
	window.open(url,"bol","directories=0,height=500,width=790,location=yes,menubar=yes,resizable=yes,scrollbars=yes,status=yes,toolbar=yes")
}


/***********************************************************************
Name: checkForValue
Description: Checks the target control for a value
			 Returns sErrMsg if no value and sets focus on the control
***********************************************************************/
function checkForValue(ctrlTarget, sErrMsg) {
	var sOut = "";
	
	// Check for simple string value
	if (isEmpty(ctrlTarget.value)) {
		ctrlTarget.focus();
		sOut = sErrMsg + "\n";
	}
	
	return sOut;
}

function checkForEmptyString(sIn, sErrMsg) {
	var sOut = "";
	
	// Check for simple string value
	if (isEmpty(sIn)) {
		sOut = sErrMsg + "\n";
	}
	
	return sOut;
}

function checkForDate(ctrlTarget, sErrMsg) {
	var sOut = "";

	if (!isDate2(ctrlTarget.value)) {
		ctrlTarget.focus();
		sOut += sErrMsg + "\n";
	}

	return sOut;
}

function checkForMoney(ctrlTarget, sErrMsg) {
	var sOut = "";

	sOut = checkForValue(ctrlTarget, sErrMsg);
	
	if (sOut == "") {
		if (!isMoney(ctrlTarget.value)) {
			sOut += sErrMsg + "\n";
		}

		ctrlTarget.focus();
	}
	
	return sOut;
}

var objFormHandle

function SetFormHandle(objFormName){
	objFormHandle=objFormName;
	return true;
}

function GetFormHandle(){
	return objFormHandle;
}

function OpenLookup(strLookupName, objForm){
	var objLookup;

	SetFormHandle(objForm);
	objLookup=window.open(strLookupName,'Lookup','height=400,menubar=no,resizable=yes,scrollbars=yes,toolbar=no,width=470');
	objLookup.focus();
	return true;
}

function OpenLookupResize(strLookupName, objForm, h, w){
	var objLookup;

	SetFormHandle(objForm);
	objLookup=window.open(strLookupName,'Lookup','height=' + h + ',width=' + w + ',menubar=no,resizable=yes,scrollbars=yes,toolbar=no');
	objLookup.focus();
	return true;
}

function OpenLookupModal(strUrl)
{
	var yheight = document.body.clientHeight;
	var xwidth = document.body.clientWidth;
	var sFeatures = "resizable:yes;dialogHeight:" + yheight + "px;dialogWidth:" + xwidth + "px;dialogLeft=10px;dialogTop=5px";

	window.showModalDialog(strUrl, "", sFeatures);
}

function roundMoney(amt)
{
	return Math.round(amt * 100) / 100;
}

function divShowHide(target, blnShow)
{
	if (blnShow) {
		target.style.visibility = "visible";
		target.style.display = "inline";
	} else {
		target.style.visibility = "hidden";
		target.style.display = "none";
	}
}



