var Helper = 
{
	getEl: function(id) { return document.getElementById(id); },
    removeElement: function( el ) {if ( Helper.getEl(el) != null ) { var e = Helper.getEl(el); var p = e.parentNode; if (p) {p.removeChild( e );} }},
	extend: function(destination, source)
	{
		for(property in source)
		{ destination[property] = source[property]; }
		return destination;
	},
    log: function(s)
	{
		if (window.console && console.log)
		{ console.log(s); } 
	},
    fromCamelCase: function(s)
    {
        s = s.replace(/([A-Z])/g, ' $1');
        s = s.substring(0, 1).toUpperCase() + s.substring(1);
        return s;
    }
};
var Validator =
{
	phone: function(field)
	{
        var val = field.value;
		val = val.replace(/[^0-9]/g, '' );
        if (val.length == 0 && !field.required) { return true; }
        var filter = /^(1?(-?\d{3})-?)?(\d{3})(-?\d{4})$/;
        return (val.indexOf('555') != 0 && val.indexOf('555') != 3 && val.indexOf('000') != 0 && val.indexOf('1') != 0 && val.length >= 10 && filter.test(val));
	},
    name: function(field)
    {
        var val = field.value.replace(/\s|^first$|^last$/gi, '');
        if (val == '') {field.value = val;}
        return (val != '');
    },
    email: function(field)
	{
		var val = field.value;
        val = val.replace(/\s/gi, '');
        var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9])+$/;
        return filter.test(val) ;
	},
	password: function(field)
	{
		var val = field.value;
        if (val.length == 0 && !field.required) { return true; }
        return (val.length >= 4 && val.indexOf(" ") == -1);
	},
	zip: function(field)
	{
		var val = field.value;
           prePopZip = val;
           var callbackProxy = function( serverData )
            {
               if (serverData == true)
               {
                   myPass(field);
               }
                else
               {
                   myFail(field);
               }
            }
            var errorbackProxy  = function( message )
            {
            };
            var callMetaData =
            {
               callback: callbackProxy,
               errorHandler: errorbackProxy,
               timeout:3000
            };
            DWRZIPValidate.validateZip( val, true, callMetaData );
    },
	required: function(field)
	{
		var val = field.value.replace(/\s/gi, '');
        return (val != '');
	},
	none: function() { return true; }
};
var SmartFormConfig =
{
	seekRuleSet:   'ruleSet',
	seekReqSet:    'reqSet',
	disallowTypes: 'submit reset button image hidden checkbox select option',
	validator: Validator,
	passHandler: function(){ Helper.log('pass'); },
	failHandler: function(){ Helper.log('fail'); }
}
var SmartForm = function(form, options)
{
	var $this = this;
    var opt = SmartFormConfig;
	if (options) { opt = Helper.extend(SmartFormConfig, options); }
	if (!form) { return  false; }
	if ( typeof form == 'string') { form = Helper.getEl(form); }
    var ruleSet = form[opt.seekRuleSet].value.split(", ");
	var reqSet =  form[opt.seekReqSet].value.split(", ");
	Helper.removeElement('ruleSet'); Helper.removeElement('reqSet');
	var inputs = form.elements;
	var matchesIndx = 0;
    this.pass = function(field)
	{
		field.validData = true;
        opt.passHandler.apply(this, arguments);
	};
	this.fail = function(field)
	{
		field.validData = false;
        opt.failHandler.apply(this, arguments);
	};
    this.validate = function(field)
	{
		var req = valid = false;
        if (!field.useRule || field.useRule == '') { return; }
        if (field.required)
		{
			req = opt.validator.required.apply(this, arguments);
		}
		else
		{ req = true; }
		valid = opt.validator[field.useRule].apply(this, arguments);
        if (!field.name.match(/zip/gi))
        {
            if (req && valid) { this.pass(field);}
            else { this.fail(field); }
        }
        field.hasValidated = true
    };
    this.validateAll = function()
    {
        for (var i=0; i < inputs.length; i++)
        {
            var myTypeRegEx = new RegExp(inputs[i].tagName, "gi");
            if (inputs[i].tagName.match(/input/gi))
            {
                myTypeRegEx = new RegExp(inputs[i].type, 'gi');
            }
            if( !myTypeRegEx.test(opt.disallowTypes) )
            {
                var myField = inputs[i];
                if (myField.value == 'First' || myField.value == 'Last')
                { myField.value = ''; }
                myField.validate();
            }

        }
    };
    for (var i=0; i < inputs.length; i++)
	{
		var myTypeRegEx = new RegExp(inputs[i].tagName, "gi");
        if (inputs[i].tagName.match(/input/gi))
        {
            myTypeRegEx = new RegExp(inputs[i].type, 'gi');
        }
        if( !myTypeRegEx.test(opt.disallowTypes) )
		{
			var $$this = inputs[i];
            $$this.validate = function() {$this.validate(this);}
            $$this.useRule = ruleSet[matchesIndx];
            for (var j=0; j < reqSet.length; j++ )
			{
				var tmpRegex = new RegExp($$this.name + "$");
                $$this.required = false;
                if (tmpRegex.test(reqSet[j]))
				{
					$$this.required = true;
					break;
				}
			}
			$$this.oldonblur = $$this.onblur;
			$$this.onblur = function()
			{
				$this.validate(this);
				if (this.oldonblur instanceof Function)
				{
					this.oldonblur.apply(this);
				}
			}
            matchesIndx++;
		}
	}
	this.form = form;
	return this;
}