
if (typeof(WV) == 'undefined') WV = {};

WV.Form = function () {
};

WV.Form.prototype = {
    init : function ( translation) {
        this.elements = new Array();
        this.translation = translation;
        // Translate the success string:
        if (this.translation[this.success_msg] != undefined) {
            this.success_msg = this.translation[this.success_msg];
        }        
        return this;
    },
    addTarget : function(target) {
        this.target = target;
    },
    addBrand : function(brand) {
        this.brand = brand;
    },
    process : function (validation_type) {
        if ( validation_type == 'inline') {
          // Show error messages on the HTML page:
          if (!this.validateInline()) return false;
        } else {
          // Else use alert():
          if (!this.validate()) return false;
        }

        if (this.pre_fxn() === false) return false;
        if (window.console && window.console.log) {
            console.log('firing ' + this.event_id);
            console.log(this.getFormData());
        }
        $(document).trigger(this.event_id, [{ 'event_name' : this.eventName,
                                              'data' : this.getFormData()}]);
        this.post_fxn();
    },
    getFormData : function () {
        var formDataObj = new Object();

        // XXX MRS fix formDataObj.instance_id = instance_id;
        for (var i = 0; i < this.elements.length; i++) {
            var id   = this.elements[i].id;
            var name = $("#"+id).attr("name");
            if (this.elements[i].type == 'checkbox') {
                formDataObj[name] = $("#"+id).is(':checked');
            } else {
                formDataObj[name] = $("#"+id).val();
            }
        }
        formDataObj['target'] = this.target;
        if (! formDataObj['brand']) formDataObj['brand'] = this.brand;
        return formDataObj;
    },
    validate : function () {
        form_elements = this.elements;
        v = new WV.FormValidation(this.translation);
        for (var i = 0; i < form_elements.length; i++) {
            e = form_elements[i];
            v.registerElement(e.id, e.display, e.type, e.min_length, e.max_length);
        }
        if (v.validate()) {
            return true;
        } else {
            var message = '';
            var errors = v.getErrors();
            for (var i=0; i < errors.length; i++) {
                message = message + errors[i] + "\n";
            }
            alert(message);
            v.clearErrors();
            return false;
        }
    },
    validateInline : function () {
        form_elements = this.elements;
        v = new WV.FormValidation(this.translation);
        for (var i = 0; i < form_elements.length; i++) {
            e = form_elements[i];
            v.registerElement(e.id, e.display, e.type, e.min_length, e.max_length);
        }
        if (v.validateInline()) {
            return true;
        } else {
            // Clear form elements first:
            for (var i = 0; i < form_elements.length; i++) {
                e = form_elements[i];
                var obj = $("#" + e.id);
                var objError = $("#" + e.id + "_error");

                obj.removeClass("form_error_field");
                objError.hide();
            }
            // Set the errors:
            var errorsInline = v.getErrorsInline();
            for (var i in errorsInline) {
              var obj = $("#" + i);
              obj.addClass("form_error_field");

              // jQuery's "objError.length > 0" is the way to check if an element exists.
              // But that returns also zero for empty elements, so, let's use getElementById() here.
              if (!document.getElementById(i + "_error")) {
                // If the error container doesn't exists, create it.
                obj.after('<div id="' + i + '_error" class="form_error"></div>');
              }

              var objError = $("#" + i + "_error");
              objError.text(errorsInline[i]);
              objError.show();
            }
            v.clearErrorsInline();
            return false;
        }
    },
    addElement : function (name, id, type, required, min_length, max_length) {
        this.elements.push(new WV.FormElement(name, id, type, required, min_length, max_length));
    },
    pre_fxn : function () {
        $(this.form_id).hide();
        $(this.loading_id).show();
        return true;
    },
    post_fxn : function () {
        alert('MNE');
    },
    error_fxn : function () {
        alert('An error occured while processing your request. Please try again in a moment.');
        $(this.loading_id).hide();
        $(this.form_id).show();
    }
};

