﻿function FormValidator(inForm, inSummary) {
    this.id = inForm;
    this.form = document.getElementById(inForm);
    this.form.FormValidator = this;

    if (document.getElementById(inSummary)) {
        this.summary = document.getElementById(inSummary);
    } else {
        if (this.form) {
            this.summary = document.createElement('p');
            errors.id = inSummary;
            errors.className = 'errors';
            this.form.insertBefore(errors);
        }
    }

    this.fields = new Array();
    this.messages = new Array();
    this.lengths = new Array();
    this.emailMessages = new Array();
    this.numFields = 0;
    this.numEmailFields = 0;
    this.errors = '';

    this.exempt = new Array();
    this.numExempt = 0;
}

FormValidator.prototype.RequiredField = function(inField, inMessage) {
    var me = this;

    this.fields[this.numFields] = inField;
    this.messages[this.numFields] = inMessage;
    this.numFields++;

    var objField = document.getElementById(inField);
    objField.FormValidator = me;
    //this.addEvent(objField, "blur", this.LabelError, false);
    if (objField) {
        this.addEvent(objField, "blur", this.LabelError, false);
    } else {
        debug('Check your required field declarations for errors: ' + inField);
    }
};

FormValidator.prototype.RequiredEmailField = function(inField, inMessage, inEmailMessage) {
    var me = this;

    this.fields[this.numFields] = inField;
    this.messages[this.numFields] = inMessage;
    this.emailMessages[this.numFields] = inEmailMessage;
    this.numFields++;

    var objField = document.getElementById(inField);
    objField.FormValidator = me;
    //this.addEvent(objField, "blur", this.LabelError, false);
    if (objField) {
        this.addEvent(objField, "blur", this.LabelError, false);
    } else {
        debug('Check your required field declarations for errors: ' + inField);
    }
};

FormValidator.prototype.LimitedField = function(inField, inMax, inMessage) {
    var me = this;

    this.fields[this.numFields] = inField;
    this.messages[this.numFields] = inMessage;
    this.lengths[this.numFields] = inMax;
    this.numFields++;

    var objField = document.getElementById(inField);
    objField.FormValidator = me;
    //this.addEvent(objField, "blur", this.LabelError, false);
};

FormValidator.prototype.RequiredPhoto = function(inField, inHidden, inMessage) {
    var me = this;

    /* hidden field isn't going to change so if it has a value, we don't set validation */
    var objHidden = document.getElementById(inHidden);
    if (objHidden.value == '') {
        this.fields[this.numFields] = inField;
        this.messages[this.numFields] = inMessage;
        this.numFields++;

        var objField = document.getElementById(inField);
        //this.addEvent(objField, "blur", this.LabelError, false);
        if (objField) {
            //this.addEvent(objField, "blur", this.LabelError, false);
            this.addEvent(objField, "change", this.LabelError, false);
        } else {
            debug('Check your required field declarations for errors: ' + inField);
        }
    }
};

//exempt code written specifically for adding attributes
//HERSHA specific: amentities, features, attractions
FormValidator.prototype.ExemptField = function(inField) {
    this.exempt[this.numExempt] = inField;
    this.numExempt++;
};

FormValidator.prototype.SetValidation = function() {
    var me = this;

    me.addEvent(me.form, "submit", me.ValidateForm, false);
};

FormValidator.prototype.ValidateForm = function(e) {
    var targ;
    if (!e) var e = window.event;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    if (targ.nodeType == 3) // defeat Safari bug
        targ = targ.parentNode;

    var me = targ.FormValidator;
    me.errors = '';

    for (var i = 0; i < me.fields.length; i++) {
        var isValid = true;
        var isValidEmail = true;
        if (!me.IsValid(i)) {
            isValid = false;
        } else if (me.emailMessages[i]) {
            //validate email
            var obj = document.getElementById(me.fields[i]);
            if (!me.IsValidEmail(obj.value)) {
                isValidEmail = false;
            }
        }

        if (isValid && isValidEmail) {
            label = me.GetLabel(me.fields[i]);
            if (label) {
                if (label.defaultClass) {
                    label.className = label.defaultClass;

                    var test = label.className;
                }
            }
        } else {
            if (!isValid) {
                me.errors += me.messages[i];
            } else if (!isValidEmail) {
                me.errors += me.emailMessages[i];
            }
            label = me.GetLabel(me.fields[i]);
            if (label) {
                if (!label.defaultClass) {
                    label.defaultClass = label.className;
                }
                label.className += ' errors';
            }
        }
    }

    if (me.errors) {
        me.summary.innerHTML = '<p>' + me.errors + '</p>';

        return false;
    } else {
        return true;
    }
};

