/*******************************************************************************
 *
 * File       : verify_form.js
 * Author     : Duco Dokter
 * Created    : Sun Jan 27 14:07:01 2002
 * CVS Version: $Id: verify_form.js,v 1.3 2002/10/09 20:30:03 dokter Exp $
 * Copyright  : Wyldebeast & Wunderliebe
 * License    : GPL
 * Contact us : dokter@wyldebeast-wunderliebe.com
 *
 * This is a generic form verification library. The function verify
 * does the main loop over the elements of the form specified as it's
 * argument, performs the checks specified and returns true or false,
 * depending on whether the form is filled in properly or not.
 *
 * Please check our website for examples and documentation:
 * http://www.wyldebeast-wunderliebe.com/projects/verify_form/verify_form.html
 *
 * LICENSE INFO:
 * -----------------------------------------------------------------------------
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version. This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details. You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 ******************************************************************************/


/* Global variables holding the error message and header.
 */
var errorMsg;
var errorHeader = "";


/* Language to use. Default is English
 */
var language  = "fr";

var cssURL    = "";
var errWindow = null;


var dict = new Array();

var err_bgColor = "#cc3333";
var ok_bgColor = "#ffffff";


dict["fr"] = new Array(5);

dict["fr"]["header"]   = "Ce formuliare n'as pas été envoyé à cause des erreures suivantes.";
dict["fr"]["required"] = " est requis(e) ";
dict["fr"]["requires"] = " requis(e) ";
dict["fr"]["nomatch"]  = " n'est pas un(e) ";
dict["fr"]["close"]    = "Fermer";
dict["fr"]["integer"]    = "nombre entier";
dict["fr"]["email"]    = "courriel";
dict["fr"]["float"]    = "nombre flottant";
dict["fr"]["date"]    = "date";


function _val_my_trim(string)
{
    return string.replace(/(^\s*)|(\s*$)/g,'');
}


/**
 * Verify the complete form for all values.
 * Synopsis: verify(form)
 */
function verify(tform) {

    errorMsg = "";

    var formOK   = true;



    var _err_bgColor = tform.getAttribute("errbgcolor");
    var _ok_bgColor = tform.getAttribute("okbgcolor");
    if (_err_bgColor != null) {
        err_bgColor = _err_bgColor;
    }
    if (_ok_bgColor != null) {
        ok_bgColor = _ok_bgColor;
    }



    for (var i= 0; i < tform.length; i++) {
	var elt = tform.elements[i];
	verifyField(elt) || (formOK = false);
    }

    if (! formOK) {
	alert(errorMsg);
    }
    return formOK;
}


/**
 * Verification dispatcher
 */
function verifyField(elt) {

    /* Now do some element specific thingies
     */
    switch(elt.type) {
    case "text":
	return verifyText(elt);
    case "password":
	return verifyText(elt);
    case "hidden":
	return verifyText(elt);
    case "textarea":
	return verifyText(elt);
    case "radio":
	return  verifyRadio(elt);
    case "checkbox":
	return  verifyCheckbox(elt);
    case "select-one":
	return verifySelect(elt);
    case "select-multiple":
	return verifySelect(elt);
    default:

	return true;
    }
}


/**
 * Verification of a select element. The element is ok-ed when the
 * value of the option is not empty.
 */
function verifySelect(elt) {
    var label    = elt.getAttribute("label");
    var required = elt.getAttribute("required");
    var ok = true;

    var f_err_bgColor = err_bgColor;
    var f_ok_bgColor = ok_bgColor;
    if (elt.getAttribute("errbgcolor") != null) {
        f_err_bgColor = elt.getAttribute("errbgcolor");
    }
    if (elt.getAttribute("okbgcolor") != null) {
        f_ok_bgColor = elt.getAttribute("okbgcolor");
    }


    if (required != null && isEmpty(elt.value)) {
	errorMsg += label + dict[language]["required"] + "\n";
	ok = false;
    }
    if (!ok) {
        elt.style.backgroundColor = f_err_bgColor;
        elt.onfocus = function() { this.style.backgroundColor = f_ok_bgColor; };
    } else {
        elt.style.backgroundColor = f_ok_bgColor;
    }

    return ok;
}


/**
 * Dispatch to verifyRadio.
 */
function verifyCheckbox(elt) {
    return verifyRadio(elt);
}


/**
 * Verification of a radio checks for dependent field, and checks those accordingly.
 */
function verifyRadio(elt) {

    var ok = true;

    //var requires = elt.getAttribute("requires");
    var label    = elt.getAttribute("label");
    var check    = elt.getAttribute("check");
    var required = elt.getAttribute("required");

    if (elt.checked && check != null) {

	var err = eval(check + "()");

	if (err != 0) {
	    errorMsg += label + ": " + err + "\n";
	    ok = false;
	}
    }

    // Now check if the radio group itself is required
    if (required != null) {

	var noneOK = true;

	for (var i= 0; i < elt.form.elements[elt.name].length; i++) {
	    if (elt.form.elements[elt.name][i].checked) {
		noneOK = false;
		break;
	    }
	}

	if (noneOK) {
	    errorMsg += label + dict[language]["required"] + "\n";
	}

	ok = ! noneOK;
    }
    return ok;
}


