// FormChek.js
//
// SUMMARY
//
// This is a set of JavaScript functions for validating input on
// an HTML form.
//
//
// Supporting utility functions validate that:
//
//      - characters are Letter, Digit, or LetterOrDigit
//      - strings are a Signed, Positive, Negative, Nonpositive, or
//        Nonnegative integer
//      - strings are Alphabetic, Alphanumeric, or Whitespace
//
// Functions are also provided to interactively check the
// above kinds of data and prompt the user if they have
// been entered incorrectly.
//
// Other utility functions are provided to:
//
//
// Many of the below functions take an optional parameter eok (for "emptyOK")
// which determines whether the empty string will return true or false.
// Default behavior is controlled by global variable defaultEmptyOK.
//
// BASIC DATA VALIDATION FUNCTIONS:
//
// isWhitespace (s)                    Check whether string s is empty or whitespace.
// isLetter (c)                        Check whether character c is an English letter
// isDigit (c)                         Check whether character c is a digit
// isLetterOrDigit (c)                 Check whether character c is a letter or digit.
// isInteger (s [,eok])                True if all characters in string s are numbers.
// isSignedInteger (s [,eok])          True if all characters in string s are numbers; leading + or - allowed.
// isPositiveInteger (s [,eok])        True if string s is an integer > 0.
// isNonnegativeInteger (s [,eok])     True if string s is an integer >= 0.
// isNegativeInteger (s [,eok])        True if s is an integer < 0.
// isNonpositiveInteger (s [,eok])     True if s is an integer <= 0.
// isAlphabetic (s [,eok])             True if string s is English letters
// isAlphanumeric (s [,eok])           True if string s is English letters and numbers only.
//
// isInternationalPhoneNumber (s [,eok]) True if string s is a valid international phone number.
// isEmail (s [,eok])                  True if string s is a valid email address.
// isValidEnglishName (s)	       True if string s is English letters with spaces

// FUNCTIONS TO REFORMAT DATA:
//
// stripCharsInBag (s, bag)            Removes all characters in string bag from string s.
// stripCharsNotInBag (s, bag)         Removes all characters NOT in string bag from string s.
// stripWhitespace (s)                 Removes all whitespace characters from s.
// stripInitialWhitespace (s)          Removes initial (leading) whitespace characters from s.
// reformat (TARGETSTRING, STRING,     Function for inserting formatting characters or
//   INTEGER, STRING, INTEGER ... )       delimiters into TARGETSTRING.


// FUNCTIONS TO PROMPT USER:
//
// prompt (s)                          Display prompt string s in status bar.
// promptEntry (s)                     Display data entry prompt string s in status bar.
// warnEmpty (theField, s)             Notify user that required field theField is empty.
// warnInvalid (theField, s)           Notify user that contents of field theField are invalid.


// FUNCTIONS TO INTERACTIVELY CHECK FIELD CONTENTS:
//
// checkString (theField, s [,eok])    Check that theField.value is not empty or all whitespace.
// checkInteger(theField, s [,eok])       Check that theField.value is an integer.
//

var EnglishLang = "1";
var ChineseLang = "2";
var SimchinLang = "3";
var selectedLanguage = EnglishLang;

// VARIABLE DECLARATIONS

var digits = "0123456789";

var lowercaseLetters = "abcdefghijklmnopqrstuvwxyz"
var uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
var charSet="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&'()*+,-./:<=>?@\^_`~ ";


// whitespace characters
var whitespace = " \t\n\r";

// CONSTANT STRING DECLARATIONS
// (grouped for ease of translation and localization)

// m is an abbreviation for "missing"

var mPrefix = "You did not enter a value into the "
var mSuffix = " field. This is a required field. Please enter it now."
var mInteger  = " field must be an integer. Please re-enter it now."
var mAmount = " field must be in dollar (e.g. 1234 for $1,234.50). Please re-enter it now."
var mAmount_cents = " field must be in cents (e.g. 50 for $1,234.50). Please re-enter it now."
var mLength1 = " field must be "
var mLength2 = " digit long. Please re-enter it now."

// s is an abbreviation for "string"
var sPPSAccountNumber   = "PPS Account Number"
var sMerchantCode       = "Merchant Code"
var sBillNumber         = "Bill Number"
var sMerchantName       = "Merchant Name"
var sBillNo             = "Bill Number"
var sInitPIN		= "PPS Access Code"
var sPIN                = "PPS Internet Password"
var sPaymentAmount      = "Payment Amount"

// i is an abbreviation for "invalid"

