var V_NOT_BLANK = 1;
var V_HTML_SAFE = 2;
var V_IS_DATE = 4;
var V_IS_NUMBER = 8;
var V_IS_EMAIL = 16;


function trim(s)
{
    if (typeof s != "string")
        return s;

    var i = 0;
    var c = s.charAt(i);

    while (c == ' ')
        c = s.charAt(++i);

    s = s.substr(i, s.length - i);
    c = s.charAt(s.length - 1);
    i = 1;

    while (c == ' ')
        c = s.charAt(s.length - ++i);

    s = s.substr(0, s.length - i + 1);

    return s;
}


function isBlank(s)
{
    if (typeof s != "string")
        return false;
    else
        return trim(s) == "";
}


/*
    Validates a credit card number using Luhn mod 10.  See the following
    URL for details about the algorithm.

    http://www.beachnet.com/~hstiles/cardtype.html
*/
function isCreditCard(s)
{
    var len = s.length;
    var i = 0;
    var sum = 0;
    var dig = 0;
    var mul = 1;

    if (len > 19)
        return false;

    for (i = 0; i < len; i++)
    {
        dig = parseInt(s.substr(len - i - 1, 1));
        dig *= mul;
        (mul == 1) ? mul = 2 : mul = 1;

        if (dig < 10)
            sum += dig;
        else
            sum += 1 + (dig % 10);
    }

    return (sum % 10) == 0;
}


function isCorrectCardType(ct, cn)
{
    if (ct == "Visa")
    {
        return (cn.substr(0, 1) == "4")
    }

    if (ct == "MasterCard")
    {
        check = cn.substr(0, 2);
        return ((check == "51") || (check == "52") || (check == "53") || (check == "54") || (check == "55"))
    }

    if (ct == "American Express")
    {
        check = cn.substr(0, 2);
        return ((check == "34") || (check == "37"))
    }

    if (ct == "Discover")
    {
        return (cn.substr(0, 4) == "6011")
    }

    return false;
}


function isHTMLSafe(s)
{
    return (s.search(/[<>\"]/g) == -1);
}


function isDate(s)
{
    var i = 0;
    var dateParts = s.split("/");

    if (dateParts.length != 3)
        return false;

    for (i = 0; i < 3; i++)
    {
        if (isNaN(dateParts[i]))
            return false;
    }

    if (dateParts[0] < 1 || dateParts[0] > 12)
        return false;

    if (dateParts[1] < 1 || dateParts[1] > 31)
        return false;

    if (dateParts[2] < 1)
        return false;

    return true;
}


function isEmail(s)
{
    var checkTLD=1;
    var knownDomsPat=/^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/;
    var emailPat=/^(.+)@(.+)$/;
    var specialChars="\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
    var validChars="\[^\\s" + specialChars + "\]";
    var quotedUser="(\"[^\"]*\")";
    var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
    var atom=validChars + '+';
    var word="(" + atom + "|" + quotedUser + ")";
    var userPat=new RegExp("^" + word + "(\\." + word + ")*$");
    var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");
    var matchArray=s.match(emailPat);

    if (matchArray==null) {
        return false;
    }

    var user=matchArray[1];
    var domain=matchArray[2];

    for (i=0; i<user.length; i++) {
        if (user.charCodeAt(i)>127) {
            return false;
       }
    }

    for (i=0; i<domain.length; i++) {
        if (domain.charCodeAt(i)>127) {
            return false;
       }
    }

    if (user.match(userPat)==null) {
        return false;
    }

    var IPArray=domain.match(ipDomainPat);
    if (IPArray!=null) {

        for (var i=1;i<=4;i++) {
            if (IPArray[i]>255) {
                return false;
           }
        }
        return true;
    }

    var atomPat=new RegExp("^" + atom + "$");
    var domArr=domain.split(".");
    var len=domArr.length;

    for (i=0;i<len;i++) {
        if (domArr[i].search(atomPat)==-1) {
            return false;
       }
    }

    if (checkTLD && domArr[domArr.length-1].length!=2 &&
            domArr[domArr.length-1].search(knownDomsPat)==-1) {
        return false;
    }

    if (len<2) {
        return false;
    }

    return true;
}


function checkField(field, fieldName, options)
{
    if (options & V_NOT_BLANK)
    {
        if (isBlank(field.value))
        {
            alert("The " + fieldName + " field may not be left blank.");
            field.focus();
            field.select();

            return false;
        }
    }

    if (options & V_HTML_SAFE)
    {
        if (!isHTMLSafe(field.value))
        {
            alert("The " + fieldName + " field contains illegal characters.\n\n" +
                "Illegal characters are:\n\n" +
                "Double quote: \"\nLess than sign: <\nGreater than sign: >");
            field.focus();
            field.select();

            return false;
        }
    }

    if (options & V_IS_DATE)
    {
        if (!isDate(field.value))
        {
            alert("The " + fieldName + " field must be in standard date format: mm/dd/yy.");
            field.focus();
            field.select();

            return false;
        }
    }

    if (options & V_IS_NUMBER)
    {
        n = field.value;

        if (n.charAt(0) == '$')
        {
            n = n.substr(1);
        }

        n = n.replace(/\,/g, "");

        if (isNaN(n))
        {
            alert("The " + fieldName + " field must be a number.");
            field.focus();
            field.select();

            return false;
        }
    }

    if (options & V_IS_EMAIL)
    {
        if (!isEmail(field.value))
        {
            alert("The " + fieldName + " field must contain a valid email address.\n\nExample: you@yourdomain.com");
            field.focus();
            field.select();

            return false;
        }
    }

    return true;
}


function countWords(s)
{
    s = s.replace(/[\f\n\r\t\v]/g, " ");
    s = s.replace(/ +/g, " ");
    s = trim(s);

    if (s.length > 0)
        return s.split(" ").length;
    else
        return 0;
}