FormValidator.prototype.GetLabel = function(id) {
    var labels = document.getElementsByTagName('label');

    for (var i = 0; i < labels.length; i++) {
        if (labels[i].htmlFor == id) {
            return labels[i];
        }
    }

    return null;
};

FormValidator.prototype.LabelError = function(e) {
    var targ;
    if (!e) var e = window.event;
    if (e.target) targ = e.target;
    else if (e.srcElement) targ = e.srcElement;
    if (targ.nodeType == 3) // defeat Safari bug
        targ = targ.parentNode;

    var me = targ.FormValidator;

    var fieldIndex;
    for (i = 0; i < me.fields.length; i++) {
        if (me.fields[i] == targ.id) {
            fieldIndex = i;
        }
    }

    var isValid = true;
    if (!me.IsValid(fieldIndex)) {
        isValid = false;
    } else if (me.emailMessages[fieldIndex]) {
        if (!me.IsValidEmail(targ.value)) {
            isValid = false;
        }
    }

    var label = me.GetLabel(targ.id);
    if (isValid) {
        if (label) {
            if (label.defaultClass) {
                label.className = label.defaultClass;

                var test = label.className;
            }
        }
    } else {
        if (label) {
            /* todo - class property of label error class */
            if (!label.defaultClass) {
                label.defaultClass = label.className;
            }
            label.className += ' errors';
        }
    }
};

FormValidator.prototype.IsValid = function(fieldIndex) {
    var me = this;

    var obj = document.getElementById(me.fields[fieldIndex]);

    /* TODO: use obj.type */
    if (obj.options) {
        //select
        if (obj.options[obj.selectedIndex].value == '') {
            return false;
        }
    } else if (obj.value == '') {
        if (me.lengths[fieldIndex]) {
            //empty therefore not too long
        } else {
            //input
            return false;
        }
    } else if (me.lengths[fieldIndex]) {
        //limited textarea
        if (obj.value.length > me.lengths[fieldIndex]) {
            return false;
        }
    }

    return true;
};

FormValidator.prototype.IsValidEmail = function(emailStr) {
    /* This pattern checks user@domain format, and is used to separate the username
    from the domain. */
    var emailPat = /^(.+)@(.+)$/
    /* We don't want to allow the following characters ( ) < > @ , ; : \ " . [ ] '   */
    var specialChars = "\\(\\)<>@,;:\\\\\\\"\\.\\[\\]"
    /* Range of characters allowed in a username or domainname.  It really states which chars aren't allowed. */
    var validChars = "\[^\\s" + specialChars + "\]"
    /* If the "user" is a quoted string, anything goes.*/
    var quotedUser = "(\"[^\"]*\")"
    /* If the domain is an IP addresses, rather than symbolic names.  
    E.g. joe@[123.124.233.4] is a legal email address. 
    NOTE: The square brackets are required. */
    var ipDomainPat = /^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
    /* An atom (basically a series of non-special characters.) */
    var atom = validChars + '+'
    /* One word in the typical username. E.g. john.doe@somewhere.com, john and doe are words.
    Basically, a word is either an atom or quoted string. */
    var word = "(" + atom + "|" + quotedUser + ")"
    // Structure of the user
    var userPat = new RegExp("^" + word + "(\\." + word + ")*$")
    /* Structure of a normal symbolic domain, as opposed to ipDomainPat, shown above. */
    var domainPat = new RegExp("^" + atom + "(\\." + atom + ")*$")

    /* Is supplied address is valid. */
    var matchArray = emailStr.match(emailPat)
    if (matchArray == null) {
        return false;
    }
    var user = matchArray[1]
    var domain = matchArray[2]

    // See if "user" is valid
    if (user.match(userPat) == null) {
        return false;
    }

    /* If an IP address, 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;
            }
        }
    }

    // Domain is symbolic name
    var domainArray = domain.match(domainPat)
    if (domainArray == null) {
        return false;
    }

    /* Check that the domain ends in a three-letter word (like com, edu, gov) 
    or a two-letter word, representing country (uk, nl), 
    and that there's a hostname preceding the domain or country. */

    /* Break up the domain to get a count of how many atoms it consists of. */
    var atomPat = new RegExp(atom, "g")
    var domArr = domain.match(atomPat)
    var len = domArr.length
    if (domArr[domArr.length - 1].length < 2 || domArr[domArr.length - 1].length > 3) {
            return false;
    }

    // Make sure there's a host name preceding the domain.
    if (len < 2) {
        return false;
    }

    return true;
};

FormValidator.prototype.addEvent = function(obj, evType, fn, useCapture) {
    if (obj.addEventListener) {
        obj.addEventListener(evType, fn, useCapture);
        return true;
    } else if (obj.attachEvent) {
        var r = obj.attachEvent("on" + evType, fn);
        return r;
    } else {
        debug("Handler could not be attached");
    }
};