var iPPSAccountNumber   = "This field must be a valid PPS account number. Please re-enter it now."
var iInteger            = "This field must be an integer. Please re-enter it now."
var iInternetPassword   = "PPS Internet Password must be 8 to 28 alphanumeric characters. Please re-enter it now. "		//SS++
//-- 25 Sept 01 var iChangeInitPassword = "If you have not changed your 5-digit PPS Access Code to Internet Password yet, please do it now."		//SS++
//-- 03 Mar 2003var iChangeInitPassword = "You cannot use your 5-digit PPS Access Code to process transaction in this site. Please set up PPS Internet Password in designated PPS Registration Terminal. Click the 'SET UP PPS INTERNET PASSWORD' to find the nearest terminal."
var iChangeInitPassword = "You cannot use your 5-digit PPS Phone Password to process transaction in this site.  Please refer 'HOW TO SET UP PPS INTERNET PASSWORD' for details."
//-- 25 Sept 01 var iChangePGPassword   = iInternetPassword + "If you have not changed your 5-digit PPS Access Code to Internet Password yet, please click \'OK\' to go to www.ppshk.com and set up your PPS Internet Password first."	
var iChangePGPassword =   iInternetPassword + "If you have not changed your 5-digit PPS Access Code to Internet Password yet, please set up a PPS Internet Password in designated PPS Registration Terminal."	

// p is an abbreviation for "prompt"

var pEntryPrompt = "Please enter a "

var pPaymentAmount      = "Payment Amount, maximum 2 decimal places are allowed (e.g. $1234, $1234.50)"
var pPaymentAmount_cents= "Payment Amount in cents (e.g. 50 for $1,234.50)"

var pRegister           = "To register a bill number"
var pPayment            = "To pay a bill"
var pEnquire            = "To display the registered bill number"
var pEnquireLast        = "To review the last payment details for a particular bill"
var pCancel             = "To cancel a registered bill number"
var pPayForm            = "Click a bill number to display the payment form"
var pPPSAccountNumber   = "PPS Account Number"
var pMerchantCode       = "Merchant Code. Leading zero is not required."
var pBillNumber         = "Bill Number"
var pMerchantName       = "Please select a Merchant Name"
var pPIN                = "Please enter a PPS Internet Password"


// Global variable defaultEmptyOK defines default return value
// for many functions when they are passed the empty string.
// By default, they will return defaultEmptyOK.
//
// defaultEmptyOK is false, which means that by default,
// these functions will do "strict" validation.
//
// You can change this default behavior globally (for all
// functions which use defaultEmptyOK) by changing the value
// of defaultEmptyOK.
//
// Most of these functions have an optional argument emptyOK
// which allows you to override the default behavior for
// the duration of a function call.
//
// This functionality is useful because it is possible to
// say "if the user puts anything in this field, it must
// be an integer (or a phone number, or a string, etc.),
// but it's OK to leave the field empty too."
// This is the case for fields which are optional but which
// must have a certain kind of content if filled in.

var defaultEmptyOK = false

// Check whether string s is empty.

function isEmpty(s)
{   return ((s == null) || (s.length == 0))
}



// Returns true if string s is empty or
// whitespace characters only.

function isWhitespace (s)

{   var i;

    // Is s empty?
    if (isEmpty(s)) 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;
}




// Removes all whitespace characters from s.
// Global variable whitespace (see above)
// defines which characters are considered whitespace.

function stripWhitespace (s)

{   return stripCharsInBag (s, whitespace)
}



// Removes initial (leading) whitespace characters from s.
// Global variable whitespace (see above)
// defines which characters are considered whitespace.

function stripInitialWhitespace (s)

{   var i = 0;

    while ((i < s.length) && charInString (s.charAt(i), whitespace))
       i++;

    return s.substring (i, s.length);
}


// Returns true if string s is English letters
// (A .. Z, a..z) or " " only.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.
//
// NOTE: Need i18n version to support European characters.
// This could be tricky due to different character
// sets and orderings for various languages and platforms.

function isValidEnglishName (s)

{   var i;

    if (isEmpty(s))
       if (isAlphabetic.arguments.length == 1) return defaultEmptyOK;
       else return (isAlphabetic.arguments[1] == true);

    // Search through string's characters one by one
    // until we find a non-alphabetic character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {
        // Check that current character is letter.
        var c = s.charAt(i);

        if (!isLetter(c) && (c !=" "))
        return false;
    }

    // All characters are letters.
    return true;
}




// Returns true if character c is an English letter
// (A .. Z, a..z).
//
// NOTE: Need i18n version to support European characters.
// This could be tricky due to different character
// sets and orderings for various languages and platforms.