WV.Form.SMS = function () {
    this.form_id     = '#sms_layer_inline';
    this.loading_id  = '#sms_loading';
    this.eventName   = 'SmsConnection';
    this.success_msg = 'thanks_sub';
    this.event_id    = '#sms_submit_event';
};

WV.Form.SMS.prototype = new WV.Form();
WV.Form.SMS.prototype.post_fxn = function (data) {
    // XXX translate and note the lack of tracking error handling
    $('#sms_form_response').show().html(this.success_msg);
    $('#sms_loading').hide();
    $('#sms_form').hide();
    $('#sms_layer_inline').show();
};
WV.Form.SMS.prototype.getFormData = function() {
    var data = WV.Form.prototype.getFormData.call(this);
    var phone = data.sms_sender_phone_area
        + data.sms_sender_phone_prefix
        + data.sms_sender_phone_suffix;

    return { 'name' : data.sms_sender_name,
             'phone' : phone,
             'brand' : data.sms_brand,
             'target' : data.target,
             'message' : data.sms_sender_message };
};


WV.Form.Email = function () {
    this.form_id     = '#email_layer_inline';
    this.loading_id  = '#email_loading';
    this.eventName   = 'EmailForm';
    this.success_msg = 'thanks_sent';
    this.event_id    = '#email_submit_event';
};

WV.Form.Email.prototype = new WV.Form();
WV.Form.Email.prototype.post_fxn = function (data) {
    $('#email_form_response').show().html(this.success_msg);
    $('#email_loading').hide();
    $('#email_form').hide();
    $('#email_layer_inline').show();
};

WV.Form.Custom = function () {
    this.form_id     = '#cform';
    this.loading_id  = '#cform_loading';
    this.eventName   = 'FormSubmit';
    this.success_msg = 'thanks_sub';
    this.event_id    = '#form_submit_event';
};

WV.Form.Custom.prototype = new WV.Form();
WV.Form.Custom.prototype.post_fxn = function (data) {
    $('#cform_loading').hide();
    $('#cform_response').html(this.success_msg);
    $('#cform_response').show();
    return true;
};

WV.FormField = function () {
};

WV.FormField.Text = function (props) {
    this.required = props.required;
    this.label    = props.label;
    this.id       = props.id;
    this.name     = props.name;
    this.value    = props.value;
};

WV.FormField.Text.prototype = new WV.FormField();
WV.FormField.Text.prototype.renderToString = function () {
    var html = '<li><label for="' + this.id + '">';
    if (this.required) html += '<em>*</em>';
    html += this.label
         +'</label>'
         + '<input type="text" id="' + this.id + '" name="' + this.name + '" value="' + this.value + '"/>'
         + '</li>';
    return html;
};

WV.FormElement = function (name, id, type, required, min_length, max_length) {
    this.display    = name;
    this.id         = id;
    this.type       = type;
    this.required   = required;
    this.min_length = min_length;
    this.max_length = max_length;
};

WV.FormValidation = function (translation) {
    //Members
    this.data_is_valid      = true;
    this.dataElements       = [];
    this.elementCounter     = 0;
    this.errors             = [];
    this.errorsInline       = new Array();

    this.translation        = translation;

    //Methods
    this.registerElement    = objRegister;
    this.unRegisterElement  = objUnregister;
    this.validate           = objValidate;
    this.validateInline     = objValidateInline;
    this.clearErrors        = objClearErrors;
    this.clearErrorsInline  = objClearErrorsInline;
    this.getErrors          = objGetErrors;
    this.getErrorsInline    = objGetErrorsInline;

    this.getTypeMessaging   = objGetTypeMessaging;

    this._                  = objTranslate;
};

//Validation.registerElement
function objRegister(id, field_name, data_type, min_length, max_length) {
    var element         = new dataElement();
    element.id          = id;
    element.field_name  = field_name;
    element.data_type   = data_type;
    element.max_length  = max_length;
    element.min_length  = min_length;

    this.dataElements.push(element);
    this.elementCounter++;
}

//Validation.unRegisterElement
function objUnregister(id) {

}

