/***********************************
File:    sgForms.js
Author  : filippo pacini <pacini@sgconsulting.it>
License :
The contents of this file are subject to the Mozilla Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/MPL/

Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
the License for the specific language governing rights and
limitations under the License.
The Initial Developer of the Original Code is S.G. Consulting
srl. Portions created by S.G. Consulting s.r.l. are Copyright (C)
2006 S.G. Consulting srl. All Rights Reserved.

************************************/

// Trim method for strings: remove leading and triling spaces from a string
// create the prototype on the String object. So you can use it like aString.sgTrim()
String.prototype.sgTrim = function() {
    // skip leading and trailing whitespace
    // and return everything in between
    return this.replace(/^\s*(\b.*\b|)\s*$/, "$1");
}

// isEmpty method for strings. Check if a string is Empty or contains only spaces
// create the prototype on the String object. So you can use it like aString.sgIsEmpty()
String.prototype.sgIsEmpty = function() {
    if (this.length == 0 || this.sgTrim() == "")
        return true;
    else
        return false;
}

// get error messages
function _getErrMsg(baseMsg, frmElem) {
    if (frmElem.title)
        return baseMsg.replace('##name##', frmElem.title);
    else if (frmElem.name)
        return baseMsg.replace('##name##', frmElem.name);
    else  //should never get here
        return baseMsg;
}

// notEmpty Validator
function _notEmpty(field, fieldValue, lang) {
    if (lang == 'it')
        var errMsg = _getErrMsg("Inserire un valore nel campo ##name##", field);
    else //default english message
        var errMsg = _getErrMsg("Fill in form field ##name##", field);
    if (fieldValue.sgIsEmpty())
        return errMsg;
    return true;
}

// Email Validator
function _isEmail(field, fieldValue, lang) {
    var strMailFilter   = /^.+@.+\..{2,3}$/;
    var strIllegalChars = /[\(\)\<\>\,\;\:\\\/\*\-\+\=\"\[\]]/;
    var email = fieldValue;
    if (lang == 'it')
        var errMsg = _getErrMsg("##name## non valida", field);
    else //default english message
        var errMsg = _getErrMsg("Invalid ##name##", field);
    if (email && !email.match(strIllegalChars) && !(strMailFilter.test(email)))
        return errMsg;
    return true;
}

// Number Validator
function _isNumber(field, fieldValue, lang) {
    var valueConv = fieldValue.replace(',', '.');
    if (lang == 'it')
        var errMsg = _getErrMsg("Formato non valido per il campo ##name##", field);
    else //default english message
        var errMsg = _getErrMsg("Invalid format in field ##name##", field);
    if (isNaN(valueConv))
        return errMsg;
    return true;
}

// Float Validator
function _isFloat(field, fieldValue, lang) {
    var valueConv = fieldValue.replace(',', '.');
    if (lang == 'it')
        var errMsg = _getErrMsg("Formato non valido per il campo ##name##", field);
    else //default english message
        var errMsg = _getErrMsg("Invalid format in field ##name##", field);
    if (isNaN(parseFloat(valueConv)))
        return errMsg;
    return true;
}

// isChecked Validator: check if a checkbox is checked
function _isChecked(field, fieldValue, lang) {
    if (lang == 'it')
        var errMsg = _getErrMsg("Selezionare il campo ##name##", field);
    else //default english message
        var errMsg = _getErrMsg("Check the field ##name##", field);
    if (!field.checked)
        return errMsg;
    return true;
}


function _checkRule(field, fieldValue, lang) {
    inner = function(rule, idx) {
        // check rule
        if (rule == 'notEmpty') {
            return _notEmpty(field, fieldValue, lang);
        }
        if (rule == 'email') {
            return _isEmail(field, fieldValue, lang);
        }
        if (rule == 'number') {
            return _isNumber(field, fieldValue, lang);
        }
        if (rule == 'float') {
            return _isFloat(field, fieldValue, lang);
        }
        if (rule == 'isChecked') {
            return _isChecked(field, fieldValue, lang);
        }
        // try if rule is an executable and fallback to a catchall rule
        return Try.these(
            rule(field, fieldValue, lang),
            invalidRule(field, fieldValue, lang)
        );
    }
    return inner;
}

function _isValid(rules, lang) {
    inner = function(field, ruleIdx) {
        var fieldValue = $F(field);
        var rulesToCheck = rules[field];
        results = rulesToCheck.map(_checkRule($(field), fieldValue, lang));
        return results.findAll(function(val,idx) {return val!=true;});
    }
    return inner;
}
 
 
function sgFormValidate(rules, lang) {
    var rulesH = $H(rules);
    var keys = rulesH.keys();
    return keys.map(_isValid(rulesH, lang)).flatten();
}

function sgFormValidateAlert(rules) {
    var lang = 'en';
    if (arguments.length > 1)
        lang = arguments[1];
    result = sgFormValidate(rules, lang);
    if (result.length>0) {
        alert(result.join('\n'));
        return false;
    }
    return true;
}

function sgFormValidateBrString(rules) {
    var lang = 'en';
    if (arguments.length > 1)
        lang = arguments[1];
    result = sgFormValidate(rules, lang);
    if (result) {
        return result.join('<br>');
    }
    return "";
}

function sgFormValidateString(rules) {
    var lang = 'en';
    if (arguments.length > 1)
        lang = arguments[1];
    result = sgFormValidate(rules, lang);
    if (result) {
        return result.join('\n');
    }
    return "";
}