function isLetter (c)
{   return ( ((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")) )
}



// Returns true if character c is a digit
// (0 .. 9).

function isDigit (c)
{   return ((c >= "0") && (c <= "9"))
}



// Returns true if character c is a letter or digit.

function isLetterOrDigit (c)
{   return (isLetter(c) || isDigit(c))
}




// Returns true if string s is English letters
// (A .. Z, a..z) only.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.
//
// NOTE: Need i18n version to support European characters.
// This could be tricky due to different character
// sets and orderings for various languages and platforms.

function isAlphabetic (s)

{   var i;

    if (isEmpty(s))
       if (isAlphabetic.arguments.length == 1) return defaultEmptyOK;
       else return (isAlphabetic.arguments[1] == true);

    // Search through string's characters one by one
    // until we find a non-alphabetic character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++)
    {
        // Check that current character is letter.
        var c = s.charAt(i);

        if (!isLetter(c))
        return false;
    }

    // All characters are letters.
    return true;
}




// isAlphanumeric (STRING s [, BOOLEAN emptyOK])
//
// Returns true if string s is English letters
// (A .. Z, a..z) and numbers only.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.
//
// NOTE: Need i18n version to support European characters.
// This could be tricky due to different character
// sets and orderings for various languages and platforms.

function isAlphanumeric (s)

{   var i;

    if (isEmpty(s))
       if (isAlphanumeric.arguments.length == 1) return defaultEmptyOK;
       else return (isAlphanumeric.arguments[1] == true);

    // Search through string's characters one by one
    // until we find a non-alphanumeric 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 or letter.
        var c = s.charAt(i);

        if (! (isLetter(c) || isDigit(c) ) )
        return false;
    }

    // All characters are numbers or letters.
    return true;
}


// isInteger (STRING s [, BOOLEAN emptyOK])
//
// Returns true if all characters in string s are numbers.
//
// Accepts non-signed integers only. Does not accept floating
// point, exponential notation, etc.
//
// We don't use parseInt because that would accept a string
// with trailing non-numeric characters.
//
// By default, returns defaultEmptyOK if s is empty.
// There is an optional second argument called emptyOK.
// emptyOK is used to override for a single function call
//      the default behavior which is specified globally by
//      defaultEmptyOK.
// If emptyOK is false (or any value other than true),
//      the function will return false if s is empty.
// If emptyOK is true, the function will return true if s is empty.
//
// EXAMPLE FUNCTION CALL:     RESULT:
// isInteger ("5")            true
// isInteger ("")             defaultEmptyOK
// isInteger ("-5")           false
// isInteger ("", true)       true
// isInteger ("", false)      false
// isInteger ("5", false)     true

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;
}


// isSignedInteger (STRING s [, BOOLEAN emptyOK])
//
// Returns true if all characters are numbers;
// first character is allowed to be + or - as well.
//
// Does not accept floating point, exponential notation, etc.
//
// We don't use parseInt because that would accept a string
// with trailing non-numeric characters.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.
//
// EXAMPLE FUNCTION CALL:          RESULT:
// isSignedInteger ("5")           true
// isSignedInteger ("")            defaultEmptyOK
// isSignedInteger ("-5")          true
// isSignedInteger ("+5")          true
// isSignedInteger ("", false)     false
// isSignedInteger ("", true)      true

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))
    }
}






// reformat (TARGETSTRING, STRING, INTEGER, STRING, INTEGER ... )
//
// Handy function for arbitrarily inserting formatting characters
// or delimiters of various kinds within TARGETSTRING.
//
// reformat takes one named argument, a string s, and any number
// of other arguments.  The other arguments must be integers or
// strings.  These other arguments specify how string s is to be
// reformatted and how and where other strings are to be inserted
// into it.
//
// reformat processes the other arguments in order one by one.
// * If the argument is an integer, reformat appends that number
//   of sequential characters from s to the resultString.
// * If the argument is a string, reformat appends the string
//   to the resultString.
//
// NOTE: The first argument after TARGETSTRING must be a string.
// (It can be empty.)  The second argument must be an integer.
// Thereafter, integers and strings must alternate.  This is to
// provide backward compatibility to Navigator 2.0.2 JavaScript
// by avoiding use of the typeof operator.
//
// It is the caller's responsibility to make sure that we do not
// try to copy more characters from s than s.length.
//
// EXAMPLES:
//
// * To reformat a 10-digit U.S. phone number from "1234567890"
//   to "(123) 456-7890" make this function call:
//   reformat("1234567890", "(", 3, ") ", 3, "-", 4)
//
// * To reformat a 9-digit U.S. Social Security number from
//   "123456789" to "123-45-6789" make this function call:
//   reformat("123456789", "", 3, "-", 2, "-", 4)
//
// HINT:
//
// If you have a string which is already delimited in one way
// (example: a phone number delimited with spaces as "123 456 7890")
// and you want to delimit it in another way using function reformat,
// call function stripCharsNotInBag to remove the unwanted
// characters, THEN call function reformat to delimit as desired.
//
// EXAMPLE:
//
// reformat (stripCharsNotInBag ("123 456 7890", digits),
//           "(", 3, ") ", 3, "-", 4)

