/**
* pixelSEVENTY2 form validation script
* 
* Author: Chris Hembrow
*   Date: 2007-03-26
*
* The latest version of this script can always be found at http://www.pixelSEVENTY2.net/pixel/p72formChecker.page
*
*/

function p72formChecker( form ) {

    var valid = true;
    var msg = "";


    this.addIfField = function( fieldName, validationToRun) {
        if ( this._validFormFieldValue( form, fieldName ) ) {
            validationToRun();
        }
    };

    /**
    * I check that a field has been filled in or selected
    */
    this.addRequiredField = function( fieldName, displayName, message ) {

        if ( ! this._validFormFieldValue( form, fieldName ) ) {
            if ( message != null && message.length > 0 ) {
                this._addError( message );
            } else {
                this._addError( displayName + " is required" );
            }
        }
        
    };
    
    
    /**
    * I check that ALL or NONE of the fields have been filled in or selected. 
    * If they are ALL required, use addRequiredField for each field
    */
    this.addAllFields = function( fieldNames, displayNames, message ) {
        count = 0;

        for ( i=0; i<fieldNames.length; i++ ) {        
            if ( this._validFormFieldValue( form, fieldNames[i] ) ) {
                count++;
            }        
        }
        // some, but not all, are completed
        if ( count > 0 && count != fieldNames.length ) {
            if ( message != null && message.length > 0 ) {
                this._addError( message );
            } else {
                m1 = "";
                for ( i=0; i<displayNames.length; i++ ) {
                    if ( form.elements[fieldNames[i]] ) {
                        if ( i > 0 ) {
                            if ( i < ( fieldNames.length -    1 ) ) {
                                m1 += ", ";
                            } else {
                                m1 += " and ";
                            }
                        }
                        m1 += displayNames[i];
                    }
                }
                m1 += " must be completed";
                this._addError( m1 );
            }
        }
        
    }
    
    
    /**
    * I check that at least one of the fields has been filled in or selected
    */
    this.addEitherField = function( fieldNames, displayNames, message ) {
        ok = false;
        for ( i=0; i<fieldNames.length; i++ ) {        
            ok = this._validFormFieldValue( form, fieldNames[i] );            
            if ( ok ) {
                break;
            }        
        }
        if ( ! ok ) {
        
            if ( message != null && message.length > 0 ) {
                this._addError( message );
            } else {
                m1 = "Either ";
                for ( i=0; i<fieldNames.length; i++ ) {
                    if ( form.elements[fieldNames[i]] ) {
                        if ( i > 0 ) {
                            if ( i < ( fieldNames.length -1 ) ) {
                                m1 += ", ";
                            } else {
                                m1 += " or ";
                            }
                        }
                        m1 += displayNames[i];
                    }
                }
                this._addError( m1 + " are required" );
            }
        }
    };

    
    /**
    * I check that the field contains a valid email address - field can be empty
    */
    this.addEmailField = function( fieldName, displayName, message ) {
        with ( form.elements[fieldName] ) {
            if ( type == "text" ) {
                if ( value != null && value != "" ) {
                    if ( ! /^[\w\d-\.\+]+@([\w\d][\w\d-]*\.)+[a-z]{2,}$/i.test( value ) ) {
//                    if ( ! /^.+[^.]@[^.].*.[a-z]{2,}$/i.test( value ) ) {
                        if ( message != null && message.length > 0 ) {
                            this._addError( message );
                        } else {
                            this._addError( displayName.replace( "{0}", value ) + " is not a valid email address" );
                        }
                    }
                } else {
                    return;
                }
            }
        }
    }
    
    
    /**
    * I check that the field contains a numeric value - field can be empty
    */
    this.addNumberField = function( fieldName, displayName, message ) {
        with ( form.elements[fieldName] ) {
            if ( type == "text" || type == "password" ) {
                if ( value != null && value != "" ) {
                    if ( isNaN( value ) ) {
                        if ( message != null && message.length > 0 ) {
                            this._addError( message );
                        } else {
                            this._addError( displayName.replace( "{0}", value ) + " must be numeric" );
                        }
                    }
                } else {
                    return;
                }
            }
        }
    }
    
    
    /**
    * I validate the field value against a regular expression - field can be empty
    */
    this.addRegularExpressionField = function( fieldName, displayName, expression, message ) {
        with ( form.elements[fieldName] ) {
            if ( type == "text" || type == "password" || type == "textarea" || type == "file" ) {
                if ( value != null && value != "" ) {
                    re = new RegExp( expression );
                    if ( ! re.test( value ) ) {
                        if ( message != null && message.length > 0 ) {
                            this._addError( message );
                        } else {
                            this._addError( displayName.replace( "{0}", value ) + " does not match the required format" );
                        }
                    }
                } else {
                    return;
                }
            }
        }
    };
    
    
    /**
    * I check that all the fields contain the same value
    */
    this.addMatchingFields = function( fieldNames, displayNames, message ) {
        ok = true;
        
        last = null;
        for ( i=0; i<fieldNames.length; i++ ) {
            current = form.elements[ fieldNames[i] ].value;
            if ( i > 0 ) {
                if ( current == null ) {
                    if ( last != null ) {
                        ok = false;
                        break;
                    }
                } else if ( current != last ) {
                    ok = false;
                    break;
                }
            }
            last = current;
        }
        
        if ( ! ok ) {
            if ( message != null && message.length > 0 ) {
                this._addError( message );
            } else {            
                m1 = "";            
                for ( i=0; i<fieldNames.length; i++ ) {
                    if ( i > 0 ) {
                        if ( fieldNames.length > 2 && i != fieldNames.length - 1 ) {
                            m1 += ", ";
                        } else {
                            m1 += " and ";
                        }
                    }
                    m1 += displayNames[i].replace( "{0}", form.elements[ fieldNames[i] ].value );
                }
                m1 += " do not match";                
                this._addError( m1 );                            
            }
        }
    };
    
    
    /**
    * I check the length of a field - "max" is optional
    */
    this.addStringLengthField = function( fieldName, displayName, min, max, message ) {    
        ok = false;    
        with ( form.elements[fieldName] ) {
            if ( type == "text" || type == "password" || type == "textarea" ) {
                if ( value != null && value != "" ) {
                    if ( value.length >= min ) {
                        if ( max == null || max == -1 ) {
                            ok = true;
                        } else {
                            ok = ( str.length() <= max );
                        }
                    }
                } else {
                    return;
                }
            }
        }
        
        if ( ! ok ) {
            if ( message != null && message.length > 0 ) {
                this._addError( message );
            } else {
                m1 = displayName.replace( "{0}", form.elements[fieldName].value );
                m1 += " must be";
                if ( max == null || max == -1 ) {
                    m1 += " at least " + min;
                } else {
                    if ( min <= 1 ) {
                        m1 += " no more than " + max;
                    } else {
                        m1 += " between " + min + " and " + max;
                    }
                }
                m1 += " characters long";
                this._addError( m1 );
            }
        }        
    };
    

    /**
    * I perform the validation
    */
    this.validate = function() {
        if ( valid ) {
            return true;
        } else {
            alert( this.getMessage() );
            return false;
        }
    };
    

    /**
    * I return the error message
    */
    this.getMessage = function() {
        return msg;
    };
    
    
    // ######### SYSTEM METHODS #########
    this._addError = function( message ) {
        valid = false;
        msg += message + "\n";
    }
    
    
    this._validFormFieldValue = function( form, fieldName ) {
    
        f = form.elements[fieldName];
        fail = false;
        
        if ( f ) {
            if ( f.type.toLowerCase().indexOf("select") == -1 && f.length > 1 ) {
                for ( i=0; i<f.length; i++ ) {
                    fail = this._checkField(f[i]);
                    if ( ! fail ) {
                        break;
                    }
                }
            } else {
                fail = this._checkField (f);            
            }
        }
        return ! fail;
    };
    
    
    this._checkField = function( f ) {
        fail = false;
        if ( f.type == "checkbox" || f.type == "radio" ) {
            fail = ( ! f.checked );
        } else if ( f.type.toLowerCase().indexOf("select") != -1 ) {
            fail = ! ( f.selectedIndex > 0 );
        } else {
            fail = ( f.value == null || f.value == "" );
        }
        return fail;
    };

}
