﻿


/// <reference path="../jQuery/1.3.2/jquery-1.3.2-vsdoc.js" />


/**
*****************************************************************
* CLASS TEMPLATE
*****************************************************************
*
* Class description : Handles Ajax Work Flow Link call backs
*
* Author : Rob E
*/


//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");
}


mrm.common.display.AjaxConditionalLinkManager = Object.subClass(
		{
			/*
			=============================
			CONSTANTS
			=============================
			*/
			REQUEST_ARGUMENT_CORE_ID				: "vhl",
			RESPONSE_ARGUMENT_RETURN_CORE_ID		: "rvhl",
			DEBUG									: false,

			
			/*
			=============================
			CONSTRUCTOR
			=============================
			*/
			init: function (instanceReferenceString) 
			{
				var _this = this;
				var container = $(document);
				
				this.instanceString = instanceReferenceString;
				
				_this.bindAllAjaxConditionalLinks(container);
			},



			/*
			 =============================
			 CONFIGURATION PROPERTIES (instance configuration)
			 =============================
			 */
				instanceString : undefined,
				
				

			/*
			=============================
			INTERNAL METHODS
			=============================
			*/
			
			//function used to bind all conditional click events
			bindAllAjaxConditionalLinks : function (container) {			
				var _this = this;
				
				//bind any ajax links that aren't compare link
				container.find(".ajax-conditional-workflow-link:not(.ajax-conditional-workflow-link-compare)").each(function () {
					_this._bindNonCompareConditionalLink($(this));
				});

				//bind the compare links 
				container.find(".ajax-conditional-workflow-link-compare").each(function () {
					_this._bindCompareConditionalLink($(this));
				});
			},
			
			/* this is what the refracture of this class should look like */
			handleConditionalLinkClick : function (e)
			{
				var _this = this;
				var jqLink = $(e.target);
				
				// this
					// limit check
					// process ajax request
				
				// process ajax request
					// update ajax url
					// handle ajax onBeforeSend
					// handle ajax onSuccess
					// handle ajax onError
					// ajax make request
				
				// onBeforeSent
					// set loading state
					
				// onError
					// set error state
					
				// onSucess
					// get state
					// process state
					// process return arguments state
					// update counter
			},
			
			//function used to bind all of the noncompare conditional click events
			_bindNonCompareConditionalLink : function (link, scopedClass)
			{
				var _this = (scopedClass) ? scopedClass : this;
				
				if (link.attr('href').indexOf('.ashx') > -1) {
					link.click(function (event) {
						//stop the default click through from happening
						event.preventDefault();
						var hdnFavouriteCount = $('input#hdnFavouriteCount');
						var spnFavouriteCount = $('span.user-toolbar-favourite-count');
						var FavouriteCountInt = parseInt(hdnFavouriteCount.val());

						var id = link.attr('id');

						//now display the loading state
						var loading = eval(id + '.loading');

						//get the href to use for the ajax call
						var href = link.attr('href');

						//display the loading state and then
						var loadingElement = $(loading);

						//$(this).after(loadingElement).remove(); 
						$(this).replaceWith(loadingElement);

						//make the ajax call
						$.ajaxManager.updateUrl(href);
						$.ajaxManager.onSuccess = function (p_response) {
							_this._processAjaxRequest(p_response, id, loadingElement, "input#hdnFavouriteCount");
						};
						$.ajaxManager.makeRequest();
						//hdnFavouriteCount.val(FavouriteCountInt + 1);
						//spnFavouriteCount.html(FavouriteCountInt + 1);
						//spnFavouriteCount.parent().css({ 'display': 'block' });
					});
				}
			},
					
			//function used to bind the compare conditional links, this adds in the jqModal functionality once the limit is reached
			_bindCompareConditionalLink : function (link, scopedClass) {
				var _this = (scopedClass) ? scopedClass : this;

				if (link.attr('href').indexOf('.ashx') > -1) {
					link.click(function (event) 
					{
						event.preventDefault();
						
						var containerTargetString = '.ui-lightbox-container div#dvCompareLimitWarning';
						
						var hdnCompareCount = $('input#hdnCompareCount');
						var spnCompareCount = $('span.user-toolbar-compare-count');
						var compareCountInt = parseInt(hdnCompareCount.val());

						//if we have hit our compare limit then display the modal dialog to warn the user
						if (compareCountInt > 2) {

							//get the params needed to hack this into the lightbox
							var rawParams = '#?go=go&width=400&height=160&target=divUvlContainer&source=dvCompareLimitWarning&displayPosition=viewableCentre';
							var parameters = uiBox_GetQueryString(rawParams);

							//show the lightbox
							uiBox_Show(parameters, rawParams);
							
							//now bind the cancel and continue buttons
							var dialogContainer = $(containerTargetString);
							
							var continueButton	= dialogContainer.find("div.button-continue");
							var cancelButton	= dialogContainer.find("div.button-cancel");
							
							
							_this._linkReference = link;
							
							
							// Attanch standard click functionality to links
							
							continueButton.click(
								function (e)
								{
									_this._handleDialogueButtonClick(true);
								}
							);
							
							cancelButton.click(
								function (e)
								{
									uiBox_Hide();
								}
							);
							
							
							// If ie then add href attribute to each buttons internal <a> tag
//							if ($.browser.msie)
//							{
//								var continueLink	= continueButton.find("a");
//								var cancelLink		= cancelButton.find("a");
//								
//								continueLink.attr("href", "javascript:" + _this.instanceString + "._handleDialogueButtonClick(true);");
//								cancelLink.attr("href", "javascript:" + _this.instanceString + "._handleDialogueButtonClick(false);");
//							}
//							
//							
//							// Style buttons
//							sIFR.runDelayedButtonStyling(containerTargetString + " " + "div.button-style-1" + " " + sIFR_settings.DEFAULT_BUTTON_STYLE_TARGET_STRING_INTERNAL_PATH);
							
						}
						else 
						{
							_this._sendCompareRequest(link);
							//hdnCompareCount.val(compareCountInt + 1);
							//spnCompareCount.html(compareCountInt + 1);
							//spnCompareCount.parent().css({'display':'block'});
						}
					});
				}
			},
			
			
			_linkReference : undefined,
			
			
			_handleDialogueButtonClick : function (sendRequest)
			{
				if (sendRequest)
				{
					this._sendCompareRequest(this._linkReference);
				}
				uiBox_Hide();
			},
			
			
			
			//function used to send the compare request
			_sendCompareRequest : function (link) {
				var _this = this;
				var id = link.attr('id');

				//now display the loading state
				var loading = eval(id + '.loading');

				//get the href to use for the ajax call
				var href = link.attr('href');

				//display the loading state and then
				var loadingElement = $(loading);

				//$(this).after(loadingElement).remove();
				link.replaceWith(loadingElement);

				//make the ajax call
				$.ajaxManager.updateUrl(href);
				$.ajaxManager.onSuccess = function (p_response) {
					_this._processCompareAjaxRequest(p_response, id, loadingElement);
				};
				$.ajaxManager.makeRequest();
			},
			
			
			//function used to process the results from the ajax requests
			_processCompareAjaxRequest : function (response, id, loadingElement) {
				var _this = this;
				
				// get link condition data
				var linkConditionsData	= eval(id);
				
				// get the next link condition result
				var result = $(eval(id + "." + response.status));
				
				// get the core id of the link conditions
				var coreId = linkConditionsData.arguments[this.REQUEST_ARGUMENT_CORE_ID];
				
				// if we have a removal argument they we update any link conditions to the new state
				if (response.arguments[this.RESPONSE_ARGUMENT_RETURN_CORE_ID])
				{
					this._processAnyMatchingLinkConditions('.' + response.arguments[this.RESPONSE_ARGUMENT_RETURN_CORE_ID] + ' a.a-icon-compare', "off", _this._bindCompareConditionalLink);
				}
				
				// update any link conditions to the new state (this covers any other link conditions that are not the current)
				this._processAnyMatchingLinkConditions('.' + coreId + ' a.a-icon-compare', response.status, _this._bindCompareConditionalLink);
				
				// swap out the current link condition state
				loadingElement.replaceWith(result);
				
				// rebind the result control
				this._reBindControl(result);
				
				// process any additional controls
				var responseResult = eval(response);
				this._processResultControls(responseResult);

				// set hidden compare counter
				if (responseResult.arguments && responseResult.arguments["count"])
				{
					$('input#hdnCompareCount').val(responseResult.arguments["count"]);
				}

				//if the result element is a callback element then drop its click handler
				if (!result.attr('href').indexOf('.ashx') == -1) {
					result.unbind('click');
				}
				else {
					_this._bindCompareConditionalLink(result);
				}
			},
			
			//function used to process the results from the ajax requests
			_processAjaxRequest : function (response, id, loadingElement, counterSelector) {
				var _this = this;
				
				// get link condition data
				var linkConditionsData	= eval(id);
				
				// get the next link condition result
				var result = $(eval(id + "." + response.status));
				
				// get the core id of the link conditions
				var coreId = linkConditionsData.arguments[this.REQUEST_ARGUMENT_CORE_ID];

				// update any link conditions to the new state (this covers any other link conditions that are not the current)
				this._processAnyMatchingLinkConditions('.' + coreId + ' a.a-icon-favourites, .' + coreId + ' a.a-icon-favourites-icon-only', response.status, _this._bindNonCompareConditionalLink);
				
				//loadingElement.after(result).remove();
				loadingElement.replaceWith(result);
				
				// rebind the result control
				this._reBindControl(result);
				
				// process any additional controls
				var responseResult = eval(response);
				this._processResultControls(responseResult);
				
				// set hidden counter if nessary
				if (counterSelector && responseResult.arguments && responseResult.arguments["count"])
				{
					$(counterSelector).val(responseResult.arguments["count"]);
				}
				
				//if the result element is a callback element then drop its click handler
				if (!result.attr('href').indexOf('.ashx') == -1) {
					result.unbind('click');
				}
				else {
					_this._bindNonCompareConditionalLink(result);
				}
			},
			
			/* Ensure that any other ajax link conditions on the page have their state updated */
			_processAnyMatchingLinkConditions : function (selector, state, binder)
			{
				var _this = this;
				var conditionalLinks = $(document).find(selector).filter("a[href]");
				
				conditionalLinks.each(function ()
				{
					//for each time the link has been found we need to amend the state globally of its
					var ___this = $(this);
					
					var replacementId = ___this.attr('id');
					var replacementElement = $(eval(replacementId + '.' + state));
					___this.replaceWith(replacementElement);
					
					_this._reBindControl(replacementElement);
					
					replacementElement.unbind('click');
					binder(replacementElement, _this);
				});	
			},
			
			// function used to loop through a result object's controls and process them to the page if nessary
			/* Normal Result controls Response
			{
				controls :
					[
						{
							controlName		: "",
							targetDomId		: "",
							content			: "",
							placementType	: ""
						},
					]
			}
			*/
			
			// add re-bind controls when inserted
			/* TODO:
					Need to add in config what control replacements should run what reinit's, add the reinit processors to an array
					and then pick out the reinit's and run them over the jqContainer that we are inserting.
					
					This needs moving into a CallBackUtilityFunction as the callbacks are now a standard format
			*/
			_reBindControl : function (jqContainer)
			{
				if (window.fix_PNGs)
				{
					if (jqContainer.find(".png").length > 0)
					{
						fix_PNGs(jqContainer);
					}
					else
					{
						fix_PNG(jqContainer);
					}
				}
				
				if (window.manheim_portfolio_tooltip)
				{
					manheim_portfolio_tooltip.BindToolTips(jqContainer);
				}
			},
			
			// TODO this needs moving into a CallBackUtilityFunction as the callbacks are now a standard format
			_findDataControl : function (result, controlName)
			{
				if (result == null || result.controls == null)
				{
					return null;
				}
				
				for (var i = 0; i < result.controls.length; i++)
				{
					if (result.controls[i].controlName == controlName)
					{
						return result.controls[i];
					}
				}
				
				return null;
			},
			
			// TODO this needs moving into a CallBackUtilityFunction as the callbacks are now a standard format
			/* Normal Content Response
			{
				controls :
					[
						{
							controlName		: "",
							targetDomId		: "",
							content			: "",
							placementType	: ""
						},
					]
			}
			*/
			_processResultControls : function (result, rebindControls)
			{
				this._debugMessage("Started: Processing ajax control results");
				
				rebindControls = (rebindControls != undefined) ? rebindControls : true;
				
				if (result == null || result.controls == null)
				{
					return;
				}
				
				for (var i = 0; i < result.controls.length; i++)
				{
					this._debugMessage("Start: Get next control reference.");
					var controlReference = result.controls[i];
					this._debugMessage("End: Get next control reference.");
					
					this._debugMessage("Start: Use JQuery to find DOM element to replace (" + "#" + result.controls[i].targetDomId + ").");
					var target = $("#" + result.controls[i].targetDomId); // TODO we should change to a normal selector not id based that way we can
					this._debugMessage("End: Use JQuery to find DOM element to replace (" + "#" + result.controls[i].targetDomId + ").");
					
					if (target.length > 0)
					{
						//var content = UnEncodeResponse(result.controls[i].content); // don't need to encode any more as the server formats json correctly now
						//var content = $(result.controls[i].content);
						
						this._debugMessage("Processing " + controlReference.controlName + " control using '" + controlReference.placementType + "' rendering method.");
						
						if (controlReference.placementType == "Replace")
						{
							target.replaceWith(result.controls[i].content);
							this._debugMessage("Replaced content for " + controlReference.controlName + " control.");
						}
						else if (controlReference.placementType == "InsertAdd")
						{
							target.append(result.controls[i].content);
							this._debugMessage("Appended content for " + controlReference.controlName + " control.");
						}
						else
						{
							// InsertReplace
							target.html(result.controls[i].content);
							this._debugMessage("Replaced inner html for " + controlReference.controlName + " control.");
						}
						
						// run reinit control
						if (rebindControls)
						{
							this._reBindControl($("#" + result.controls[i].targetDomId));
						}
						
						this._debugMessage("Finished re bind for " + controlReference.controlName + " control.");
					}
				}
				
				this._debugMessage("Finished: Processing ajax control results");
			},
			
			_debugMessage : function (message)
		     {
				if (this.DEBUG)
				{
					alert(message);
				}
		     }
		}
	);