function reformat (s)

{   var arg;
    var sPos = 0;
    var resultString = "";

    for (var i = 1; i < reformat.arguments.length; i++) {
       arg = reformat.arguments[i];
       if (i % 2 == 1) resultString += arg;
       else {
           resultString += s.substring(sPos, sPos + arg);
           sPos += arg;
       }
    }
    return resultString;
}


// isPositiveInteger (STRING s [, BOOLEAN emptyOK])
//
// Returns true if string s is an integer > 0.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.

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) ) );
}




/* FUNCTIONS TO NOTIFY USER OF INPUT REQUIREMENTS OR MISTAKES. */


// Display prompt string s in status bar.

function prompt (s)
{   window.status = s
}



// Display data entry prompt string s in status bar.

function promptEntry (s)
{   window.status = pEntryPrompt + s
}

function promptString (s)
{   window.status = s
}




// Notify user that required field theField is empty.
// String s describes expected contents of theField.value.
// Put focus in theField and return false.

function warnEmpty (theField, s)
{   theField.focus()
    theField.select()
    alert(mPrefix + s + mSuffix)
    return false
}



// Notify user that contents of field theField are invalid.
// String s describes expected contents of theField.value.
// Put select theField, put focus in it, and return false.

function warnInvalid (theField, s)
{   theField.focus()
    theField.select()
    alert(s)
    return false
}




/* FUNCTIONS TO INTERACTIVELY CHECK VARIOUS FIELDS. */

// checkString (TEXTFIELD theField, STRING s, [, BOOLEAN emptyOK==false])
//
// Check that string theField.value is not all whitespace.
//
// For explanation of optional argument emptyOK,
// see comments of function isInteger.

function checkString (theField, s, emptyOK)
{   // Next line is needed on NN3 to avoid "undefined is not a number" error
    // in equality comparison below.
    if (checkString.arguments.length == 2) emptyOK = defaultEmptyOK;
    if ((emptyOK == true) && (isEmpty(theField.value))) return true;
    if (isWhitespace(theField.value))
       return warnEmpty (theField, s);
    else return true;
}

function checkInteger (theField, s, emptyOK)
{   if (checkInteger.arguments.length == 2) emptyOK = defaultEmptyOK;
    if ((emptyOK == true) && (isEmpty(theField.value))) return true;
    if (isWhitespace(theField.value))
       return warnEmpty (theField, s);
    if (!isInteger(theField.value, false))
       return warnInvalid (theField, s + mInteger);
    else return true;
}


function checkLength(theField, s, length)
{   if (theField.value.length != length)
	return warnInvalid (theField, s + mLength1 + length + mLength2);
    else return true;
}

function checkAcctNumber(accountNumber)
{
    return ( checkLength(accountNumber, sPPSAccountNumber, 8) &&
    		 checkString(accountNumber, sPPSAccountNumber) &&
		 checkInteger(accountNumber, sPPSAccountNumber) )
}

function checkInitPIN(pin)
{
    return ( checkLength(pin, sInitPIN, 5) &&
    		 checkString(pin, sInitPIN) &&
		 checkInteger(pin, sInitPIN) )
}

function checkNewPIN(pin)
{
    //SS++ To implement changing password function
    if (isEmpty(pin.value)) 
	return warnEmpty (pin, sPIN);

    //Validate PPS on Internet Password which is 8-28 alphanumeric characters
    if (pin.value.length < 8) {
	return warnInvalid(pin, iInternetPassword);
    } 

    if (pin.value.length > 28) {
	return warnInvalid(pin, iInternetPassword);
    } 
	 
    if (!isAlphanumeric(pin.value)) {
      return warnInvalid(pin, iInternetPassword)
    }

    return true
}

