// Default behavior is controlled by global variable defaultEmptyOK.
var defaultEmptyOK = false;

// 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.
// isFloat (s [,eok])                  True if string s is an unsigned floating point (real) number. (Integers also OK.)
// isSignedFloat (s [,eok])            True if string s is a floating point number; leading + or - allowed. (Integers also OK.)
// isIntegerInRange (s, a, b [,eok])   True if string s is an integer between a and b, inclusive.

// 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.
// isAlphabetic (s [,eok])             True if string s is English letters 
// isAlphanumeric (s [,eok])           True if string s is English letters and numbers only.
// isDate(d,eok)                       True if valid date
// isTime(t)						   True if valid time
// isWhitespace (s)                    Check whether string s is empty or whitespace.
// isEmail(e,eok)					   This will validate an email, if eok is true a blank email will return ok.

// paddInt(s,n)                        This will left padd a string containing an integer(s) with zeros and return a string with the length of (n)
// lpad(s,n[,x])                       Left Padd a value
// rpad(s,n[,x])                       Right Padd a value


// parseInteger is a  Bug Fix for parseInt which can not handle 08 & 09...
// this function will strip off the leading zeros before parsing
function parseInteger(s) {
   while (s.charAt(0) == '0')
      s = s.substring(1, s.length);

	if (s.length==0)
		return parseInt('0');
	else
		return parseInt(s);
}

// VARIABLE DECLARATIONS

var digits = "0123456789";
var lowercaseLetters = "abcdefghijklmnopqrstuvwxyz";
var uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var whitespace = " \t\n\r";
var decimalPointDelimiter = ".";


// 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 characters which appear in string bag from string s.

function stripCharsInBag (s, bag)

{   var i;
    var returnString = "";

    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }

    return returnString;
}



// Removes all characters which do NOT appear in string bag 
// from string s.

function stripCharsNotInBag (s, bag)

{   var i;
    var returnString = "";

    // Search through string's characters one by one.
    // If character is in bag, append to returnString.

    for (i = 0; i < s.length; i++)
    {   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);
        if (bag.indexOf(c) != -1) returnString += c;
    }

    return returnString;
}



// 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 character c is an English letter 
// (A .. Z, a..z).
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));
}



// isInteger (STRING s [, BOOLEAN defaultEmptyOK])
// 
// Returns true if all characters in string s are numbers.
//
// Accepts non-signed integers only. Does not accept floating 
// point, exponential notation, etc.
//
//
// By default, returns defaultEmptyOK if s is empty.
// There is an optional second argument called defaultEmptyOK.
// defaultEmptyOK is used to override for a single function call
//      the default behavior which is specified globally by
//      defaultEmptyOK.
// If defaultEmptyOK is false (or any value other than true), 
//      the function will return false if s is empty.
// If defaultEmptyOK 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;
}

function isEmail(emailaddress)
{
    if (isEmpty(emailaddress)) 
       if (isEmail.arguments.length == 1) return defaultEmptyOK;
       else return (isEmail.arguments[1] == true);

	var Temp     = emailaddress;
	var AtSym    = Temp.indexOf('@');
	var junk    = Temp.indexOf(',') + Temp.indexOf('!') + Temp.indexOf('#') + Temp.indexOf(';') + Temp.indexOf(':');
	var Period   = Temp.lastIndexOf('.');
	var Space    = Temp.indexOf(' ');
	var Length   = Temp.length - 1;   // Array is from 0 to length-1

	if ((AtSym < 1) || junk > 0 ||         // '@' cannot be in first position
    	(Period <= AtSym+1) ||             // Must be atleast one valid char btwn '@' and '.'
	    (Period == Length ) ||             // Must be atleast one valid char after '.'
    	(Space  != -1))                    // No empty spaces permitted
		return false;
	else
		return true;
}


// isSignedInteger (STRING s [, BOOLEAN defaultEmptyOK])
// 
// 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 parseInteger because that would accept a string
// with trailing non-numeric characters.
//
// For explanation of optional argument defaultEmptyOK,
// 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));
    }
}


// isPositiveInteger (STRING s [, BOOLEAN defaultEmptyOK])
// 
// Returns true if string s is an integer > 0.
//
// For explanation of optional argument defaultEmptyOK,
// 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)  || (parseInteger (s) > 0) ) );
}

// isNonnegativeInteger (STRING s [, BOOLEAN defaultEmptyOK])
// 
// Returns true if string s is an integer >= 0.
//
// For explanation of optional argument defaultEmptyOK,
// see comments of function isInteger.

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)  || (parseInteger (s) >= 0) ) );
}



// isNegativeInteger (STRING s [, BOOLEAN defaultEmptyOK])
// 
// Returns true if string s is an integer < 0.
//
// For explanation of optional argument defaultEmptyOK,
// see comments of function isInteger.

function isNegativeInteger (s)
{   var secondArg = defaultEmptyOK;

    if (isNegativeInteger.arguments.length > 1)
        secondArg = isNegativeInteger.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 negative, not positive, number

    return (isSignedInteger(s, secondArg)
         && ( (isEmpty(s) && secondArg)  || (parseInteger (s) < 0) ) );
}


