// Getting the rel data tag //
// Form submission //

(function($){

	$.fn.formConfig = function(options){

		var opts = $.extend( {}, $.fn.formConfig.defaults, options );



		// Loop through resulting elements //
		return this.each(function(){
			var $this = $(this);

			if(opts.preventDocumentUnload){
				window.onbeforeunload = function(){
					if($this.data('AJAX_ON')){
						return 'Tasks are still being completed in the background, are you sure you want to exit?';
					}
				}
			}

			// Find any submit buttons and disable their default behaviour //
			$this.find('input[type="submit"]').remove();

			// Find any a._jsTriggerFormSubmit buttons, and unhide them //
			$this.find('a._jsTriggerFormSubmit').removeClass('hide');

			var checkValid = false;
			// Handle listeners for submitted form //
			for(var obj in opts.listeners){
				var eachObj = opts.listeners[obj];
				for(var e in eachObj){
					var eachArr = eachObj[e];

					for(var x in eachArr){
						var z=0;
						var selector = '';
						var fnc = false;

						for(var y in eachArr){

							if(z == 0){
								selector = eachArr[y];
							}

							if(z == 1){
								fnc = eachArr[y];
							}

							z++;
						}

						// Bind listener //
						listen( $this, e, selector, fnc, opts );
					}
				}
			}

			// Validation //
			if(opts.validator){

				// Check if we're AJAXing the form //
				if(opts.ajaxSubmit){
					opts.validator.preventSubmit = true;
				}

				$this.validate( opts.validator );
				checkValid = true;
			}

			// Handle submission (AJAX or hard-refresh) //
			$this.submit(function(){

				var $each = $(this);

				$each.data('submitted', false);

				var isValid = true;
				if(checkValid){
					if( $each.data('valid') == 0 ){
						isValid = false;
					}
				}
				// If it's not valid, validator will handle //
				if(opts.onBeforeSubmit && isValid){
					if(opts.onBeforeSubmit( $each ) == false){
						return false;
					}
				}

				if(opts.preventSubmit){
					return false;
				}

				if(isValid){
					$each.data('submitted', true);

					if(opts.onSubmit){
						opts.onSubmit( $each );
					}

					if(opts.ajaxSubmit){

						// Turn on AJAX //
						$this.data('AJAX_ON', true);

						submitViaAJAX( $each, opts);
						// Do not submit form as normal //
						// If we need to reset the form parts //


						return false;
					} else {
						// Submit //
						return true;
					}

				}
			});

		});

	}

	function listen( $form, event, selector, fnc, opts ){

		switch(event){
			case 'click':
				$form.find( selector ).click(function(e){

					var $this = $(this);

					if($this.hasClass('_jsConfirmSubmit')){
						var msg = $this.attr('msg');
						if(!confirm(msg)){
							return false;
						}
					}

					if($this.attr('rel')){
						$form.append('<input type="hidden" name="' + $this.attr('rel') + '" value="1" />');
					}

					if(fnc){
						fnc( $form, e );
					}

					$form.submit();

					if(!$form.data('submitted')){
						return false;
					}

					if(opts.disableListener){
						$this.addClass( '_jsDisabled disabled' );
					}

					if(opts.disableForm){
						$form.addClass('_jsDisabled disabled');
						$form.find('input, select, textarea').attr('disabled', true);
					}

				});
				break;

			case 'onKeyEnter' :
				$form.find( selector ).keypress(function(e){
					if(e.keyCode == 13){

						if(fnc){
							fnc( $form, e);
						}

						$form.submit();

						if(!$form.data('submitted')){
							return false;
						}

						var $this = $(this);
						if(opts.disableListener){
							$this.addClass( '_jsDisabled disabled' );
						}

						if(opts.disableForm){
							$form.addClass('_jsDisabled disabled');
							$form.find('input, select, textarea').attr('disabled', true);
						}
					}
				});
				break;

			case 'change' :
				$form.find( selector ).change(function(e){

					var $this = $(this);

					if(fnc){
						fnc( $form, e);
					}

					$form.submit();

					if(!$form.data('submitted')){
						return false;
					}

					if(!$form.data('submitted')){
						return false;
					}

					if(opts.disableListener){
						$this.addClass( '_jsDisabled disabled' );
					}

					if(opts.disableForm){
						$form.addClass('_jsDisabled disabled');
						$form.find('input, select, textarea').attr('disabled', true);
					}

				});
			break;
		}
	}

	function submitViaAJAX($form, opts){

		// Prepare post data object //
		var postData = {};
		$form.find(opts.formElements).each(function(){
			var $this = $(this);
			if(!$this.hasClass( '_jsFormExp' ))
			postData[$this.attr('name')] = $this.val();

			if($this.attr('type') == 'checkbox'){
				if(!$this.attr('checked')){
					delete postData[$this.attr('name')];
				}
			}

		});

		// Tell the script that this is an AJAX request //
		postData[opts.ajaxKeyword] = true;

		// For any more customizable data //
		postData = $.extend( {}, postData, opts.postData );

		if($form.hasClass('_jsFormActive')){
			return false;
		}

		$form.data('postData', postData);

		// Add an active state to the form //
		$form.addClass( '_jsFormActive' );

		var action = $form.attr('action');

		if(!action){
			action = '';
		}

		$.ajax({
			url			: action,
			data		: postData,
			type		: 'POST',
			dataType	: opts.ajaxDataType,
			timeout 	: opts.ajaxTimeout,
			success		: function(data, textStatus, xhr){

				$form.data('AJAX_ON', false);

				// Form is no longer activated //
				$form.removeClass( '_jsFormActive' );
				$form.removeClass('_jsDisabled disabled');
				$form.find('._jsDisabled').removeClass('_jsDisabled disabled');
				$form.find('input, select, textarea').attr('disabled', false);

				if(data.success){
					// Perform success callback //
					if(opts.fnSuccess){
						opts.fnSuccess($form, data, textStatus, xhr);
					}

				} else {
					// Perform failure callback //
					if(opts.fnFailure){
						opts.fnFailure($form, data, textStatus, xhr);
					}
				}

				if(opts.resetForm){
					var $formParts = $form.find('input, textarea').val('');
					$.fn.inputHints.restore( $formParts.removeClass('valPassed') );
				}

			},
			error		: function (xhr, textStatus, errorThrown){

				$form.data('AJAX_ON', false);

				// Form is no longer activated //
				$form.removeClass( '_jsFormActive' );
				$form.removeClass('_jsDisabled disabled');
				$form.find('._jsDisabled').removeClass('_jsDisabled disabled');
				$form.find('input, select, textarea').attr('disabled', false);

				// Errors are for incorrect data type and failed connection //
				if(opts.fnError){
					opts.fnError($form, xhr, textStatus, errorThrown );
				}
			}
		});
	}

	$.fn.formConfig.defaults = {
		listeners		: [{ 'click': ['._jsTriggerFormSubmit'] }],
		disableListener	: true,
		disableForm		: true,
		ajaxSubmit		: false,
		ajaxDataType	: 'json',
		ajaxTimeout		: 20000, // Milisecond timeout //
		ajaxKeyword		: 'ajax_on',
		formElements	: 'input, select, textarea',
		formExceptions	: '._jsFormExp',
		fnSuccess		: function($form, data, textStatus, xhr ){},
		fnFailure		: function($form, data, textStatus, xhr ){},
		fnError			: function($form, xhr, textStatus, errorThrown ){},
		resetForm		: true
	};

})(jQuery);