function checkPIN(pin)
{
    //SS++ To implement changing password function
    if (isEmpty(pin.value)) 
	return warnEmpty (pin, sPIN);
    //Assume did not change PPS Access Code to PPS on Internet Password
    if (pin.value.length == 5) {
	return warnInvalid(pin, iChangeInitPassword);
    } 

    //Validate PPS on Internet Password which is 8-28 alphanumeric characters
    if (pin.value.length < 8) {
	return warnInvalid(pin, iInternetPassword);
    } 

    if (pin.value.length > 28) {
	return warnInvalid(pin, iInternetPassword);
    } 
	 
    if (!isAlphanumeric(pin.value)) {
      return warnInvalid(pin, iInternetPassword)
    }

    return true;
}

//check PIN passed from other payment gateway (e.g.ESD, EIPO), 
//make sure the PIN have changed from 5 digits to 8-28 alphanumeric characters
function checkPGPIN(pin,language)
{
   if (isEmpty(pin.value)) 
	return warnEmpty (pin, sPIN);

/* ++ 04 Jan 2006
    if (pin.value.length == 5) {
	if (confirm(iChangePGPassword))
		window.open("http://www.eps.com.hk/shop&buy.html",'changePIN','left=0,top=0,menubar=no,status=yes,location=no,resizable=yes,scrollbars=no,toolbar=no,width=500,height=350');
*/
/*-- 25 Sept 01	    if (language==ChineseLang) {
               window.open("https://www.ppshk.com/index_c.html","changePIN");
	    } else {
               window.open("https://www.ppshk.com","changePIN");
*/
/* ++ 04 Jan 2006
        return false;
    } 
*/

    //Validate PPS on Internet Password which is 8-28 alphanumeric characters
    if (pin.value.length < 8) {
	return warnInvalid(pin, iInternetPassword);
    } 

    if (pin.value.length > 28) {
	return warnInvalid(pin, iInternetPassword);
    } 
	 
    if (!isAlphanumeric(pin.value)) {
      return warnInvalid(pin, iInternetPassword)
    }

    return true;
}