// isNonpositiveInteger (STRING s [, BOOLEAN defaultEmptyOK])
// 
// Returns true if string s is an integer <= 0.
//
// For explanation of optional argument defaultEmptyOK,
// see comments of function isInteger.

function isNonpositiveInteger (s)
{   var secondArg = defaultEmptyOK;

    if (isNonpositiveInteger.arguments.length > 1)
        secondArg = isNonpositiveInteger.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)  || (parseInteger (s) <= 0) ) );
}





// isFloat (STRING s [, BOOLEAN defaultEmptyOK])
// 
// True if string s is an unsigned floating point (real) number. 
//
// Also returns true for unsigned integers. If you wish
// to distinguish between integers and floating point numbers,
// first call isInteger, then call isFloat.
//
// Does not accept exponential notation.
//
// For explanation of optional argument defaultEmptyOK,
// see comments of function isInteger.

function isFloat (s)

{   var i;
    var seenDecimalPoint = false;

    if (isEmpty(s)) 
       if (isFloat.arguments.length == 1) return defaultEmptyOK;
       else return (isFloat.arguments[1] == true);

    if (s == decimalPointDelimiter) return false;

    // 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 ((c == decimalPointDelimiter) && !seenDecimalPoint) seenDecimalPoint = true;
        else if (!isDigit(c)) return false;
    }

    // All characters are numbers.
    return true;
}


// isSignedFloat (STRING s [, BOOLEAN defaultEmptyOK])
// 
// True if string s is a signed or unsigned floating point 
// (real) number. First character is allowed to be + or -.
//
// Also returns true for unsigned integers. If you wish
// to distinguish between integers and floating point numbers,
// first call isSignedInteger, then call isSignedFloat.
//
// Does not accept exponential notation.
//
// For explanation of optional argument defaultEmptyOK,
// see comments of function isInteger.

function isSignedFloat (s)

{   if (isEmpty(s)) 
       if (isSignedFloat.arguments.length == 1) return defaultEmptyOK;
       else return (isSignedFloat.arguments[1] == true);

    else {
        var startPos = 0;
        var secondArg = defaultEmptyOK;

        if (isSignedFloat.arguments.length > 1)
            secondArg = isSignedFloat.arguments[1];

        // skip leading + or -
        if ( (s.charAt(0) == "-") || (s.charAt(0) == "+") )
           startPos = 1;    
		   
        return (isFloat(s.substring(startPos, s.length), secondArg));
    }
}

// isAlphabetic (STRING s [, BOOLEAN defaultEmptyOK])
// 
// Returns true if string s is English letters 
// (A .. Z, a..z) only.
//
// For explanation of optional argument defaultEmptyOK,
// 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 defaultEmptyOK])
// 
// Returns true if string s is English letters 
// (A .. Z, a..z) and numbers only.
//
// For explanation of optional argument defaultEmptyOK,
// 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;
}

// isIntegerInRange (STRING s, INTEGER a, INTEGER b [, BOOLEAN defaultEmptyOK])
// 
// isIntegerInRange returns true if string s is an integer 
// within the range of integer arguments a and b, inclusive.
// 
// For explanation of optional argument defaultEmptyOK,
// see comments of function isInteger.

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 parseInteger
    // 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).
    var num = parseInteger (s);
    return ((num >= a) && (num <= b));
}

//d is a string containing a date value...
function isDate (d) {
    //Returns true if value is a date format or is NULL
    //otherwise returns false	
	
	if (isEmpty(d)) 
       if (isDate.arguments.length == 1) return defaultEmptyOK;
       else return (isDate.arguments[1] == true);

    //Returns true if value is a date in the mm/dd/yyyy format
	isplit = d.indexOf('/');

	if (isplit == -1 || isplit == d.length)
		return false;

    sMonth = d.substring(0, isplit);
	isplit = d.indexOf('/', isplit + 1);

	if (isplit == -1 || (isplit + 1 ) == d.length)
		return false;

    sDay = d.substring((sMonth.length + 1), isplit);

	sYear = d.substring(isplit + 1);

	if (!isInteger(sMonth,false)) //check month
		return false;
	else
	if (!isIntegerInRange(sMonth, 1, 12)) //check month
		return false;
	else
	if (!isInteger(sYear,false)) //check year
		return false;
	else
	if (!isIntegerInRange(sYear, 1900, 9999)) //check year
		return false;
	else
	if (!isInteger(sDay,false)) //check day
		return false;
	else {
	maxDay = 31;

	if (sMonth == 4 || sMonth == 6 || sMonth == 9 || sMonth == 11)
		maxDay = 30;
	else
	if (sMonth == 2)
	{
		if (sYear % 4 > 0)
			maxDay =28;
		else
			if (sYear % 100 == 0 && sYear % 400 > 0)
				maxDay = 28;
			else
				maxDay = 29;
	}
	
	if (!isIntegerInRange(sDay, 1, maxDay)) // check day
		return false;
	else
		return true;
    }
}

