// VARIABLE DECLARATIONS

var digits = "0123456789";
var lowercaseLetters = "abcdefghijklmnopqrstuvwxyz"
var uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"

var ALPHA_NUMERIC_CHARACTERS = digits + lowercaseLetters + uppercaseLetters;

// whitespace characters
var whitespace = " \t\n\r";

// decimal point character differs by language and culture
var decimalPointDelimiter = "."



// Check whether string s is empty.

function isEmpty(s)
	{
	return ((s == null) || (s.length == 0));
	}

function stripWhitespace(s)
	{
	return stripCharsInBag(s, whitespace)
	}

// Returns true if string s is empty or
// whitespace characters only.
function isWhitespace(s)
	{
	var i;

    if (isEmpty(s)) 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;
	}


function hasSpace(str)
	{
	var startLength = str.length;
	var endLength = stripCharsInBag(str, whitespace)
	endLength = endLength.length;

	if (startLength != endLength)
		{
		return true;
		}
	else
		{
		return false;
		}
	}

function charInString(c, s)
	{
	for (i = 0; i < s.length; i++)
    	{
		if (s.charAt(i) == c) return true;
    	}
    return false
	}




// 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);
	}

function stripFollowingWhitespace(s)
	{
	var i = s.length;

	while ((i > 0) && charInString(s.charAt(i-1), whitespace))
		{
		i = i - 1;
    	}
	return s.substring (0, i);
	}

// not named simply trim() to avoid any potential collisions later on as js evolves
function trimString(s)
	{
	var tempS = stripInitialWhitespace(s)
	return stripFollowingWhitespace(tempS);
	}


// Removes all characters which appear in string bag from string s
// f('hello', 'eo') returns 'hll'
function stripCharsInBag(s, bag)
	{
    var returnString = "";

    // Search through string's characters one by one.
    // If character is not in bag, append to returnString.

    for (var 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
// f('hello', 'eo') returns 'eo'
function stripCharsNotInBag(s, bag)
	{
    var returnString = "";

    // Search through string's characters one by one.
    // If character is in bag, append to returnString.

    for (var 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;
	}






// 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))
	}



function isInteger(s)
	{
	var i;

    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 isSignedInteger(s)
	{
	var startPos = 0;
	// skip leading + or -
	if ( (s.charAt(0) == "-") || (s.charAt(0) == "+") )
	startPos = 1;
	return (isInteger(s.substring(startPos, s.length)))
    }

function isPositiveInteger(s)
	{
    return (isSignedInteger(s) && ( isEmpty(s) || (parseInt (s) > 0) ) );
	}

function isNonnegativeInteger(s)
	{
    return (isSignedInteger(s) && ( isEmpty(s) || (parseInt (s) >= 0) ) );
	}

function isNegativeInteger(s)
	{
    return (isSignedInteger(s) && ( isEmpty(s) || (parseInt (s) < 0) ) );
	}

function isNonpositiveInteger(s)
	{
    return (isSignedInteger(s) && ( isEmpty(s) || (parseInt (s) <= 0) ) );
	}


function isFloat(s)
	{
	var i;
    var seenDecimalPoint = false;

    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;
}


function isSignedFloat(s)
	{
	var startPos = 0;

	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)))
    }

function isAlphabetic(s)
	{
	var i;
    // 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;
}



function isAlphanumeric(s)
	{
	var i;

    // 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;
}






// 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;
}




// isIntegerInRange returns true if string s is an integer
// within the range of integer arguments a and b, inclusive.

function isIntegerInRange (s, a, b)
	{
    // 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;

	// if we're this far, it's safe to run an eval against this string- it contins only 0-9
	// but a leading zero will cause problems... we could walk through and strip leading, or
	// just try to eval it..
	s = eval(s);

    // 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).
    var num = parseInt (s);
    return ((num >= a) && (num <= b));
	}


function replaceReturnWithBr(str)
{
	return str.replace(/(\r\n|[\r\n])/g, "<br />");
}

function hasNumber(str)
{
	var regex = /\d/g;
	return regex.test(str);
}

function hasAlpha(str)
{
	var regex = /[A-z]/g;
	return regex.test(str);
}