function setLanguage(lang)
{
    selectedLanguage = lang;
    if (lang == EnglishLang) {
        mPrefix = "You did not enter a value into the "
        mSuffix = " field. This is a required field. Please enter it now."
        mInteger  = " field must be an integer. Please re-enter it now."
        //mAmount = " field must be in dollar (e.g. 1234 for $1,234.00). Please re-enter it now."
        mAmount = " field must be in dollar. Please re-enter it now."
        mAmount_cents = " field must be in cents. Please re-enter it now."
        mLength1 = " field must be "
        mLength2 = " digit long. Please re-enter it now."

        sPPSAccountNumber   = "PPS Account Number"
        sMerchantCode       = "Merchant Code"
        sBillNumber         = "Bill Number"
        sMerchantName       = "Merchant Name"
        sBillNo             = "Bill Number"
        sPIN                = "PPS Internet Password"
        sPaymentAmount      = "Payment Amount"

        iPPSAccountNumber   = "This field must be a valid PPS account number. Please re-enter it now."
        iInteger            = "This field must be an integer. Please re-enter it now."
	iInternetPassword   = "PPS Internet Password must be 8 to 28 alphanumeric characters. Please re-enter it now. "		//SS++
//-- 25 Sept 01 	iChangeInitPassword = iInternetPassword + "If you have not changed your 5-digit PPS Access Code to Internet Password yet, please do it now."		//SS++
//-- 25 Sept 01 	iChangePGPassword =   iInternetPassword + "If you have not changed your 5-digit PPS Access Code to Internet Password yet, please click \'OK\' to go to www.ppshk.com and set up your PPS Internet Password first."	
//-- 03 Mar  03 	iChangeInitPassword = "You cannot use your 5-digit PPS Access Code to process transaction in this site. Please set up PPS Internet Password in designated PPS Registration Terminal. Click the 'SET UP PPS INTERNET PASSWORD' to find the nearest terminal."
	iChangeInitPassword = "You cannot use your 5-digit PPS Phone Password to process transaction in this site.  Please refer 'HOW TO SET UP PPS INTERNET PASSWORD' for details."
	iChangePGPassword =   iInternetPassword + "If you have not changed your 5-digit PPS Access Code to Internet Password yet, please set up a PPS Internet Password in designated PPS Registration Terminal."	

        pEntryPrompt        = "Please enter a "
        pPaymentAmount      = "Payment Amount in dollar (e.g. 1234 for $1,234.50)"
        pPaymentAmount_cents= "Payment Amount in cents (e.g. 50 for $1,234.50)"
        pRegister           = "To register a bill number"
        pPayment            = "To pay a bill"
        pEnquire            = "To display the registered bill number"
        pEnquireLast        = "To review the last payment details for a particular bill"
        pCancel             = "To cancel a registered bill number"
        pPayForm            = "Click a bill number to display the payment form"
        pPPSAccountNumber   = "PPS Account Number"
        pMerchantCode       = "Merchant Code. Leading zero is not required."
        pBillNumber         = "Bill Number"
        pMerchantName       = "Please select a Merchant Name"
        pPIN                = "Please enter a PPS Internet Password"
    } else {
	    if (lang == ChineseLang) {
			mPrefix = "»Õ¤U¨S¦³¦b³o"
			mSuffix = "Äæ¶ñ¤W©Ò¶·¸ê®Æ¡A½Ð­«·s¿é¤J¡C"
			mInteger  = "Äæ¥²¶·¬O¤@­Ó¾ã¼Æ¡C½Ð­«·s¿é¤J¡C"
			//mAmount = "Äæ¥²¶·¬O»È½X (¨Ò: 1234 ¥Nªí $1,234.00)¡C½Ð­«·s¿é¤J¡C"
			mAmount = "Äæ¥²¶·¬O¤¸(¨Ò: 1234 ¥Nªí $1,234.50)¡C½Ð­«·s¿é¤J¡C"
			mAmount_cents = "Äæ¥²¶·¬O¨¤(¨Ò: 50 ¥Nªí $1,234.50)¡C½Ð­«·s¿é¤J¡C"
			mLength1 = "Äæ¥²¶·¬O"
			mLength2 = "¦ìªø¡C½Ð­«·s¿é¤J¡C"
			
			sPPSAccountNumber   = "Ãº¶OÆF¤á¤f¸¹½X¡£¤K¦ì¼Æ¦r )"
			sMerchantCode       = "°Ó¤á½s¸¹"
			sBillNumber         = "½ã³æ¸¹½X"
			sMerchantName       = "°Ó¤á¦WºÙ"
			sBillNo             = "½ã³æ¸¹½X"
			sInitPIN            = "Ãº¶OÆF±K½X¡£¤­¦ì¼Æ¦r¡¤"
			sPIN                = "Ãº¶OÆFºô¤W±K½X"
			sPaymentAmount      = "Ãº¥Iª÷ÃB"
			
			iPPSAccountNumber   = "¦¹Äæ¥²¶·¬O¤@­Ó¦³®ÄªºÃº¶OÆF¤á¤f¸¹½X¡C½Ð­«·s¿é¤J¡C"
			iInteger            = "¦¹Äæ¥²¶·¬O¤@­Ó¾ã¼Æ¡C½Ð­«·s¿é¤J¡C"
			iInternetPassword   = "Ãº¶OÆFºô¤W±K½X¥²¶·¬O8-28¦ì¦r¥À©Î/¤Î¼Æ¦r¡A½Ð­«·s¿é¤J¡C"		
			//-- 25 Sept 01 	iChangeInitPassword = iInternetPassword + "­Õ­Y»Õ¤U¨Ã¥¼§ó§ïÃº¶OÆFºô¤W·s±K½X,½Ð«ö¥ªÃä¥Ø¿ý'³]©wÃº¶OÆFºô¤W±K½X'¡C"
			//-- 25 Sept 01 	iChangePGPassword =   "»Õ¤U©Ò¿é¤J¤§Ãº¶OÆFºô¤W±K½X»Ý­n¤K¦Ü¤Ü¤K­Ó¦ìªº­^¤å¦r¥À©Î/¤Î¼Æ¦r¤¤¶¡¤£¯à¦³ªÅ¦ì¡A­Õ­Y»Õ¤U¨Ã¥¼§ó§ïÃº¶OÆFºô¤W·s±K½X¡A½Ð¥ý«ö ¡u½T©w¡v ¨ìwww.ppshk.com³]©wÃº¶OÆFºô¤W±K½X¡C"
			//-- 03 mar 03	iChangeInitPassword = "»Õ¤U¥²¶·¨ì«ü©wªºÃº¶OÆF²×ºÝ¾÷³]©wÃº¶OÆFºô¤W±K½X¤~¥i¦b³oºô¯¸¶i¦æ¥æ©ö¡C½Ð«ö '³]©wÃº¶OÆFºô¤W±K½X' ¬d¸ß³Ìªñªº²×ºÝ¾÷¦a§}¡C"
			iChangeInitPassword = "»Õ¤Uªº¢´¦ì¼Æ¦rÃº¶OÆF¹q¸Ü±K½X¨Ã¤£¥i¦b³oºô¯¸¶i¦æ¥æ©ö¡C½Ð°Ñ¦Ò ' ¦p¦ó³]©wÃº¶OÆFºô¤W±K½X ' ¬d¸ß¸Ô±¡¡C"
			iChangePGPassword =   "»Õ¤U©Ò¿é¤J¤§Ãº¶OÆFºô¤W±K½X»Ý­n¤K¦Ü¤Ü¤K­Ó¦ìªº­^¤å¦r¥À©Î/¤Î¼Æ¦r¤¤¶¡¤£¯à¦³ªÅ¦ì¡A­Õ­Y»Õ¤U¨Ã¥¼§ó§ïÃº¶OÆFºô¤W·s±K½X¡A½Ð¥ý¨ì«ü©wªºÃº¶OÆF²×ºÝ¾÷³]©wÃº¶OÆFºô¤W±K½X¤~¥i¦b³oºô¯¸¶i¦æ¥æ©ö¡C"
			
			pEntryPrompt        = "½Ð¿é¤J"
			pPaymentAmount      = "Ãº¥Iª÷ÃB¥²¶·¬O¤¸(¨Ò: 1234 ¥Nªí $1,234.50)"
			pPaymentAmount_cents= "Ãº¥Iª÷ÃB¥²¶·¬O¨¤(¨Ò: 50 ¥Nªí $1,234.50)"
			pRegister           = "­nµn°O¤@­Ó½ã³æ¸¹½X"
			pPayment            = "­nÃº¥æ½ã³æ"
			pEnquire            = "­nÅã¥Ü©Òµn°O¤§½ã³æ¸¹½X"
			pEnquireLast        = "­nÂÐ¬d½ã³æ¤§³Ìªñ¤@¦¸Ãº¶O¸Ô±¡"
			pCancel             = "­n¨ú®ø©Òµn°O¤§½ã³æ¸¹½X"
			pPayForm            = "­nÅã¥ÜÃº¶Oªí¡A½Ð¡u«ö¡v¨ä¤¤¤@­Ó½ã³æ¸¹½X"
			pPPSAccountNumber   = "Ãº¶OÆF¤á¤f¸¹½X( ¤K¦ì¼Æ¦r )"
			pMerchantCode       = "°Ó¤á½s¸¹"
			pBillNumber         = "½ã³æ¸¹½X"
			pMerchantName       = "½Ð¿ï¾Ü¤@­Ó°Ó¤á¦WºÙ"
			pPIN                = "½Ð¿é¤JÃº¶OÆFºô¤W±K½X"
	    } else {
	    	// Simplified Chinese
			mPrefix = "¸óÏÂÃ»ÓÐÔÚÕâ"
			mSuffix = "À¸ÌîÉÏËùÐë×ÊÁÏ£¬ÇëÖØÐÂÊäÈë¡£"
			mInteger  = "À¸±ØÐëÊÇÒ»¸öÕûÊý¡£ÇëÖØÐÂÊäÈë¡£"
			mAmount = "À¸±ØÐëÊÇÔª(Àý: 1234 ´ú±í $1,234.50)¡£ÇëÖØÐÂÊäÈë¡£"
			mAmount_cents = "À¸±ØÐëÊÇ½Ç(Àý: 50 ´ú±í $1,234.50)¡£ÇëÖØÐÂÊäÈë¡£"
			mLength1 = "À¸±ØÐëÊÇ"
			mLength2 = "Î»³¤¡£ÇëÖØÐÂÊäÈë¡£"
			
			sPPSAccountNumber   = "½É·ÑÁé»§¿ÚºÅÂë£Û°ËÎ»Êý×Ö )"
			sMerchantCode       = "ÉÌ»§±àºÅ"
			sBillNumber         = "ÕËµ¥ºÅÂë"
			sMerchantName       = "ÉÌ»§Ãû³Æ"
			sBillNo             = "ÕËµ¥ºÅÂë"
			sInitPIN            = "½É·ÑÁéÃÜÂë£ÛÎåÎ»Êý×Ö£Ý"
			sPIN                = "½É·ÑÁéÍøÉÏÃÜÂë"
			sPaymentAmount      = "½É¸¶½ð¶î"
			
			iPPSAccountNumber   = "´ËÀ¸±ØÐëÊÇÒ»¸öÓÐÐ§µÄ½É·ÑÁé»§¿ÚºÅÂë¡£ÇëÖØÐÂÊäÈë¡£"
			iInteger            = "´ËÀ¸±ØÐëÊÇÒ»¸öÕûÊý¡£ÇëÖØÐÂÊäÈë¡£"
			iInternetPassword   = "½É·ÑÁéÍøÉÏÃÜÂë±ØÐëÊÇ8-28Î»×ÖÄ¸»ò/¼°Êý×Ö£¬ÇëÖØÐÂÊäÈë¡£"		
			iChangeInitPassword = "¸óÏÂµÄ£µÎ»Êý×Ö½É·ÑÁéµç»°ÃÜÂë²¢²»¿ÉÔÚÕâÍøÕ¾½øÐÐ½»Ò×¡£Çë²Î¿¼ ' ÈçºÎÉè¶¨½É·ÑÁéÍøÉÏÃÜÂë ' ²éÑ¯ÏêÇé¡£"
			iChangePGPassword =   "¸óÏÂËùÊäÈëÖ®½É·ÑÁéÍøÉÏÃÜÂëÐèÒª°ËÖÁØ¥°Ë¸öÎ»µÄÓ¢ÎÄ×ÖÄ¸»ò/¼°Êý×ÖÖÐ¼ä²»ÄÜÓÐ¿ÕÎ»£¬ÌÈÈô¸óÏÂ²¢Î´¸ü¸Ä½É·ÑÁéÍøÉÏÐÂÃÜÂë£¬ÇëÏÈµ½Ö¸¶¨µÄ½É·ÑÁéÖÕ¶Ë»úÉè¶¨½É·ÑÁéÍøÉÏÃÜÂë²Å¿ÉÔÚÕâÍøÕ¾½øÐÐ½»Ò×¡£"
			
			pEntryPrompt        = "ÇëÊäÈë"
			pPaymentAmount      = "½É¸¶½ð¶î±ØÐëÊÇÔª(Àý: 1234 ´ú±í $1,234.50)"
			pPaymentAmount_cents= "½É¸¶½ð¶î±ØÐëÊÇ½Ç(Àý: 50 ´ú±í $1,234.50)"
			pRegister           = "ÒªµÇ¼ÇÒ»¸öÕËµ¥ºÅÂë"
			pPayment            = "Òª½É½»ÕËµ¥"
			pEnquire            = "ÒªÏÔÊ¾ËùµÇ¼ÇÖ®ÕËµ¥ºÅÂë"
			pEnquireLast        = "Òª¸²²éÕËµ¥Ö®×î½üÒ»´Î½É·ÑÏêÇé"
			pCancel             = "ÒªÈ¡ÏûËùµÇ¼ÇÖ®ÕËµ¥ºÅÂë"
			pPayForm            = "ÒªÏÔÊ¾½É·Ñ±í£¬Çë¡¸°´¡¹ÆäÖÐÒ»¸öÕËµ¥ºÅÂë"
			pPPSAccountNumber   = "½É·ÑÁé»§¿ÚºÅÂë( °ËÎ»Êý×Ö )"
			pMerchantCode       = "ÉÌ»§±àºÅ"
			pBillNumber         = "ÕËµ¥ºÅÂë"
			pMerchantName       = "ÇëÑ¡ÔñÒ»¸öÉÌ»§Ãû³Æ"
			pPIN                = "ÇëÊäÈë½É·ÑÁéÍøÉÏÃÜÂë"
	    }
	}
}

