//
// Copyright (c) 2007 Men's Senior Baseball League - San Jose.  All rights reserved.
//
// Object: sjmsblUtil.
//
// Available functions
//
// sjmsblUtil.isEmpty
// sjmsblUtil.isFieldLengthValid
// sjmsblUtil.isInvalidASCIICharacters
// sjmsblUtil.isNotPositive
// sjmsblUtil.isUrlValid
// sjmsblUtil.isWhitespace
// sjmsblUtil.onEnter
// sjmsblUtil.trim
// sjmsblUtil.validateValue
// sjmsblUtil.warnOnCheckbox
// sjmsblUtil.warnOnDuplicate
// sjmsblUtil.warnOnEmpty
// sjmsblUtil.warnOnEmptyWithoutFocus
// sjmsblUtil.warnOnInvalidCharacter
// sjmsblUtil.warnOnInvalidCharacters2
// sjmsblUtil.warnOnInvalidCharactersQuotes
// sjmsblUtil.warnOnInvalidLength
// sjmsblUtil.warnOnInvalidName
// sjmsblUtil.warnOnInvalidPassword
// sjmsblUtil.warnOnLessThanOne
// sjmsblUtil.warnOnNonInt
// sjmsblUtil.warnOnNonFloat
// sjmsblUtil.warnOnNonNumeric
// sjmsblUtil.warnOnNumberNotInRange
// sjmsblUtil.warnOnSelectBox
// sjmsblUtil.warnOnDotInName
// sjmsblUtil.warnOnInvalidANSISQLDelimiterCharacter

