/**
 * @projectDescription 	Validates form before submitting regularly or via AJAX
 * @version 			1.0
 * @author 				Alex Heyd - alex.heyd@rga.com - AIM: "overwritten"
 * @date				03/09/2010
 * @lastUpdate 			03/09/2010 
 * @QATech 				n/a
 * @QAPassed 			NO
 * @dependency 			Field.js
 * 						helpers.js
 * @param {Object}		options
 * @param {Boolean}		options.useAjax Whether or not to use AJAX to submit the form
 * @param {Object}		options.fields Passed into $.Field constructor
 * @param {Object}		options.ajaxOptions Used for $.ajax() call
 */

(function($){
	var undefined;
		
	$.Form = function(options){
		var
			self = this,
			settings = $.extend(true, {}, this.defaults, options);
			
		this.$element = settings.$element;
		this.fields = {};
		
		/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		 * start:private
		 * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
		function _init(){
			// build field objects
			$.each(settings.fields, function(fieldName, fieldProperties){
				if (self.$element.find('[name=' + fieldName + ']').exists()){
					fieldProperties.name = fieldName;
					fieldProperties.$element = self.$element.find('[name=' + fieldName + ']');
					self.fields[fieldName] = new $.Field(fieldProperties);
				}
			});
			
			// sets up dependency objects for condition checks
			$.each(settings.fields, function(name, rules){
				var fieldObj = self.fields[name];
				var conditions = fieldObj.getConditions();
				
				$.each(conditions, function(conditionType, condition){
					$.each(condition, function(conditionFieldName, conditionRules){
						$.dispatch('setDependency.' + name, [self.fields[conditionFieldName]]);
					});
				});
			});
			
			self.$element.submit(function(e){
				self.submit(e);
			});
			
			// if custom init method is provided, execute it
			if (this.init) this.init();
		};
		
		// end:private
		
		/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		 * start:public
		 * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
		
		this.submit = function(e){
			$.dispatch('submitted.form');
			var validated = this.validate();
			if (!validated || settings.useAjax) e.preventDefault();
			
			if (validated && settings.useAjax){
				if (settings.ajaxOptions.url == undefined) settings.ajaxOptions.url = self.$element.attr('action');
				settings.ajaxOptions.data = this.getValues();
				$.ajax(settings.ajaxOptions);
			}
			
			(validated) ? $.dispatch('isValid.form') : $.dispatch('isInvalid.form');
			if (validated) this.clear();
		};
		
		this.getValues = function(){
			var values = {};
			
			$.each(this.fields, function(fieldName, fieldObj){
				var val = fieldObj.getValue();
				if (val != '') values[fieldName] = val;
			});
			
			return values;
		};
		
		this.clear = function(){
			this.$element.get(0).reset();
			this.$element.find('.invalid').removeClass('invalid');
			$.each(this.fields, function(fieldName, fieldObj){
				fieldObj.setValue();
			});
			$.dispatch('formReset');
		};
		
		this.validate = function(){
			var valid = true;

			$.each(this.fields, function(fieldName, fieldObj){
				if (!fieldObj.validate()) valid = false;
			});
			
			(valid) ? $.dispatch('isValid.form') : $.dispatch('isInvalid.form');
			
			return valid;
		};
		
		// end:public
		
		_init();
	};
	
	$.Form.prototype.defaults = {
		useAjax: true, fields: {}, ajaxOptions: { dataType: 'json', type: 'GET' }
	};
})(jQuery);