//Validation.validate()
function objValidate() {
    this.data_is_valid = true;
    for (var i=0; i<this.dataElements.length; i++) {
        var element = this.dataElements[i];
        if (element.data_type == 'dropdown') {
            if ((document.getElementById(element.id).value == "") && (element.min_length > 0)) {
                this.errors.push(element.field_name + ' ' + this._('required'));
                this.data_is_valid = false;
            }
        } else if (element.data_type == 'listbox') {
            total_selected = document.getElementById(element.id).options.length;
            if (total_selected < element.min_length) {
                this.errors.push("You must select at least "+element.min_length+" "+element.field_name);
                this.data_is_valid = false;
            } else if (total_selected > element.max_length && element.max_length != 0) {
                this.errors.push("You can select a maximum of "+element.max_length+" "+element.field_name);
                this.data_is_valid = false;
            }
        } else if (element.data_type == 'checkbox') {

        } else {
            var value = idValue(element.id);
            if (isEmpty(value) && element.min_length > 0) {
                this.errors.push(element.field_name + ' ' + this._('required'));
                this.data_is_valid = false;
            }
            if (!isEmpty(value)) {
                if (!validateByDataType(value, element.data_type)) {
                    this.errors.push(element.field_name + ' ' + this.getTypeMessaging(element.data_type));
                    this.data_is_valid = false;
                }
                if (value.length < element.min_length) {
                    this.errors.push(element.field_name +' '+ this._('min') +' '+ element.min_length +' '+ this._('characters'));
                    this.data_is_valid = false;
                }
                if (value.length > element.max_length) {
                    this.errors.push(element.field_name +' '+ this._('max') +' '+ element.max_length +' '+ this._('characters'));
                    this.data_is_valid = false;
                }
            }
        }


    }

    if (!this.data_is_valid) {
        var error_string = "";
        for (var i=0; i<this.errors.length; i++) {
            error_string += "- "+this.errors[i]+"\n";
        }
        //alert(error_string);
        //this.errors = [];
        return false;
    } else {
        return true;
    }

}

//Validation.validateInline()
function objValidateInline() {
    this.data_is_valid = true;
    for (var i=0; i<this.dataElements.length; i++) {
        var element = this.dataElements[i];
        if (element.data_type == 'dropdown') {
            if ((document.getElementById(element.id).value == "") && (element.min_length > 0)) {
                this.errorsInline[element.id] = element.field_name + ' ' + this._('required');
                this.data_is_valid = false;
            }
        } else if (element.data_type == 'listbox') {
            total_selected = document.getElementById(element.id).options.length;
            if (total_selected < element.min_length) {
                this.errorsInline[element.id] = "You must select at least "+element.min_length+" "+element.field_name;
                this.data_is_valid = false;
            } else if (total_selected > element.max_length && element.max_length != 0) {
                this.errorsInline[element.id] = "You can select a maximum of "+element.max_length+" "+element.field_name;
                this.data_is_valid = false;
            }
        } else if (element.data_type == 'checkbox') {

        } else {
            var value = idValue(element.id);
            if (isEmpty(value) && element.min_length > 0) {
                this.errorsInline[element.id] = element.field_name + ' ' + this._('required');
                this.data_is_valid = false;
            }
            if (!isEmpty(value)) {
                if (!validateByDataType(value, element.data_type)) {
                    this.errorsInline[element.id] = element.field_name + ' ' + this.getTypeMessaging(element.data_type);
                    this.data_is_valid = false;
                }
                if (value.length < element.min_length) {
                    this.errorsInline[element.id] = element.field_name +' '+ this._('min') +' '+ element.min_length +' '+ this._('characters');
                    this.data_is_valid = false;
                }
                if (value.length > element.max_length) {
                    this.errorsInline[element.id] = element.field_name +' '+ this._('max') +' '+ element.max_length +' '+ this._('characters');
                    this.data_is_valid = false;
                }
            }
        }
    }

    return this.data_is_valid;
}

function objClearErrors() {
    this.errors = [];
}

function objClearErrorsInline() {
    this.errorsInline = new Array();
}