function errorMsg(obj,msg)
{
    alert(msg);
    if ( obj != null )
       obj.focus();
    return false;	
}	

function isSupportedChar(str)
{
    for (var i=0; i<str.length; i++) {
      temp = "" + str.substring(i, i + 1);
      if (charSet.indexOf(temp) == -1)
         return false
    }
    return true;
}

// check if the input is digit number
function isAllDigit(str) {
	charset = "0123456789";
	var result = true;
 
	for (var i=0;i<str.length;i++) {
		if (charset.indexOf(str.substr(i,1))<0) {
			result = false;
			break;
		}
	}
 	
 	return result;
}

function CheckValidSign(str)
{
	str = trim(str);
	 if ( str.length > 0 ) 
	{
		if (str.indexOf('{')>=0 ||
			str.indexOf('}')>=0 ||
			str.indexOf('[')>=0 ||
			str.indexOf(']')>=0 ||
			str.indexOf('<')>=0 ||
			str.indexOf('>')>=0 ||
			str.indexOf('|')>=0 ||
			str.indexOf(';')>=0 ||
			str.indexOf('&')>=0 ||
			str.indexOf('^')>=0 ||
			str.indexOf('\"')>=0 ||
			str.indexOf('\\')>=0 ||
			str.indexOf('=')>=0 ) 
		
		return false; 
	}
	return true;	
}