/**
 * Formsubmit
 */
jQuery.fn.formSubmit = function(option) {
	// Try catch environment
	try {
		// Early exit no element selected
		if (!this.length) {
			throw('No element selected ');
		}
		
		// If empty options create empty objct
		var options = option || {};
		
		// Define method
		if(options.allowScript) {
			var type = "GET";
			var dataType = "jsonp";
		} else {
			var type = "POST";
			var dataType = "json";
		}
		
		// If function put it as success function
		if (typeof options == 'function')
			options = { success: options };
	
		// Url, clean url
		var url = $.trim(this.attr('action'));
		if (url) 
			url = (url.match(/^([^#]+)/)||[])[1];
		url = url || window.location.href || '';
		
		// Gather form, add if data
		var form = this.formToArray();
		
		if (options.data) {
			options.extraData = options.data;
			for (var n in options.data) {
			  if(options.data[n] instanceof Array) {
				for (var k in options.data[n])
				  form.push( { name: n, value: options.data[n][k] } );
			  }
			  else
				 form.push( { name: n, value: options.data[n] } );
			}
		}
		
		// Give pre-submit callback an opportunity to abort the submit
		if (options.before && options.before(form, options) === false) {
			return;
		}
		
		// Param length
		if($.param(form).length - url.length + 1 > 2030) {
			if(options.allowPost) {
				var type = "POST";
				var dataType = "json";
			} else {
				throw('Data length exceeds GET limit');
			}
		}
		
		// Add method parameter
		form.push( { name: "method_", value: dataType } );
		
		// Do request with form data
		$.ajax({
			type: type,
		    url: url,
		    dataType: dataType,
		    data: form,
		    jsonp: "callback_",
		    success: function(data, textStatus) {
				if(data.result && data.result == 'success') {
					// Call google analytics if defined
					if(options.analytics && data.analytics) {
						$.analytics(options.analytics, data.analytics);
					}
					
					// Call success function if defined
					if(options.success) {
						options.success(data);
					}
				} else  {
					// Call error function if defined
					if (options.error) {
						options.error(data);
					}
				}
			},
		    error: function(request, textStatus){
		        var data = { error: textStatus, request : request};
		        
		        if(options.error) {
		        	options.error(data);
		        }
		    }
		});	
	} catch(error) {
		alert('Submit error: ' + error);
	}
}

/**
 * formToArray() gathers form element data into an array of objects
 */
jQuery.fn.formToArray = function() {
	var a = [];
	if (this.length == 0) return a;

	var form = this[0];
	var els = form.elements;
	if (!els) return a;
	
	for (var i=0; true; i++) {
		if (typeof(els[i]) == 'undefined') {
			break;
		}
		
		var el = els[i];
		var n = el.name;
		if (!n) continue; 

		var v = $.fieldValue(el, true);
		if (v && v.constructor == Array) {
			for(var j=0, jmax=v.length; j < jmax; j++)
				a.push({name: n, value: v[j]});
		}
		else if (v !== null && typeof v != 'undefined')
			a.push({name: n, value: v});      
	}
	
	return a;
};

/**
 * Returns the value(s) of the element in the matched set.
 */
jQuery.fn.fieldValue = function(successful) {
	for (var val=[], i=0, max=this.length; i < max; i++) {
		var el = this[i];
		var v = $.fieldValue(el, successful);
		if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
			continue;
		v.constructor == Array ? $.merge(val, v) : val.push(v);
	}
	return val;
};

/**
* Returns the value of the field element.
*/
jQuery.fieldValue = function(el, successful) {
	var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
	if (typeof successful == 'undefined') successful = true;

	if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
		(t == 'checkbox' || t == 'radio') && !el.checked ||
		(t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
		tag == 'select' && el.selectedIndex == -1))
			return null;

	if (tag == 'select') {
		var index = el.selectedIndex;
		if (index < 0) return null;
		var a = [], ops = el.options;
		var one = (t == 'select-one');
		var max = (one ? index+1 : ops.length);
		for(var i=(one ? index : 0); i < max; i++) {
			var op = ops[i];
			if (op.selected) {
				var v = op.value;
				if (!v) // extra pain for IE...
					v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
				if (one) return v;
				a.push(v);
			}
		}
		return a;
	}
	return el.value;
};

/**
 * Process analytics
 */
jQuery.analytics = function(google_object, analytics) {
	if(analytics.transaction) {
		var addTransaction = ['_addTrans'];
		
		for(var i=0; i < analytics.transaction.length; i++) {
			addTransaction[i+1] = analytics.transaction[i];
		}
		
		if(addTransaction.length > 1) {
			google_object.push(addTransaction);
		}
	}
	
	if(analytics.items) {
		for (var key in analytics.items) {
			var addItem = ['_addItem'];
			
			for(var i=0; i < analytics.items[key].length; i++) {
				addItem[i+1] = analytics.items[key][i];
			}
			
			if(addItem.length > 1) {
				google_object.push(addItem);
			}
		}
	}
	
	google_object.push(['_trackTrans']);
}