function objGetErrors() {
    return this.errors;
}

function objGetErrorsInline() {
    return this.errorsInline;
}

function objGetTypeMessaging(type) {
    if (type == "alpha") {
        return this._('alpha');
    } else if (type == "num") {
        return this._('numeric');
    }else if (type == "alpha-num") {
        return this._('alpha_numeric');
    } else if (type == "alpha-num-symbol") {
        return this._('alpha_numeric_symbol');
    } else if (type == "email") {
        return this._('valid_email');
    } else if (type == "url") {
        return this._('valid_url');
    } else if (type == "zip-us") {
        return this._('valid_zip');
    } else if (type == "zip-ca") {
        return "must be a valid Canadian Postal Code";
    }
}

function objTranslate(phrase) {
    if (this.translation[phrase] != undefined) {
        return this.translation[phrase];
    } else {
        return phrase;
    }
}

function formatErrors(errors) {
    var error_string = "";
    for (var i=0; i<errors.length; i++) {
        error_string += "- "+errors[i]+" \n";
    }
    return error_string;
}

// Data Element Object ======================
function dataElement() {
    this.id             = "";
    this.field_name     = "";
    this.data_type      = "";
    this.min_length     = "";
    this.max_length     = "";
}


//Function Reference ==================================
function validateByDataType (value, data_type) {
    if (data_type == 'alpha') {
        return isAlpha(value);
    } else if (data_type == 'alpha-num') {
        return isAlphaNumeric(value);
    } else if (data_type == 'num') {
        return isNumeric(value);
    } else if (data_type == 'alpha-num-symbol') {
        return true;
    } else if (data_type == 'url') {
        return isValidUrl(value);
    } else if (data_type == 'email') {
        return isValidEmail(value);
    } else if (data_type == 'zip-us') {
        return isValidPostalCode(value, 'us');
    } else if (data_type == 'zip-ca') {
        return isValidPostalCode(value, 'ca');
    }
}
function isNotEmpty(value) {
    if (value.length > 0) {
        return true;
    } else {
        return false;
    }
}

function isEmpty(value) {
    return !isNotEmpty(value);
}

//Standard Data Types ==================================
function isNumeric(value) {
    var pattern = /^[0-9]+$/;
    return testPattern(value, pattern);
}
function isNumericSpace(value) {
    var pattern = /^[0-9\s]+$/;
    return testPattern(value, pattern);
}
function isAlpha(value) {
    var pattern = /^[a-zA-Z\s]+$/;
    return testPattern(value, pattern);
}
function isAlphaNumeric(value) {
    var pattern = /^[a-zA-Z0-9\s]+$/;
    return testPattern(value, pattern);
}
function isValid(value, pattern) {
    return testPattern(value, pattern);
}
//=======================================================

//Additional Data Types =================================
function isValidEmail(address) {
    var email_filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
    if (email_filter.test(address)) {
        return true;
    } else {
        return false;
    }
}

function isValidUrl(value) {
    var pattern = /^((http|https):\/\/)?([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?$/;
    return testPattern(value, pattern);
}

function isValidPostalCode(value, country_code) {
    if (country_code == 'us') {
        var pattern = /^[0-9]+$/;
    } else if (country_code == 'ca') {
        var pattern = /^[0-9]+$/;
    } else {
        var pattern = "";
    }
    return testPattern(value, pattern);
}

//=======================================================

//Special Functions =================================
/**
    Checks an array of field ID's to see if data has been entered

    @param array fields An array of field ID's to check
    @return true if all fields contain data, false if 1 or more are empty
*/
function fieldsCompleted(fields) {
    var fields_complete = true;

    for (var i=0; i < fields.length; i++) {
        if (isEmpty(document.getElementById(fields[i]).value)) {
            fields_complete = false;
        }
    }
    return fields_complete;
}

//Private =================================
function testPattern(value, pattern) {
    if (pattern.test(value)) {
        return true;
    } else {
        return false;
    }
}


// Other ==================================
function idValue(id) {
    return document.getElementById(id).value;
}