var sjmsblUtil = new function() {
    this.className      = "sjmsblUtil";

    this.onEnter = function(field, evt, functionToCall) {
        var keyCode = evt.which ? evt.which : evt.keyCode;
        if (keyCode == 13) {
            if (functionToCall) {
                functionToCall();
            }
            return false;
        } else {
            return true;
        }
    }

    // Validates a standard name
    this.warnOnInvalidName = function(field, name, maxLgth) {
        var maxLength = 255;

        if ( name == null ) {
            name = sjmsblUtil.NAME;
        }

        if ( maxLgth != null ) {
            maxLength = maxLgth;
        }

        if (sjmsblUtil.warnOnEmpty(field, name)) {
            return true;
        }

        if (sjmsblUtil.warnOnInvalidCharacter(field)) {
            return true;
        }

        if (sjmsblUtil.warnOnInvalidLength( field, name, maxLength )) {
            return true;
        }

        return false;
    }

    this.validateValue = function(field, name, maxLgth, maxLength) {
        if ( maxLgth != null ) {
            maxLength = maxLgth;
        }

        if (sjmsblUtil.warnOnInvalidLength( field, name, maxLength )) {
            return true;
        }

        if (sjmsblUtil.warnOnInvalidCharacters2(field)) {
            return true;
        }
        return false;
    }

    //checks for valid length
    this.warnOnInvalidLength = function(field, name, maxLgth) {
        if (field.value.length > maxLgth ) {
            var msg = new String( sjmsblUtil.INVALID_LENGTH );
            msg = msg.replace( /\{0\}/, name );
            msg = msg.replace( /\{1\}/, maxLgth );
            alert( msg );
            field.focus();
            field.select();
            return true;
        }

        return false;
    }

    //These are the common JavaScript methods

    //checks whether the string is empty
    this.isEmpty = function(s) {
        return ((s == null) || (s.length == 0));
    }

    //checks for whitespaces
    this.isWhitespace = function(s) {
        var whitespace = new String(" \b\t\n\r");
        var isSpace = true;
        if (! sjmsblUtil.isEmpty(s)) {
            isSpace = false;
        }

        if (!isSpace) {
            // Search through string's characters one by one
            // until we find a non-whitespace character.
            for (var i = 0; i < s.length; i++) {
                var c = s.charAt(i);
                if (whitespace.indexOf(c) == -1) {
                    isSpace = false;
                    break;
                } else {
                    isSpace=true;
                }
            }
        }
        // All characters are whitespace.

        return isSpace;
    }

    //iterates through the characters one by one and checks for non-numeric digit.
    this.isNotPositive = function(field) {
        s = field.value;
        for (var i=0; i<s.length; i++) {
            var oneChar = s.charAt(i);
            if (oneChar < "0" || oneChar > "9") {
                return true;
            }
        }

        return false;
    }

    //Checks for non numeric field. The numeric value has to be greater than 0.
    this.warnOnLessThanOne = function(field, name) {
        var msg = new String( sjmsblUtil.PLEASE_ENTER_NUMERIC_VALUE );
        msg = msg.replace( /\{0\}/, name );
        var checkedValue = Number( field.value );

        if( isNaN( checkedValue ) ||  checkedValue < 1 ){
            field.focus();
            field.select();
            alert(msg);
            return true;
        } else {
            return false;
        }
    }

    //checks for the field to be empty
    this.warnOnEmpty = function(field, name) {
        var empty = sjmsblUtil.isWhitespace(field.value);
        var msg = new String( sjmsblUtil.PLEASE_ENTER );
        msg = msg.replace( /\{0\}/, name );

        if (empty) {
            field.focus();
            field.select();
            alert(msg);
        }

        return empty;
     }

     //checks for the field to be empty
     this.warnOnEmptyWithoutFocus = function(field, name) {
        var empty = sjmsblUtil.isWhitespace(field.value);
        var msg = new String( sjmsblUtil.PLEASE_ENTER );
        msg = msg.replace( /\{0\}/, name );

        if (empty) {
            alert(msg);
        }

        return empty;
     }

    //checks for the field to be empty
    this.warnOnSelectBox = function(field, name) {
        var msg = new String( sjmsblUtil.PLEASE_ENTER );
        msg = msg.replace( /\{0\}/, name );

        if(!field.options.length>0) {
                alert(msg);
                return true;
        } else {
            return false;
        }
      }

    this.warnOnNonInt = function(field, name) {
        var msg = new String( sjmsblUtil.PLEASE_ENTER_INTEGER_VALUE );
        msg = msg.replace( /\{0\}/, name );
        var notInt = false;
        var s = field.value;
        for( var i=0; i<s.length; i++ ) {
            var oneChar = s.charAt(i);
            if ( i == 0 && oneChar == "-" ) {
                continue;
            }

            if( oneChar == ","  ) {
                continue;
            }

            if( oneChar < "0" || oneChar > "9" ) {
                notInt = true;
            }
        }

        if( notInt ) {
            field.focus();
            field.select();
            alert(msg);
        }

        return notInt;
    }

    this.trim = function( value ) {
        if( value == null ) {
            return "";
        }

        var firstNonSpace = 0;
        var lastNonSpace = 0;
        for( var i=0; i<value.length; i++ ) {
            if( value.charAt(i) != " " ) {
                firstNonSpace = i;
                break;
            }
        }
        for( var i=(value.length-1); i>=0; i-- ) {
            if( value.charAt(i) != " " ) {
                lastNonSpace = i;
                break;
            }
        }

        var trimmedValue = "";
        if( lastNonSpace >= firstNonSpace ) {
            trimmedValue = value.substring( firstNonSpace, lastNonSpace+1 );
        }

        return trimmedValue;
    }

    this.warnOnNonFloat = function(field, name, restrictSplChars) {
        var msg = new String( sjmsblUtil.PLEASE_ENTER_DECIMAL_VALUE );
        msg = msg.replace( /\{0\}/, name );
        var notReal = false;
        var dotDone = false;
        var s = sjmsblUtil.trim( field.value );
        for( var i=0; i<s.length; i++ ) {
            var oneChar = s.charAt(i);
        if( oneChar == "-" ) {
                if ( i==0 )
                    continue;
        else {
            notReal = true;
            break;
        }
            }

        if( !restrictSplChars && (oneChar == "," || oneChar == "." || oneChar == " ") ) {
        continue;
            }
        else {
        if( oneChar == "." ) {
            if (!dotDone ) {
            dotDone = true;
            continue;
            }
            else {
            notReal = true;
            break;
            }
        }
        }
            if( oneChar < "0" || oneChar > "9" ) {
                notReal = true;
            }
        }
        if( notReal ) {
            field.focus();
            field.select();
            alert(msg);
        }

        return notReal;
    }

    //checks for non numeric fields
    this.warnOnNonNumeric = function(field, name) {
        var msg = new String( sjmsblUtil.PLEASE_ENTER_NUMERIC_VALUE );
        msg = msg.replace( /\{0\}/, name );
        var notPositive = sjmsblUtil.isNotPositive(field);

        if( notPositive ) {
            field.focus();
            field.select();
            alert(msg);
        }

        return notPositive;
    }

    this.warnOnNumberNotInRange = function(field, name, nMin, nMax) {
        if (sjmsblUtil.warnOnNonNumeric(field, name)) {
            return true;
        }

        var nValue = parseInt(field.value);

        if (nValue < nMin || nValue > nMax) {
            field.focus();
            field.select();

            var msg = new String( sjmsblUtil.VALUE_NOT_IN_RANGE );
            msg = msg.replace(/\{0\}/, nMin);
            msg = msg.replace(/\{1\}/, nMax);

            alert(msg);
            return true;
        }

        return false;
    }

    //checks for bad email
    this.warnOnBadEmail = function(field) {
        var regExEmail = /^.+\@.+\..+$/
        var emailBad = sjmsblUtil.warnOnEmpty(field, "e-mail address");
        if (!emailBad) {
            emailBad = (! regExEmail.test(field.value));
            if (emailBad) {
                field.focus();
                field.select();
                alert( sjmsblUtil.INVALID_EMAIL );
            }
        }
        return (emailBad);
    }


    //Validating the email address using RFC 822 specification (closely).
    //http://www.w3.org/Protocols/rfc822/#z66

    this.checkEmail = function(emailStr) {
    //  The following pattern is used to check if the entered e-mail address
    //  fits the user@domain format.  It also is used to separate the username
    //  from the domain.

        var emailPat=/^(.+)@(.+)$/;

    //  The following string represents the pattern for matching all special
    //  characters.  We don't want to allow special characters in the address.
    //  These characters include ( ) < > @ , ! ; : \ " . [ ]

        var specialChars="\\(\\)><@!,;:\\\\\\\"\\.\\[\\]";

    //  The following string represents the range of characters allowed in a
    //  username or domainname.  It really states which chars aren't allowed.

        var validChars="\[^\\s" + specialChars + "\]";

    //  The following pattern applies if the "user" is a quoted string (in
    //  which case, there are no rules about which characters are allowed
    //  and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com
    //  is a legal e-mail address.

        var quotedUser="(\"[^\"]*\")";

    //  The following pattern applies for domains that are IP addresses,
    //  rather than symbolic names.  E.g. joe@[123.124.233.4] is a legal
    //  e-mail address. NOTE: The square brackets are required.

        var ipDomainPat=/^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;

    //  The following string represents an atom (basically a series of non-special characters.)

        var atom=validChars + '+';

    //  The following string represents one word in the typical username.
    //  For example, in john.doe@somewhere.com, john and doe are words.
    //  Basically, a word is either an atom or quoted string.

        var word="(" + atom + "|" + quotedUser + ")";

        // The following pattern describes the structure of the user

        var userPat=new RegExp("^" + word + "(\\." + word + ")*$");

    //  The following pattern describes the structure of a normal symbolic
    //  domain, as opposed to ipDomainPat, shown above.

        var domainPat=new RegExp("^" + atom + "(\\." + atom +")*$");

    //  Finally, let's start trying to figure out if the supplied address is valid.

    //  Begin with the coarse pattern to simply break up user@domain into
    //  different pieces that are easy to analyze.

        var matchArray=emailStr.match(emailPat);

        if (matchArray==null) {

    //  Too many/few @'s or something; basically, this address doesn't
    //  even fit the general mould of a valid e-mail address.

            return false;
        }
        var user=matchArray[1];
        var domain=matchArray[2];

        // Start by checking that only ASCII characters are in the strings (0-255).

        for (i=0; i<user.length; i++) {
            if (user.charCodeAt(i)>255) {
                return false;
            }
        }
        for (i=0; i<domain.length; i++) {
            if (domain.charCodeAt(i)>255) {
                return false;
            }
        }

        // See if "user" is valid

        if (user.match(userPat)==null) {
            // user is not valid
            return false;
        }

    //  if the e-mail address is at an IP address (as opposed to a symbolic
    //  host name) make sure the IP address is valid.

        var IPArray=domain.match(ipDomainPat);
        if (IPArray!=null) {

            // this is an IP address

            for (var i=1;i<=4;i++) {
                if (IPArray[i]>255) {
                    return false;
                }
            }
            return true;
        }

        // Domain is symbolic name.  Check if it's valid.

        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;
            }
        }

        // Make sure there's a host name preceding the domain.

        if (len<2) {
            return false;
        }

        // If we've gotten this far, everything's valid!
        return true;
    }

    //check if a group of checboxes are not checked
    this.warnOnCheckbox = function(field, name) {
        var notchecked = true;
        var msg = new String( sjmsblUtil.PLEASE_SELECT );
        msg = msg.replace( /\{0\}/, name );

        if (field.length>0) {
            for (var i=0; i<field.length; i++) {
                if(field[i].checked == true) {
                    notchecked = false;
                    break;
                } else {
                    notchecked = true;
                }
            }
        } else {
            if(field.checked == true) {
                notchecked = false;
            } else {
                notchecked = true;
            }
        }
        if (notchecked) {
            alert(msg);
            return true;
        } else {
            return false;
        }
    }

     //checks for invalid characters
    this.warnOnInvalidCharacter = function(field) {
       var s = field.value;
       var invalidCharacters = new String("/\\:*?\"<>|[]");
       var isInvalid = false;

        // Search through string's characters one by one
        // until we find a non-whitespace character.
        for (var i = 0; i < s.length; i++) {
            var c = s.charAt(i);
            if (invalidCharacters.indexOf(c) == -1) {
                isInvalid = false;
            } else {
                isInvalid = true;
                field.focus();
                field.select();
                alert( sjmsblUtil.INVALID_CHARACTERS );
                break;
            }
        }
      if (!isInvalid) {
        isInvalid = sjmsblUtil.warnOnInvalidCharacters2(field);
      }
      return isInvalid;
    }

    this.warnOnInvalidANSISQLDelimiterCharacter = function(field) {
       var s = field.value;

       var invalidCharacters = new String(sjmsblUtil.ANSI_SQL_DELIMITER_CHARACTERS);//Total of 20 characters
       var isInvalid = false;

       //Search through string's characters one by one
       //until we find a non-whitespace character.
       for (var i = 0; i < s.length; i++) {
           var c = s.charAt(i);
           if (invalidCharacters.indexOf(c) == -1) {
               isInvalid = false;
           } else {
               isInvalid = true;
               field.focus();
               field.select();
               alert(sjmsblUtil.INVALID_ANSI_SQL_DELIMITER_CHARACTERS);
               break;
           }
       }
       return isInvalid;
    }

    this.warnOnDuplicate = function( field, current ) {
        var name = field[current].value;
        var msg = new String( sjmsblUtil.DUPLICATE_ERROR );

        for ( j = current + 1; j < field.length; j++ ) {
            if ( field[j].value == name ) {
                field[j].focus();
                field[j].select();
                alert( msg );
                return true;
            }
        }

        return false;
    }

    this.warnOnDotInName = function( field, msg ) {
        if( field != null ) {
        var value = field.value;
        for( var i=0; value != null && i < value.length; i++ )
            if( value.charAt(i) == ".")
            {
                field.focus();
                alert( msg );
                return true;
            }
        }
        return false;
    }

    //Test if the given URL string is valid.
    this.isUrlValid = function( urlString ) {
        if( urlString == '' ) {
            return false;
        }

        var whiteSpace = /(\s+)([\w.]+)/;
        //Trim the beginning white space from urlSting if there is any.
        if( urlString.match( whiteSpace ) != null ) {
             urlString = urlString.replace( whiteSpace, "$2" );
        }

        //A valid URL string has to start with http:// or https://

        if( ( ( urlString.indexOf( "http://" ) == 0 )&& urlString.length > 7 ) || ( urlString.indexOf( "https://" ) == 0 && urlString.length > 8 ) ) {
            return true;
        }

        if ((urlString.indexOf("file://") == 0 || urlString.indexOf("file:\\") == 0) && urlString.length > 7) {
            return true;
        }
        return false;
    }

    //Test if the given field is less than the given length.
    this.isFieldLengthValid = function( len, field )
    {
        if( sjmsblUtil.isEmpty ( field ) ) {
            return true;
        } else {
            return ( field.length <= len );
        }

    }

    //Method to check for invalid ascii codes for the given field
    this.warnOnInvalidCharacters2 = function(field) {
        var s = field.value;
        var isInvalid = false;

        // Search through string's characters one by one
        // until we find a invlid character.
        for (var i = 0; i < s.length; i++) {
            c = s.charCodeAt(i);
            if(!(c > 0 && c < 65535)) {
                    isInvalid = true;
                    field.focus();
                    field.select();
                    alert( sjmsblUtil.INVALID_CHARACTERS2 + ":" + s.charAt(i));
                    break;
            } else {
                // The 8000 and 9000 excluded range need to be revised
                // It excludes delta, pi, euro etc.  8364 is the code for euro
                if (c >= 8000 && c <= 9000 && c != 8364) {
                    isInvalid = true;
                    field.focus();
                    field.select();
                    alert( sjmsblUtil.INVALID_CHARACTERS2 + ":" + s.charAt(i));
                    break;
                } else {
                    isInvalid = false;
                }
            }
        }

      return isInvalid;
    }

    //Method to check for invalid ascii codes for the given field only used for global varaibles names
    //where we don't allow ' & " in the names
    this.warnOnInvalidCharactersQuotes = function(field) {
        var s = field.value;
        var isInvalid = false;
        // Search through string's characters one by one
        // until we find a invlid character.
        for (var i = 0; i < s.length; i++) {
            c = s.charCodeAt(i);
            if(!(c > 0 && c < 65535)) {
                isInvalid = true;
                field.focus();
                field.select();
                alert( sjmsblUtil.INVALID_CHARACTERS2 + ":" + s.charAt(i));
                break;
            } else {
                // The 8000 and 9000 excluded range need to be revised
                // It excludes delta, pi, euro etc.  8364 is the code for euro
                if ((c >= 8000 && c <= 9000 && c != 8364) || (c == 34 || c == 39 || c == 44)) {
                    isInvalid = true;
                    field.focus();
                    field.select();
                    alert( sjmsblUtil.INVALID_CHARACTERS2 + ":" + s.charAt(i));
                    break;

                } else {
                    isInvalid = false;
                }
            }
        }

      return isInvalid;
    }

    // The first 128 Unicode characters correspond to the ASCII characters
    // and have the same byte value. The Unicode characters U+0020 through
    // U+007E are equivalent to the ASCII characters 0x20 through 0x7E.
    // Returns true if non-ASCII character is found.
    this.isInvalidASCIICharacters = function(field) {
        var s = field.value;
        var isInvalid = false;

        // Search through string's characters one by one
        // until we find a invlid character.
        for (var i = 0; i < s.length; i++) {
            c = s.charCodeAt(i);
            if(!(c >= 0x20 && c <= 0x7E)) {
                isInvalid = true;
                break;
            }
        }

      return isInvalid;
    }

    // The this.checks for the equality of password and confirmPassword.
    // If the passwords match, it checks for non-ASCII char in the password.
    // confirmPassword may be null.
    this.warnOnInvalidPassword = function(password, confirmPassword) {
        if ( sjmsblUtil.isInvalidASCIICharacters(password) ) {
            alert( sjmsblUtil.NON_ASCII_PASSWORD );
            password.select();
            password.focus();
            return true;
        }

        if ( confirmPassword != null) {
            if ( password.value != confirmPassword.value ) {
                alert( sjmsblUtil.PASSWORD_CONFIRM_FAILED );
                password.focus();
                return true;
            }
        }

        return false;
    }
};

sjmsblUtil.PLEASE_ENTER             = "Please enter '{0}'.";
sjmsblUtil.PLEASE_ENTER_FIRST_NAME  = "Please enter your first name.";
sjmsblUtil.PLEASE_ENTER_LAST_NAME   = "Please enter your last name.";
sjmsblUtil.PLEASE_ENTER_EMAIL       = "Please enter your email address.";

// Score Card Error Messages

sjmsblUtil.PLEASE_ENTER_GAME_DATE   = "Please enter a game date.";
sjmsblUtil.PLEASE_CHOOSE_GM1_FIELD  = "Please choose a field for game 1.";