/**
 * Verify a text field. The field is OK if one of the following conditions is true:
 * 1. it's not required and empty;
 * 2. it's not empty and doesn't have a mask specified;
 * 3. it's not empty and satisfies it's specified mask.
 */
function verifyText(elt) {

    var ok = true;

    var f_err_bgColor = err_bgColor;
    var f_ok_bgColor = ok_bgColor;
    if (elt.getAttribute("errbgcolor") != null) {
        f_err_bgColor = elt.getAttribute("errbgcolor");
    }
    if (elt.getAttribute("okbgcolor") != null) {
        f_ok_bgColor = elt.getAttribute("okbgcolor");
    }

    var label    = elt.getAttribute("label");
    var mask     = elt.getAttribute("mask");
    var required = elt.getAttribute("required");
    var validate = elt.getAttribute("validate");

    var minlength = elt.getAttribute("minlength");


    if (! isEmpty(elt.value) && mask != null && ! verifyMask(elt.value, mask)) {
	ok = false;
	errorMsg += label + " : " + elt.value + dict[language]["nomatch"] + dict[language][mask] + "\n";
    }
    elt.value = _val_my_trim(elt.value);
    if (! isEmpty(elt.value) && minlength != null) {
        if (parseInt(minlength) > elt.value.length) {
            ok = false;
	    errorMsg += label + " doit être au minimum de " + minlength + " caractères\n";
        } // if
    } // if


    if (required != null && isEmpty(elt.value)) {
	ok = false;
	errorMsg += label + dict[language]["required"] + "\n";
    }
    if (!ok) {
        elt.style.backgroundColor = f_err_bgColor;
        elt.onfocus = function() { this.style.backgroundColor = f_ok_bgColor; };
    } else {
        elt.style.backgroundColor = f_ok_bgColor;
    }

    return ok;
}


/**
 * The text element may have a mask specified. This should take the form of a
 * regular expression. If the element doesn't match the mask, false is returned.
 */
function verifyMask(value, mask) {
    switch (mask) {
    case "integer":
        exp = new RegExp(/^[0-9]*$/);
        break;
    case "float":
        exp = new RegExp(/^[0-9]*$|^[0-9]*\.[0-9]*$/);
        break;
    case "date":
        exp = new RegExp(/^\d{4}-\d{1,2}-\d{1,2}$/);
        break;
    case "email":
        return my_validate_emailCheck(value);
        break;
    }
    return exp.test(value);
}


/**
 * Determine whether a value is empty. This is true when all characters in the
 * value are one of "\n, \t, ' '".
 */
function isEmpty(value) {

    for (var i= 0; i < value.length; i++) {
	var c = value.charAt(i);

	if ((c != ' ') && (c != '\n') && (c != '\t')) return false;
    }

    return true;
}


function requiresHandler(e) {

    var form;

    if (e.target != null) {
	form = e.target.form;
    }
    else {
	form = e.srcElement.form;
    }


    /* Find all fields that require other fields
     */
    for (var i= 0; i < form.length; i++) {

	var elt = form.elements[i];
	var requires          = elt.getAttribute("requires");
	var requiresHandler   = elt.getAttribute("requireshandler");
	var unrequiresHandler = elt.getAttribute("unrequireshandler");

	if (elt.checked && requires != null) {

	    if (requiresHandler != null) {
		eval(requiresHandler);;
	    }
	}
	else if (requires != null) {

	    if (unrequiresHandler != null) {
		eval(unrequiresHandler);;
	    }
	}
    }

    e.cancelBubble= true;
}




/*******************************************************************************
 *
 * BEGIN User functions to customize behaviour.
 *
 ******************************************************************************/


/**
 * Create an event listener for the form, that listens to changes, and applies the
 * required class to new required fields.
 */
function setRequiresHandler(form) {

    for (var i = 0; i < form.length; i++) {
	form.elements[i].onclick = requiresHandler;
    }
}


/**
 * Set you own error header
 */
function setErrorHeader(header) {
    errorHeader = header;
}


/**
 * Set the stylesheet to use for the error window.
 */
function setStylesheet(url) {
    cssURL = url;
}


/**
 * Set the language to use
 */
function setLanguage(lang) {

    if (dict[lang] != null) {
	language = lang;
    }
}



function my_validate_emailCheck(str)
{
    var at="@"
    var dot="."
    var lat=str.indexOf(at)
    var lstr=str.length
    var ldot=str.indexOf(dot)
    if (str.indexOf(at)==-1){
        return false
    }

    if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr){
        return false
    }

    if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr){
        return false
    }

    if (str.indexOf(at,(lat+1))!=-1){
        return false
    }

    if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot){
        return false
    }

    if (str.indexOf(dot,(lat+2))==-1){
        return false
    }

    if (str.indexOf(" ")!=-1){
        return false
    }

    return true
}
