﻿/// <reference path="../../../../jQuery/1.3.2/jquery-1.3.2-vsdoc.js" />

/**
*
* mp-search-configuration
*
* This class manages the search criterion on the server enviroment
*
* Hooks up the change event on mp-control-data control, via ajax:
*	- Validates search criteria selection.
*	- Re-binds user search on the their session on the server.
*	- Responds with a stock count of their current search crition selection.
*	- Refreshs ui diplay with stock count.
*
* Author : Marc Lancashire
*/

	// Check that namespace into which the Class definition will be creates has been defined & if not then create

	if (!mrm.global.isNamespaceDefined("mrm.common.display")) mrm.global.createNamespace("mrm.common.display", "1.0");

	// Class definition : 

	mrm.common.display.SearchConfiguration = Object.subClass
	(
		{
			/*
			=============================
			CONSTANTS
			=============================
			*/
			DEBUG								: false,

			ARGUMENT_WORKFLOW					: "wflw",
			
			WORKFLOW_ACTION						: "_re_pr",
			
			MODE_ALLWAYS_BIND					: true,
			
			SELECTOR_FORM						: "form.mp-search-count",
			SELECTOR_BIND_INPUTS				: "form.mp-search-count input.mp-control-data, form.mp-search-count select.mp-control-data",
			SELECTOR_DATA_INPUTS				: "input:text.mp-control-data, select.mp-control-data, input:checked.mp-control-data, input:selected.mp-control-data, input[type = 'hidden'].mp-control-data",
			SELECTOR_DATACOUNTERS				: "#mp-stock-count",
			SELECTOR_FORM_SUBMITS				: ".validatePostcode",

			"MRM_STOCK_COUNT_REFRESH"			: "MRM-STOCK-COUNT-REFRESH",

			ASYNC_WORK_FLOW_TIMER				: 0,
			SEARCH_SYNC_DELAY					: 500,
			
			DEFAULT_INPUT_VALIDATION_RESULT		: true,
			DEFAULT_STATE						: "...",

			HANDLER_URL							: "/Handlers/cta.ashx",

			/*
			=============================
			CONSTRUCTOR
			=============================
			*/
			init: function() {
				
			},


			/*
			=============================
			PUBLIC MEMBERS
			=============================
			*/
			
			// bind an entire containers data elements
			"bind": function(jqContainer)
			{
				var __this = this;

				if (jqContainer.find(this.SELECTOR_FORM).length == 0)
				{
					jqContainer = jqContainer.closest(this.SELECTOR_FORM).parent();
				}

				// bind the stock count refresh to the form
				jqContainer.unbind(this.MRM_STOCK_COUNT_REFRESH);
				jqContainer.bind(this.MRM_STOCK_COUNT_REFRESH,
					function (jqEvent)
					{
						__this._syncSearchCriteria(jqContainer);
					}
				);

				jqContainer.find(this.SELECTOR_BIND_INPUTS).bind("change.stock-count", null , function(e) { __this.OnDataElementChange(e); });
				jqContainer.find(this.SELECTOR_BIND_INPUTS).bind("clear", null , function(e) { __this.clearDataRequestTimeout(e); });
			},
			
			// bind a single data element
			"bindDataElement": function(jqDataElement)
			{
				var __this = this;
				
				jqDataElement.bind("change.stock-count", null , function(e) { __this.OnDataElementChange(e); });
				jqDataElement.bind("clear", null , function(e) { __this.clearDataRequestTimeout(e); });
			},
			
			// carries out a search criteria change event
			OnDataElementChange: function(event) {
				
				this._debugtrace("OnDataElementChange");

				dataElement = $(event.target);

				if (this.MODE_ALLWAYS_BIND || this.ValidateInput(dataElement,false))
				{
					this.GetStockCount(dataElement);
				}
				else
				{
					this.OnInvalidInput(null, dataElement);
				}
			},
			
			
			clearDataRequestTimeout : function  (e)
			{
				clearTimeout(this.ASYNC_WORK_FLOW_TIMER);
			},
			
			
			// carries out a search form submit event
			OnSearchFormSubmit: function(event)
			{
				this._debugtrace("OnSearchFormSubmit");
				
				jqDataElement = ($(event.target).is("form"))? $(event.target) : $(event.target).closest("form"); // this should be a form
				
				var isValid = this.ValidateInput(jqDataElement, true);
				
				if (!isValid)
				{
					this.OnInvalidInput(jqDataElement, null, true);
				}
				else
				{
					jqDataElement.trigger("submit");
				}
				
				return isValid;
			},
			
			
			// validates the users search criteria input
			ValidateInput: function(jqDatalement, throwError) {

				this._debugtrace("ValidateInput");

				return this.DEFAULT_INPUT_VALIDATION_RESULT;
			},

			// called when the users search criteria is invalid, called from form submission and criteria change
			OnInvalidInput: function(jqFormElement, jqDataElement, throwError) {

				this._debugtrace("Invalid Input");

			},

			// carries out a delayed stock count and search criteria re-sync
			GetStockCount: function(jqDataElement) {

				this._debugtrace("GetStockCount");

				clearTimeout(this.ASYNC_WORK_FLOW_TIMER);

				// scope
				var currentScope = this;

				this.ASYNC_WORK_FLOW_TIMER = setTimeout(function() { currentScope._syncSearchCriteria(jqDataElement) }, this.SEARCH_SYNC_DELAY);
			},
			
			// carries out an imedate stock count and search criteria re-sync
			GetStockCountNow: function(jqDataElement)
			{
				this._syncSearchCriteria(jqDataElement);
			},

			// raised on change of the stock count
			OnStockCountChange: function(stockCount) {

				this._debugtrace("Stock Count = " + stockCount + ".");

			},

			/*
			=============================
			PUBLIC SYNC METHODS
			=============================
			*/

			OnSyncBefore: function() {

				this._debugtrace("OnSyncBefore");

				$(this.SELECTOR_DATACOUNTERS).html(this.DEFAULT_STATE);
			},

			OnSyncError: function(XMLHttpRequest, textStatus, errorThrown) {

				this._debugtrace("OnSyncError");
				
				return;
			},

			OnSyncSuccess: function(p_response) {

				this._debugtrace("OnSyncSuccess:{" + p_response + "}");

				var result = eval(p_response);
				
				this.callbackUtilities.processResultControls(result);

				this.OnStockCountChange(p_response);

				return;
			},


			/*
			=============================
			PRIVATE MEMBERS
			=============================
			*/

			// 
			_syncSearchCriteria: function(dataElement) {

				this._debugtrace("_syncSearchCriteria");

				// get parent form				
				var formElement = (dataElement.is("form")) ? dataElement : dataElement.parents(this.SELECTOR_FORM);
				if (formElement.length < 1) formElement = $(document).find(this.SELECTOR_FORM);
				//var formElement = dataElement.parents(this.SELECTOR_FORM);

				// get work flow key from mp-sync-key data item in form
				var wflw = this._workflowKey(formElement);

				// setup ajax call
				$.ajaxManager.clearArguments();

				$.ajaxManager.ajaxSettings.arguments.add(this.ARGUMENT_WORKFLOW, wflw);

				// add search criteria arguments to ajax call
				formElement.find(this.SELECTOR_DATA_INPUTS).each(
					function() {
						var inputElement = $(this);
						$.ajaxManager.ajaxSettings.arguments.add(inputElement.attr("name"), inputElement.val());
					}
				)

				// set the base url for the handler
				$.ajaxManager.ajaxSettings.requestUrl = this.HANDLER_URL;

				// set url
				$.ajaxManager.updateUrl($.ajaxManager.ajaxSettings.arguments.getString("&"));

				var currentScope = this;

				// bind before send
				$.ajaxManager.onBeforeSend = function() { currentScope.OnSyncBefore() };

				// bind error
				$.ajaxManager.onError = function(XMLHttpRequest, textStatus, errorThrown) { currentScope.OnSyncError(XMLHttpRequest, textStatus, errorThrown) };

				// bind success
				$.ajaxManager.onSuccess = function(p_response) { currentScope.OnSyncSuccess(p_response) };

				// fire ajax request
				$.ajaxManager.makeRequest();
			},

			_workflowKey: function(formElement, workflowAction)
			{
				var wfa = workflowAction;
				if (!wfa)
				{
					wfa = this.WORKFLOW_ACTION;
				}
				
				return mrm.global.utilities.workflow.getScopedWorkflowKey(formElement, wfa);
			},

			_debugtrace: function(message, override) {

				if (this.DEBUG || override) {
					alert("[Search Configuration] " + message);
				}
			}

		}
	);

	//alert("mrm.common.display.SearchConfiguration");

