/**
 * @license jQuery wizard plug-in 3.0.7 (18-SEPT-2012)
 *
 *
 * Copyright (c) 2012 Jan Sundman (jan.sundman[at]aland.net)
 *
 * http://www.thecodemine.org
 *
 * Licensed under the MIT licens:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 */


(function($){
	$.widget("ui.formwizard", {

		_init: function() {

			var wizard = this;
			var formOptionsSuccess = this.options.formOptions.success;
			var formOptionsComplete = this.options.formOptions.complete;
			var formOptionsBeforeSend = this.options.formOptions.beforeSend;
			var formOptionsBeforeSubmit = this.options.formOptions.beforeSubmit;
			var formOptionsBeforeSerialize = this.options.formOptions.beforeSerialize;
			this.options.formOptions = $.extend(this.options.formOptions,{
				success	: function(responseText, textStatus, xhr){
					if(formOptionsSuccess){
						formOptionsSuccess(responseText, textStatus, xhr);
					}
					if(wizard.options.formOptions && wizard.options.formOptions.resetForm || !wizard.options.formOptions){
						wizard._reset();
					}
				},
				complete : function(xhr, textStatus){
					if(formOptionsComplete){
						formOptionsComplete(xhr, textStatus);
					}
					wizard._enableNavigation();
				},
				beforeSubmit : function(arr, theForm, options) {
					if(formOptionsBeforeSubmit){
						var shouldSubmit = formOptionsBeforeSubmit(arr, theForm, options);
						if(!shouldSubmit)
							wizard._enableNavigation();
						return shouldSubmit;
					}
				},
				beforeSend : function(xhr) {
					if(formOptionsBeforeSend){
						var shouldSubmit = formOptionsBeforeSend(xhr);
						if(!shouldSubmit)
							wizard._enableNavigation();
						return shouldSubmit;
					}
				},
				beforeSerialize: function(form, options) {
					if(formOptionsBeforeSerialize){
						var shouldSubmit = formOptionsBeforeSerialize(form, options);
						if(!shouldSubmit)
							wizard._enableNavigation();
						return shouldSubmit;
					}
				}
			});
			
			if (this.options.historyEnabled) {
				$.bbq.removeState("_" + $(this.element).attr('id'));
			}

			this.steps = this.element.find(".step").hide();

			this.firstStep = this.steps.eq(0).attr("id");
			this.activatedSteps = new Array();
			this.isLastStep = false;
			this.previousStep = undefined;
			this.currentStep = this.steps.eq(0).attr("id");
			this.nextButton	= this.element.find(this.options.next)
					.click(function() {
						return wizard._next();
					});

			this.nextButtonInitinalValue = this.nextButton.val();
			this.nextButton.val(this.options.textNext);

				this.backButton	= this.element.find(this.options.back)
					.click(function() {
						wizard._back();return false;
					});

				this.backButtonInitinalValue = this.backButton.val();
				this.backButton.val(this.options.textBack);

			if(this.options.validationEnabled && jQuery().validate  == undefined){
				this.options.validationEnabled = false;
				if( (window['console'] !== undefined) ){
					console.log("%s", "validationEnabled option set, but the validation plugin is not included");
				}
			}else if(this.options.validationEnabled){
				this.element.validate(this.options.validationOptions);
			}
			if(this.options.formPluginEnabled && jQuery().ajaxSubmit == undefined){
				this.options.formPluginEnabled = false;
				if( (window['console'] !== undefined) ){
					console.log("%s", "formPluginEnabled option set but the form plugin is not included");
				}
			}

			if(this.options.disableInputFields == true){
				$(this.steps).find(":input:not('.wizard-ignore')").attr("disabled","disabled");
			}

			if(this.options.historyEnabled){
				$(window).bind('hashchange', undefined, function(event){
					var hashStep = event.getState( "_" + $(wizard.element).attr( 'id' )) || wizard.firstStep;
					if(hashStep !== wizard.currentStep){
						if(wizard.options.validationEnabled && hashStep === wizard._navigate(wizard.currentStep)){
							if(!wizard.element.valid()){
								wizard._updateHistory(wizard.currentStep);
								wizard.element.validate().focusInvalid();

								return false;
							}
						}
						if(hashStep !== wizard.currentStep)
							wizard._show(hashStep);
					}
				});
			}

			this.element.addClass("ui-formwizard");
			this.element.find(":input").addClass("ui-wizard-content");
			this.steps.addClass("ui-formwizard-content");
			this.backButton.addClass("ui-formwizard-button ui-wizard-content");
			this.nextButton.addClass("ui-formwizard-button ui-wizard-content");

			if(!this.options.disableUIStyles){
				this.element.addClass("ui-helper-reset ui-widget ui-widget-content ui-helper-reset ui-corner-all");
				this.element.find(":input").addClass("ui-helper-reset ui-state-default");
				this.steps.addClass("ui-helper-reset ui-corner-all");
				this.backButton.addClass("ui-helper-reset ui-state-default");
				this.nextButton.addClass("ui-helper-reset ui-state-default");
			}
			this._show(undefined);
			return $(this);
		},

		_next : function(){
			if(this.options.validationEnabled){
				if(!this.element.valid()){
					this.element.validate().focusInvalid();
					return false;
				}
			}

			if(this.options.remoteAjax != undefined){
				var options = this.options.remoteAjax[this.currentStep];
				var wizard = this;
				if(options !== undefined){
					var success = options.success;
					var beforeSend = options.beforeSend;
					var complete = options.complete;

					options = $.extend({},options,{
						success: function(data, statusText){
							if((success !== undefined && success(data, statusText)) || (success == undefined)){
								wizard._continueToNextStep();
							}
						},
						beforeSend : function(xhr){
							wizard._disableNavigation();
							if(beforeSend !== undefined)
								beforeSend(xhr);
							$(wizard.element).trigger('before_remote_ajax', {"currentStep" : wizard.currentStep});
						},
						complete : function(xhr, statusText){
							if(complete !== undefined)
								complete(xhr, statusText);
							$(wizard.element).trigger('after_remote_ajax', {"currentStep" : wizard.currentStep});
							wizard._enableNavigation();
						}
					})
					this.element.ajaxSubmit(options);
					return false;
				}
			}

			return this._continueToNextStep();
		},

		_back : function(){
			if(this.activatedSteps.length > 0){
				if(this.options.historyEnabled){
					this._updateHistory(this.activatedSteps[this.activatedSteps.length - 2]);
				}else{
					this._show(this.activatedSteps[this.activatedSteps.length - 2], true);
				}
			}
			return false;
		},

		_continueToNextStep : function(){
			if(this.isLastStep){
				for(var i = 0; i < this.activatedSteps.length; i++){
					this.steps.filter("#" + this.activatedSteps[i]).find(":input").not(".wizard-ignore").removeAttr("disabled");
				}
				if(!this.options.formPluginEnabled){
					return true;
				}else{
					this._disableNavigation();
					this.element.ajaxSubmit(this.options.formOptions);
					return false;
				}
			}

			var step = this._navigate(this.currentStep);
			if(step == this.currentStep){
				return false;
			}
			if(this.options.historyEnabled){
				this._updateHistory(step);
			}else{
				this._show(step, true);
			}
			return false;
		},

		_updateHistory : function(step){
			var state = {};
			state["_" + $(this.element).attr('id')] = step;
			$.bbq.pushState(state);
		},

		_disableNavigation : function(){
			this.nextButton.attr("disabled","disabled");
			this.backButton.attr("disabled","disabled");
			if(!this.options.disableUIStyles){
				this.nextButton.removeClass("ui-state-active").addClass("ui-state-disabled");
				this.backButton.removeClass("ui-state-active").addClass("ui-state-disabled");
			}
		},

		_enableNavigation : function(){
			if(this.isLastStep){
				this.nextButton.val(this.options.textSubmit);
			}else{
				this.nextButton.val(this.options.textNext);
			}

			if($.trim(this.currentStep) !== this.steps.eq(0).attr("id")){
				this.backButton.removeAttr("disabled");
				if(!this.options.disableUIStyles){
					this.backButton.removeClass("ui-state-disabled").addClass("ui-state-active");
				}
			}

			this.nextButton.removeAttr("disabled");
			if(!this.options.disableUIStyles){
				this.nextButton.removeClass("ui-state-disabled").addClass("ui-state-active");
			}
		},

		_animate : function(oldStep, newStep, stepShownCallback){
			this._disableNavigation();
			var old = this.steps.filter("#" + oldStep);
			var current = this.steps.filter("#" + newStep);
			old.find(":input").not(".wizard-ignore").attr("disabled","disabled");
			current.find(":input").not(".wizard-ignore").removeAttr("disabled");
			var wizard = this;
			old.animate(wizard.options.outAnimation, wizard.options.outDuration, wizard.options.easing, function(){
				current.animate(wizard.options.inAnimation, wizard.options.inDuration, wizard.options.easing, function(){
					if(wizard.options.focusFirstInput)
						current.find(":input:first").focus();
					wizard._enableNavigation();

					stepShownCallback.apply(wizard);
				});
				return;
			});
		},

		_checkIflastStep : function(step){
			this.isLastStep = false;
			if($("#" + step).hasClass(this.options.submitStepClass) || this.steps.filter(":last").attr("id") == step){
				this.isLastStep = true;
			}
		},

		_getLink : function(step){
			var link = undefined;
			var links = this.steps.filter("#" + step).find(this.options.linkClass);

			if(links != undefined){
				if(links.filter(":radio,:checkbox").size() > 0){
					link = links.filter(this.options.linkClass + ":checked").val();
				}else{
					link = $(links).val();
				}
			}
			return link;
		},

		_navigate : function(step){
			var link = this._getLink(step);
			if(link != undefined){
				if((link != "" && link != null && link != undefined) && this.steps.filter("#" + link).attr("id") != undefined){
					return link;
				}
				return this.currentStep;
			}else if(link == undefined && !this.isLastStep){
				var step1 =  this.steps.filter("#" + step).next().attr("id");
				return step1;
			}
		},

		_show : function(step){
			var backwards = false;
			var triggerStepShown = step !== undefined;
			if(step == undefined || step == ""){
					this.activatedSteps.pop();
					step = this.firstStep;
					this.activatedSteps.push(step);
			}else{
				if($.inArray(step, this.activatedSteps) > -1){
					backwards = true;
					this.activatedSteps.pop();
				}else {
					this.activatedSteps.push(step);
				}
			}

			if(this.currentStep !== step || step === this.firstStep){
				this.previousStep = this.currentStep;
				this._checkIflastStep(step);
				this.currentStep = step;
				var stepShownCallback = function(){if(triggerStepShown){$(this.element).trigger('step_shown', $.extend({"isBackNavigation" : backwards},this._state()));}}
				if(triggerStepShown){
					$(this.element).trigger('before_step_shown', $.extend({"isBackNavigation" : backwards},this._state()));
				}
				this._animate(this.previousStep, step, stepShownCallback);
			};


		},

	   _reset : function(){
			this.element.resetForm()
			$("label,:input,textarea",this).removeClass("error");
			for(var i = 0; i < this.activatedSteps.length; i++){
				this.steps.filter("#" + this.activatedSteps[i]).hide().find(":input").attr("disabled","disabled");
			}
			this.activatedSteps = new Array();
			this.previousStep = undefined;
			this.isLastStep = false;
			if(this.options.historyEnabled){
				this._updateHistory(this.firstStep);
			}else{
				this._show(this.firstStep);
			}

		},

		_state : function(state){
			var currentState = { "settings" : this.options,
				"activatedSteps" : this.activatedSteps,
				"isLastStep" : this.isLastStep,
				"isFirstStep" : this.currentStep === this.firstStep,
				"previousStep" : this.previousStep,
				"currentStep" : this.currentStep,
				"backButton" : this.backButton,
				"nextButton" : this.nextButton,
				"steps" : this.steps,
				"firstStep" : this.firstStep
			}

			if(state !== undefined)
				return currentState[state];

			return currentState;
		},

	  /*Methods*/

		show : function(step){
			if(this.options.historyEnabled){
				this._updateHistory(step);
			}else{
				this._show(step);
			}
		},

		state : function(state){
			return this._state(state);
		},

		reset : function(){
			this._reset();
		},

		next : function(){
			this._next();
		},

		back : function(){
			this._back();
		},

		destroy: function() {
			this.element.find("*").removeAttr("disabled").show();
			this.nextButton.unbind("click").val(this.nextButtonInitinalValue).removeClass("ui-state-disabled").addClass("ui-state-active");
			this.backButton.unbind("click").val(this.backButtonInitinalValue).removeClass("ui-state-disabled").addClass("ui-state-active");
			this.backButtonInitinalValue = undefined;
			this.nextButtonInitinalValue = undefined;
			this.activatedSteps = undefined;
			this.previousStep = undefined;
			this.currentStep = undefined;
			this.isLastStep = undefined;
			this.options = undefined;
			this.nextButton = undefined;
			this.backButton = undefined;
			this.formwizard = undefined;
			this.element = undefined;
			this.steps = undefined;
			this.firstStep = undefined;
		},

		update_steps : function(){
			this.steps = this.element.find(".step").addClass("ui-formwizard-content");
			this.firstStep = this.steps.eq(0).attr("id");
			this.steps.not("#" + this.currentStep).hide().find(":input").addClass("ui-wizard-content").attr("disabled","disabled");
			this._checkIflastStep(this.currentStep);
			this._enableNavigation();
			if(!this.options.disableUIStyles){
				this.steps.addClass("ui-helper-reset ui-corner-all");
				this.steps.find(":input").addClass("ui-helper-reset ui-state-default");
			}
		},

		options: {
	   		historyEnabled	: false,
			validationEnabled : false,
			validationOptions : undefined,
			formPluginEnabled : false,
			linkClass	: ".link",
			submitStepClass : "submit_step",
			back : ":reset",
			next : ":submit",
			textSubmit : 'Submit',
			textNext : 'Next',
			textBack : 'Back',
			remoteAjax : undefined,
			inAnimation : {opacity: 'show'},
			outAnimation: {opacity: 'hide'},
			inDuration : 400,
			outDuration: 400,
			easing: 'swing',
			focusFirstInput : false,
			disableInputFields : true,
			formOptions : { reset: true, success: function(data) { if( (window['console'] !== undefined) ){console.log("%s", "form submit successful");}},
			disableUIStyles : false
		}
   }
 });
})(jQuery);
