/*
Copyright (c) 2007, Parosweb O.E. All rights reserved.
version: 2007-06-10
*/

////////////////////////////////////////////////////////////////////////////////
// Shortcuts ///////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
function prepend( element, addElement ) {
    var father = element.parentNode;
    father.insertBefore( addElement, element );
}
function append( element, addElement ) {
    var father = element.parentNode;
    father.insertBefore( addElement, element.nextSibling );
}
var $D = YAHOO.util.Dom;
var $E = YAHOO.util.Event;
var $ = $D.get;
var $v = void(0);

////////////////////////////////////////////////////////////////////////////////
// Form Object /////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
function PWForm( sIdForm ) {
    this.sIdForm = sIdForm ? sIdForm : null;
    this.sClassErr = 'err';
    this.sErrHeader = 'Please enter/select values for the following fields:';
    this.sErrSelect = 'Please select a valid "%FIELDNAME%"';
    this.sErrEnter = 'Please enter a valid "%FIELDNAME%"';
    this.bYUIErr = true;
    this.sYUIErrButton = 'OK';
    this.sYUIErrHeader = null;
		this.bYUISuc = true;
    this.sYUISucButton = 'OK';
    this.sYUISucHeader = 'Success';
		this.bSuccess = false;
		this.sSuccess = '<ul><li>Your message has been sent successfully.</li></ul><br /><br />';
    this.CFG = new Object();
}
// init ////////////////////////////////////////////////////////////////////////
PWForm.prototype.init = function() {
    var o = this;
		if ( o.bSuccess ) {
			o.showSuccessdialog();
			o.bSuccess = false;
		}
    o.sError = '';
    o.getForm();
    // avoid name="submit" pitfall
    if ( o.oForm.submit=='[object HTMLInputElement]' ) {
        alert('ERROR: a form element has its attribute name set to "submit"'); return;
    }
    // prepare o.sErrHeader
    if (o.bYUIErr) { o.sErrHeader = '<p>'+o.sErrHeader+'</'+'p><ul>';  }
    else { o.sErrHeader += '\n\n'; }
    // handle submit
    o.fSubmitHandler = function(e) {
        $E.preventDefault(e);
        if( o.validate() ) { o.oForm.submit(); }
    };
    $E.on( o.sIdForm, 'submit', o.fSubmitHandler, o, true )
};
// validate ////////////////////////////////////////////////////////////////////
PWForm.prototype.validate = function() {
    var o = this;
    o.sError = '';
    var oError = null;
    // init fields
    o.getFields();
    // validate
    for ( var i=0; i<o.aFields.length; ++i ) {
        var f = o.aFields[i];
        if ( !f.isValid( o.aFields ) ) {
            // catch first error
            if ( !oError ) {
                oError = f;
                o.sError = o.sErrHeader;
            }
            o.handleError ( f );
            // set error class
            f.setErrorClass( o.sClassErr, true );
        } else {
            // nullify cError
            f.cError = null;
            // remove error class
            f.setErrorClass( o.sClassErr, false );
        }
    };
    if ( oError ) {
        o.showErrordialog();
        // focus on first error
        oError.element.focus();
        return false;
    } else {
        // submit form
        return true;
    }
};
// getfields ///////////////////////////////////////////////////////////////////
PWForm.prototype.getFields = function() {
    var o = this;
    o.aFields = new Array();
    for ( var i=0; i < o.oForm.length; ++i ) {
        var el = o.oForm.elements[i];
        if ( el.type ) {
            var ix = o.getIndex( o.aFields, el );
            if ( ix==-1 ) {
                o.aFields[o.aFields.length] = new PWField( el, o );
            } else {
                o.aFields[ ix ].mergeField(el);
            }
        }
    }
};
// getindex ////////////////////////////////////////////////////////////////////
PWForm.prototype.getIndex = function( a, el ) {
    if ( el.name ) {
        var eN = el.name.toLowerCase();
        for ( var i=0; i < a.length; ++i ) {
       	    if ( a[i].element.name && a[i].element.name.toLowerCase()==eN ) {  return i; }
        }
    }
    return -1;
};
// getform /////////////////////////////////////////////////////////////////////
PWForm.prototype.getForm = function() {
    var o = this;
    // no id given
    if ( !o.sIdForm ) { o.oForm = $(document.forms[0]);
        // no id present
        if ( !o.oForm.id ) { o.sIdForm = $D.generateId( o.oForm ); }
        // id present
        else { o.sIdForm = o.oForm.id; }
    }
    // id given
    else { o.oForm = $( o.sIdForm ); }
};
// handleerror /////////////////////////////////////////////////////////////////
PWForm.prototype.handleError = function( f ) {
    var o = this;
    var e = f.element;
    var fErr = ( (f.realname)? f.realname : ( (e.id) ? e.id : e.name ) );
    // handle sError
    if ( o.bYUIErr ) { o.sError += '<li>' + fErr + '</'+'li>'; }
    else { o.sError += '- ' + fErr + '\n'; }
    // handle cError
    var t = f.type;
    if ( t=='select-one' || t=='select-multiple' || t=='radio' || t=='checkbox' ) {
        var sErr = o.sErrSelect; }
    else {
        var sErr = o.sErrEnter; }
    o.cError = f.err ? f.err : sErr;
    o.cError = o.cError.replace( '%FIELDNAME%', f.realname ? f.realname : ( (e.id) ? e.id : e.name) );
};
// showErrordialog /////////////////////////////////////////////////////////////
PWForm.prototype.showErrordialog = function() {
    var o = this;
    // yui simpledialog
    if ( o.bYUIErr ) {
        var handleOK = function() { 
					this.hide(); 
					// possible yui bug? anyway .. let's delete everything yui created //
					var cleanUp1 = $D.get( 'simpledialog1_c' );
					var cleanUp2 = $D.get( '_yuiResizeMonitor' );
					var cleanUp3 = $D.get( 'simpledialog1_mask' );
					if ( cleanUp1 ) { cleanUp1.parentNode.removeChild( cleanUp1 ); }
					if ( cleanUp2 ) { cleanUp2.parentNode.removeChild( cleanUp2 ); }
					if ( cleanUp3 ) { cleanUp3.parentNode.removeChild( cleanUp3 ); }
				};
        var d = new YAHOO.widget.SimpleDialog( 'simpledialog1',
            { width: '300px',
              fixedcenter: true,
              visible: false,
              draggable: false,
              close: false,
              text: o.sError+'</'+'ul>',
              constraintoviewport: true,
              modal: true,
              underlay: 'matte',
              buttons: [ { text:o.sYUIErrButton, handler:handleOK, isDefault:true } ]
            } );
        if ( o.sYUIErrHeader ) { d.setHeader( o.sYUIErrHeader ); }
        d.render( document.body );
        d.show();
    // simple javascript alert
    } else {
        alert( o.sError );
    }
};
// showSuccessdialog /////////////////////////////////////////////////////////////
PWForm.prototype.showSuccessdialog = function() {
    var o = this;
    // yui simpledialog
    if ( o.bYUISuc ) {
				var handleOK = function() { 
					this.hide(); 
					// possible yui bug? anyway .. let's delete everything yui created //
					var cleanUp1 = $D.get( 'simpledialog1_c' );
					var cleanUp2 = $D.get( '_yuiResizeMonitor' );
					var cleanUp3 = $D.get( 'simpledialog1_mask' );
					if ( cleanUp1 ) { cleanUp1.parentNode.removeChild( cleanUp1 ); }
					if ( cleanUp2 ) { cleanUp2.parentNode.removeChild( cleanUp2 ); }
					if ( cleanUp3 ) { cleanUp3.parentNode.removeChild( cleanUp3 ); }
				};
        var d = new YAHOO.widget.SimpleDialog( 'simpledialog1',
            { width: '300px',
              fixedcenter: true,
              visible: false,
              draggable: false,
              close: false,
              text: o.sSuccess,
              constraintoviewport: true,
              modal: true,
              underlay: 'matte',
              buttons: [ { text:o.sYUISucButton, handler:handleOK, isDefault:true } ]
            } );
        if ( o.sYUISucHeader ) { d.setHeader( o.sYUISucHeader ); }
        d.render( document.body );
        d.show();
    // simple javascript alert
    } else {
        alert( o.sSuccess );
    }
};
////////////////////////////////////////////////////////////////////////////////
// Field Object ////////////////////////////////////////////////////////////////
function PWField( el, o ) {
    this.name = el.name;
    var CFG = o.CFG[this.name] || false;
    this.type = el.type;
    this.element = el;
    this.elements = new Array();
    this.err = CFG ? CFG.err : el.getAttribute('err');
    // parent element error class set
    this.pcerr = CFG ? CFG.pcerr : this.parseBool( el.getAttribute('pcerr') );
    this.required = CFG ? CFG.required : this.parseBool( el.getAttribute('required') );
    this.realname = CFG ? CFG.realname : el.getAttribute('realname');
    this.exclude = CFG ? CFG.exclude : el.getAttribute('exclude');
    switch ( this.type ) {
        case 'textarea':
        case 'password':
        case 'text':
        case 'file':
            this.value = el.value;
            this.minLength = CFG ? CFG.minlength : el.getAttribute('minlength');
            this.maxLength = CFG ? CFG.maxlength : el.getAttribute('maxlength');
            this.regex = this.getRegex( el, CFG );
            this.minValue = CFG ? CFG.minvalue : el.getAttribute('minvalue');
            this.maxValue = CFG ? CFG.maxvalue : el.getAttribute('maxvalue');
            this.equals = CFG ? CFG.equals : el.getAttribute('equals');
            this.callback = CFG ? CFG.callback : el.getAttribute('callback');
            break;
        case 'select-one':
        case 'select-multiple':
            this.values = new Array();
            for ( var i=0; i<el.options.length; ++i ) {
                if ( el.options[i].selected &&
                   ( !this.exclude || el.options[i].value!=this.exclude ) ) {
                    this.values[this.values.length] = el.options[i].value;
                }
            }
            this.min = CFG ? CFG.min : el.getAttribute('min');
            this.max = CFG ? CFG.max : el.getAttribute('max');
            this.equals = CFG ? CFG.equals : el.getAttribute('equals');
            break;
        case 'checkbox':
            this.min = CFG ? CFG.min : el.getAttribute('min');
            this.max = CFG ? CFG.max : el.getAttribute('max');
        case 'radio':
            //this.required = this.parseBool( this.required || el.getAttribute('required') );
            this.values = new Array();
            if ( el.checked ){ this.values[0]=el.value; }
            this.elements[0] = el;
            break;
    };
}
// isvalid /////////////////////////////////////////////////////////////////////
PWField.prototype.isValid = function( aFields ) {
    var o = this; 
    switch ( o.type ) {
        case "textarea":
        case "password":
        case "text":
        case "file":
            return o.validateText( aFields );
        case "select-one":
        case "select-multiple":
        case "radio":
        case "checkbox":
            return o.validateGroup( aFields );
        default:
            return true;
    }
};
// validatetext ////////////////////////////////////////////////////////////////
PWField.prototype.validateText = function( aFields ) {
    var o = this;
    // handle callback function
    if ( o.required && o.callback ) {
        var fId = o.element.id ? o.element.id : '';
        var fName = o.element.name ? o.element.name : '';
        // bResult=callback('id','name','value');
        eval( 'var bResult='+o.callback+'(\''+fId+'\', \''+fName+'\', \''+o.value+'\');' );
   	if ( !bResult ) { return false; }
        else { return true; }
    }
    // required value is empty
    if ( o.required && !o.value ) { return false; }
    // value less than minlength
    if ( o.value && (o.minLength && o.value.length<o.minLength) ) { return false; }
    // value is more than maxlength
    if ( o.value && (o.maxLength && o.value.length>o.maxLength) ) { return false; }
    // value fails regular expression
    if ( o.regex ) {
	if ( !o.checkRegex( o.regex, o.value) ) {
            // the field isn't required, but there is a value
	    if ( !o.required && o.value ) { return false; }
	    if ( o.required ) { return false; }
        }
        else { return true; }
    }
    // check equality
    if ( o.equals ) {
	for ( var i=0; i<aFields.length; ++i ) {   	   
            var f = aFields[i];
	    if ( (f.element.name==o.equals) || (f.element.id==o.equals) ) {
	       	if ( f.element.value != o.value ) { return false; }
	       	break;
	    }
	}
    }
    // check against minvalue and maxvalue
    if ( o.required ) {
	var fVal = parseFloat( o.value );
	if ( (o.minValue || o.maxValue) && isNaN(fVal) ) { return false; }
	if ( (o.minValue) && (fVal<o.minValue) ) { return false; }
	if ( (o.maxValue) && (fVal>o.maxValue) ) { return false; }
    }
    return true;
};
// validategroup ///////////////////////////////////////////////////////////////
PWField.prototype.validateGroup = function( aFields ){
    var o = this;
    if ( o.required && o.values.length==0 ) { return false; }
    if ( o.required && o.min && o.min>o.values.length ) { return false; }
    if ( o.required && o.max && o.max<o.values.length ) { return false; }
    return true;
};
// seterrorclass ///////////////////////////////////////////////////////////////
PWField.prototype.setErrorClass = function( cN, action ) {
    var o = this;
    var a = action ? true : false;
    var pcerr = pcerr ? true : false;
    // handle group
    if ( (o.elements) && (o.elements.length>0) ) {
        //alert( 'Foo' );
        for ( var i=0; i<o.elements.length; ++i) {
            var e = o.elements[i];
            if (a) { $D.addClass( e, cN ); }
            else if ( $D.hasClass( e, cN ) ) { $D.removeClass( e, cN ); }
        }
    // handle single element
    } else {
        var e = o.element;
        if (a) { $D.addClass( e, cN ); }
        else if ( $D.hasClass( e, cN ) ) { $D.removeClass( e, cN ); }
    }
    // handle parent element
    var e = o.element.parentNode;
    if ( o.pcerr ) {
        if (a) { $D.addClass( e, cN ); }
        else if ( $D.hasClass( e, cN ) ) { $D.removeClass( e, cN ); }
    }
};
// mergefield //////////////////////////////////////////////////////////////////
PWField.prototype.mergeField = function( el ){
    var o = this;
    var req = o.parseBool( el.getAttribute('required') );
    if ( req ) { o.required = true; }
    if ( !o.err ) { o.err = el.getAttribute('err'); }
    if ( !o.equals ) { o.equals = el.getAttribute('equals'); }
    if ( !o.callback ) { o.callback = el.getAttribute('callback'); }
    if ( !o.realname ) { o.realname = el.getAttribute('realname'); }
    if ( !o.max ) { o.max = el.getAttribute('max'); }
    if ( !o.min ) { o.min = el.getAttribute('min'); }
    if ( !o.regex ) { o.regex = o.getRegex( el ); }
    if ( el.checked ) { o.values[o.values.length] = el.value; }
    o.elements[o.elements.length] = el;
};
// parsebool ///////////////////////////////////////////////////////////////////
PWField.prototype.parseBool = function( val ) {
    return !( !val || val==0 || val=="0" || val=='false' );
};
// checkregex //////////////////////////////////////////////////////////////////
PWField.prototype.checkRegex = function( rgx, val ) {
    switch ( rgx ) {
        case "JSVAL_RX_EMAIL":
            return ( ( /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/ ).test( val ) );
        case "JSVAL_RX_TEL":
            return ( ( /^1?[\- ]?\(?\d{3}\)?[\- ]?\d{3}[\- ]?\d{4}$/ ).test( val ) );
        case "JSVAL_RX_PC":
            return ( ( /^[a-z]\d[a-z] ?\d[a-z]\d$/i ).test( val ) );
        case "JSVAL_RX_ZIP":
            return ( ( /^\d{5}$/ ).test( val ) );
        case "JSVAL_RX_NUMERIC_99":
            return ( ( /^\d{1,2}$/ ).test( val ) );
        case "JSVAL_RX_MONEY":
            return ( ( /^\d+([\.]\d\d)?$/ ).test( val ) );
        case "JSVAL_RX_CREDITCARD":
            return ( !isNaN( val ) );
        case "JSVAL_RX_POSTALZIP":
            if( val.length==6 || val.length==7 ) {
                return( ( /^[a-zA-Z]\d[a-zA-Z] ?\d[a-zA-Z]\d$/ ).test( val ) );
            }
            if( val.length==5 || val.length==10 ) {
                return( ( /^\d{5}(\-\d{4})?$/ ).test( val) );
            }
            break;
        default:
            return ( rgx.test( val ) );
    }
};
// getregex ////////////////////////////////////////////////////////////////////
PWField.prototype.getRegex = function( el, CFG ){
    var regex = CFG ? CFG.regex : el.getAttribute('regex');
    if ( regex==null ) { return null; }
    var regexType = typeof( regex );
    regexType = regexType.toUpperCase();
    if ( regexType=='FUNCTION' ) {
        return regex;
    }
    else if ( (regexType=='STRING')
              && !(regex=='JSVAL_RX_EMAIL') && !(regex=='JSVAL_RX_TEL')
   	      && !(regex=='JSVAL_RX_PC') && !(regex=='JSVAL_RX_ZIP')
              && !(regex=='JSVAL_RX_MONEY') && !(regex=='JSVAL_RX_CREDITCARD')
              && !(regex=='JSVAL_RX_POSTALZIP') && !(regex == 'JSVAL_RX_NUMERIC_99') ) {
        var nBegin = 0;
        var nEnd = 0;
        if ( regex.charAt(0)=='/' ) { nBegin=1; }
        if ( regex.charAt(regex.length-1)=='/' ) { nEnd=0; }
        return new RegExp( regex.slice(nBegin, nEnd) );
    }
    else {
        return regex;
    }
};
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////