/***********************************
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;
}

var sgForms = {
    // get error messages
    _getErrMsg: function(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
    _notEmpty: function(field, fieldValue, lang) {
	if (lang == 'it')
            var errMsg = sgForms._getErrMsg("Inserire un valore nel campo ##name##", field);
	else //default english message
            var errMsg = sgForms._getErrMsg("Fill in form field ##name##", field);
	if (fieldValue.sgIsEmpty())
            return errMsg;
	return true;
    },

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

    // Phone Validator
    _isPhone: function(field, fieldValue, lang) {
	var phoneNumber = fieldValue.replace(/[\ \(\)\<\>\,\;\:\\\/\*\-\+\=\"\[\]]/g, '');
	if (lang == 'it')
            var errMsg = sgForms._getErrMsg("##name## non valida", field);
	else //default english message
            var errMsg = sgForms._getErrMsg("Invalid ##name##", field);
	if (phoneNumber && isNaN(phoneNumber))
            return errMsg;
	return true;
    },

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

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

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

    _checkRule: function(field, fieldValue, lang) {
	inner = function(rule) {
            // check rule
            if (rule == 'notEmpty') {
		return sgForms._notEmpty(field, fieldValue, lang);
            }
            if (rule == 'email') {
		return sgForms._isEmail(field, fieldValue, lang);
            }
            if (rule == 'number') {
		return sgForms._isNumber(field, fieldValue, lang);
            }
            if (rule == 'float') {
		return sgForms._isFloat(field, fieldValue, lang);
            }
            if (rule == 'isChecked') {
		return sgForms._isChecked(field, fieldValue, lang);
            }
            if (rule == 'phone') {
		return sgForms._isPhone(field, fieldValue, lang);
            }
            // try if rule is an executable and fallback to a catchall rule
	    try {
		return rule(field, fieldValue, lang);
	    } catch (e) {
		return e;
	    }
	}
	return inner;
    },

    _isValid: function(rules, lang) {
	inner = function(field, acc) {
	    var fieldRef = document.getElementById(field);
            var rulesToCheck = rules[field];
            results = sgFun.map(sgForms._checkRule(fieldRef, fieldRef.value, lang), rulesToCheck);
            return acc.concat(sgFun.filter(function(val) {return val!=true;}, results));
	}
	return inner;
    },
 
 
    validate: function(rules, lang) {
	var keys = new Array();
	for (var field in rules) {
	    keys[keys.length] = field;
	}
	return sgFun.foldl(sgForms._isValid(rules, lang), keys, new Array());
    },

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

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

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