
(function() {
	var $package = jsPackage("epoint.ow.ajaxflow");
	
	var StateManager = $package.StateManager = {
		currentState : {},
		
		setCurrentState : function(flowName, stateName) {
			this.currentState[flowName] = stateName;
		},
		
		getCurrentState : function(flowName) {
			var name = this.currentState[flowName];
			if (name) {
				return name;
			} else {
				return null;
			}
		},
		
		getFlowMethodsObject : function(flowName) {
			return jsPackage("epoint.ow.ajaxflow.flowmethods." + flowName);
		},
		
		runPreContentReplaceMethod : function(flowName, state) {
			if (state != null) {
				var methodName = "pre_content_replace_" + state;
				return this.runFlowMethod(flowName, methodName);
			}
			
			return true;
		},
		
		runPreTransitMethod : function(flowName, state) {
			if (state != null) {
				var methodName = "pre_transit_" + state;
				return this.runFlowMethod(flowName, methodName);
			}
			
			return true;
		},
		
		runPreStateMethod : function(flowName, state) {
			if (state != null) {
				var methodName = "pre_" + state;
				return this.runFlowMethod(flowName, methodName);
			}
			
			return true;
		},
		
		runPreAlwaysStateMethod : function(flowName, state) {
			if (state != null) {
				var methodName = "pre_always_" + state;
				return this.runFlowMethod(flowName, methodName);
			}
			
			return true;
		},
		
		runPostStateMethod : function(flowName, state) {
			if (state != null) {
				var methodName = "post_" + state;
				return this.runFlowMethod(flowName, methodName);
			}
			
			return true;
		},
		
		runPostAlwaysStateMethod : function(flowName, state) {
			if (state != null) {
				var methodName = "post_always_" + state;
				return this.runFlowMethod(flowName, methodName);
			}
			
			return true;
		},
		
		runFlowMethod : function(flowName, methodName) {
			if (methodName != null) {
				var flow = this.getFlowMethodsObject(flowName);
				if (flow[methodName]) {
					return flow[methodName](this.getCurrentState(flowName));
				}	
			}
			
			return true;
		},
		
		transit : function(flowName, url, divId) {
			var oldState = StateManager.getCurrentState(flowName);
			var callbackFn = StateManager.getCallbackFunction(flowName, divId, oldState);
			StateManager.lockDiv(divId);
			$.post(url, [], callbackFn, "json");
		},
		
		reload : function(flowName, url, divId) {
			var oldState = StateManager.getCurrentState(flowName);
			var callbackFn = StateManager.getCallbackFunction(flowName, divId, oldState);
			StateManager.lockDiv(divId);
			$.post(url, [], callbackFn, "json");
		},
		
		getCallbackFunction : function(flowName, divId, oldState) {
			return function(response) {
				if (response) {
					var newState = response.currentStateName;
					StateManager.setCurrentState(flowName, newState);
					
					StateManager.runPreContentReplaceMethod(flowName, oldState);
					$('#' + divId).html(response.stateContent);
					epoint.ow.DocumentReadyManager.runAllActions();
					
					StateManager.runPostAlwaysStateMethod(flowName, oldState);
					if (oldState != newState) {
						StateManager.runPostStateMethod(flowName, oldState);
					}
					
					StateManager.runPreAlwaysStateMethod(flowName, newState);
					if (oldState != newState) {
						StateManager.runPreStateMethod(flowName, newState);
					}
				}
				StateManager.unlockDiv(divId);
			};
		},
		
		registerDefaultSubmitEventHandler : function(formName, flowName, divId) {
			var form = epoint.ow.Utils.getForm(formName);
			$(form).submit(function(e, action) {
				var deferred = jQuery.Deferred();
			
				deferred.done(function () {
					epoint.ow.forms2.Utils.runFormValidationSuccessActions(formName);
					
					var oldState = StateManager.getCurrentState(flowName);
					
					var valid = StateManager.runPreTransitMethod(flowName, oldState);
					if (!(valid == true)) {
						return;
					}
					
					var callbackFn = StateManager.getCallbackFunction(flowName, divId, oldState);
					
					if (epoint.ow.forms2.Utils.containsNotEmptyFileFields(formName)) {
						epoint.ow.forms2.AjaxManager.submitFormWithIFrame(formName, callbackFn, ["iframe_submit", true], action, "json");
					} else {
						epoint.ow.forms2.AjaxManager.submitForm(formName, callbackFn, null, action, "json", null);
					}
				});
				
				deferred.fail(function () {
					StateManager.unlockDiv(divId);
					epoint.ow.forms2.Utils.runFormValidationFailedActions(formName);
				});
			
				StateManager.lockDiv(divId);
				epoint.ow.forms2.Utils.validateForm(formName, deferred);
				return false;
			});
		},
		
		submitFormWithoutValidation : function(formName, action, flowName, divId) {
			var oldState = StateManager.getCurrentState(flowName);
			var callbackFn = StateManager.getCallbackFunction(flowName, divId, oldState);
			
			StateManager.lockDiv(divId);
			
			if (epoint.ow.forms2.Utils.containsNotEmptyFileFields(formName)) {
				epoint.ow.forms2.AjaxManager.submitFormWithIFrame(formName, callbackFn, ["iframe_submit", true], action, "json");
			} else {
				epoint.ow.forms2.AjaxManager.submitForm(formName, callbackFn, null, action, "json", null);
			}
			return false;
		},
		
		lockDiv : function(divId) {
			var o = $("#" + divId);
			$("<div>").addClass('box_cover').attr('id', StateManager.getLockDivId(divId)).css({
				left: o.position().left,
				top: o.position().top,
				width: o.width(),
				height: o.height(),
				"opacity": 0.5
			}).insertBefore(o);


		},
		
		unlockDiv : function(divId) {
			$("#" + StateManager.getLockDivId(divId)).remove();
		},
		
		getLockDivId : function(divId) {
			return divId + "_cover";
		}
	};
})();