//t is a string containing a time value...
function isTime (t) {
    //Returns true if value is a time format or is NULL
    //otherwise returns false	
	
	if (isEmpty(t))  //check for blank time
		return defaultEmptyOK;

	if ((t.length == 1 || t.length == 2) && isInteger(t)) //check for the case where they just have the hours
		return true;
		
    //Returns true if value is a time in the hh:mm format
	isplit = t.indexOf(':');

	if (isplit == -1 || isplit == t.length)
		return false;

    sHour = t.substring(0, isplit);
	if (sHour.length > 2)
		return false;
    sMinute = t.substring((sHour.length + 1), (t.length - (isplit - 1)));
	if (sMinute.length > 2)
		return false;
	
	if (!isInteger(sHour,false)) //check hours
		return false;
	else
	if (!isIntegerInRange(sHour, 1, 12)) //check hour
		return false;
	else
	if (!isInteger(sMinute,false)) //check minutes
		return false;
	else
	if (!isIntegerInRange(sMinute, 0, 59)) //check minutes
		return false;
	else
		return true;
}


// Convert a Date (MM/DD/YYYY) to YYYYDDMM

function date2Number(d) {
	if (!isDate(d)) return null;
	
	isplit = d.indexOf('/');


    sMonth = d.substring(0, isplit);
	isplit = d.indexOf('/', isplit + 1);


    sDay = d.substring((sMonth.length + 1), isplit);
	sYear = d.substring(isplit + 1);

	// Handle 2 digit Years...will work with dates up to 2029
	if (sYear.length==2)
		if (parsInt(sYear) < 30)
			sYear='19'+sYear;
		else
			sYear='20'+sYear;
	
	sDay = paddInt(sDay,2);
	sMonth = paddInt(sMonth,2);
	
	return parseInt(sYear + sMonth + sDay);
}

// Compares 2 Dates and Returns a value based on comparison
// These Dates must be validated first!
// -1:	d1 < d2
// 0:	d1 = d2
// 1:	d1 > d2

function compareDates(d1,d2) {
//Parse Date 1
	isplit = d1.indexOf('/');


    sMonth1 = d1.substring(0, isplit);
	isplit = d1.indexOf('/', isplit + 1);


    sDay1 = d1.substring((sMonth1.length + 1), isplit);
	sYear1 = d1.substring(isplit + 1);
//Parse Date 2
	isplit = d2.indexOf('/');


    sMonth2 = d2.substring(0, isplit);
	isplit = d2.indexOf('/', isplit + 1);


    sDay2 = d2.substring((sMonth2.length + 1), isplit);
	sYear2 = d2.substring(isplit + 1);
	
	sDay1 = paddInt(sDay1,2);
	sDay2 = paddInt(sDay2,2);
	sMonth1 = paddInt(sMonth1,2);
	sMonth2 = paddInt(sMonth2,2);
	
	sDate1 = parseInt(sYear1 + sMonth1 + sDay1);
	sDate2 = parseInt(sYear2 + sMonth2 + sDay2);

	
	if (sDate1 == sDate2) return 0;
	if (sDate1 > sDate2) return 1;
	if (sDate1 < sDate2) return -1;
}

// Left Padd an integer with Zeros, if the string is longer than n, s will be returned
function paddInt(s,n) {
	if (s.length < n) {
		while (s.length < n) { 
			s = '0' + s;
		}
	}

	return s;
}

// Right Padd a value (default will be with '0' if no thirdd paramter is provided
// Usage rpad(str,n [,c])
// Returns a stringof <n> length made up of <str> right padded with '0'
// Example: rpad('123',10)     == '1230000000';
// Example: rpad('123',10,'x') == '123xxxxxxx';
function rPadd() {
	s=arguments[0];
	n=arguments[1];
	if(arguments.length > 2)
		p=arguments[2];
	else
		p='0';

	if (s.length < n) {
		while (s.length < n) { 
			s = s + p;
		}
	}
	return s;
}

//Left Padd a Value 
// Usage lpad(str,n [,c])
// Returns a stringof <n> length made up of <str> left padded with '0'
// Example: lpad('123',10)     == '0000000123';
// Example: lpad('123',10,'x') == 'xxxxxxx123';
function lPadd() {
	s=arguments[0];
	n=arguments[1];
	if(arguments.length > 2)
		p=arguments[2];
	else
		p='0';

	if (s.length < n) {
		while (s.length < n) { 
			s = p + s;
		}
	}
	return s;
}

// Select the 'val' in a select box ('sel')
function selectOption(sel,val) {
	for (var i=0;i < sel.options.length; i++) {
		if (sel.options[i].value == val) {
			sel.options[i].selected=true;
			break;
		}
	}
}

// Select the radio Button with value==value
function selectRadio(rb,value) {
	for (i=0;i < rb.length; i++) {
		if (rb[i].value == value) {
			rb[i].checked=true;
			break;
		}
	}
}

