/**
 * Title: CPLAT
 * Copyright: Copyright (c) 2008
 * Company: BBC Worldwide Ltd
 * Description:	AjaxOverLayScreenManager to manage display of screen on popup overlay window
 * @author: NgAW1
 * @version: $Revision: $
 * @date: 10 June 2008 16:51:45
 */
 

/**
 * This define the AjaxOverLayScreenManager Class, which is a singleton object
 * providing Ajax OverLay Screen Management functionalities
 * @param base {@link BBCWORLDWIDE_CPLAT.BaseObject}
 * @return this {@link BBCWORLDWIDE_CPLAT.AjaxOverLayScreenManager}
 */
BBCWORLDWIDE_CPLAT.AjaxOverLayScreenManager = function(base) {
	var arrayScreens = new Array(); // Array of Screens definitions
	var overLayHeight  = 350; // Overlay height, default 350  - can be supplied by hook in clientConfigParams using userDefinedOverLayDimension.height
	var overLayWidth   = 600; // Overlay width, default 600 - can be supplied by hook in clientConfigParams using userDefinedOverLayDimension.width
	var currentScreen = 0; // current screen definition being displayed
	var passionSiteCallBackFunc; // call back function supplied by passion Site 
	var passionSiteErrorCallBackFunc; // error call back function supplied by passion site
	var passionSiteOverlayCloseCallBackFunc; // call bacj function when overlay is close
	var imgLoader = new Image();

	// Getter for passionSiteCallBackFunc
	base.getPassionSiteCallBackFunc = function() {
		return passionSiteCallBackFunc;
	};
    
	/**
	 * This method setup the onclick handler for opening the overlay screen to load xhtml fragment via AJAX call
	 * @param: p_oClickedLink {@link archor tag}
	 */ 
	
	base.handleLinkClick  = function(p_oClickedLink) {
		 
		// Don't show in overlay if screen is too small
		if (isScreenTooSmallForOverlay()) {
			window.location = $(p_oClickedLink).attr("href");
			return;
		}
		
		// If user hasn't defined screen flows then we just use href and title from the clicked links
		// note: now all interaction goes through client aplpication, unlikely we need to use screen flows
		// so most likely the href and title will be used to define the screen that will be rendered in overlay
		if (base.getClientConfigParams().userDefinedScreensFlow != null) {
			 arrayScreens = base.getClientConfigParams().userDefinedScreensFlow;
		} else {
			arrayScreens[0] = {
				retrieveURL:$(p_oClickedLink).attr("href"),
				screenTitle:$(p_oClickedLink).attr("title")
			};
		}
		
		// If user defined screen height and width then use it, otherwise use default
		if (base.getClientConfigParams().userDefinedOverLayDimension != null) {
			overLayHeight  = base.getClientConfigParams().userDefinedOverLayDimension.height;
			overLayWidth   = base.getClientConfigParams().userDefinedOverLayDimension.width;
		} 
		
		// Passion site callback
		if ((base.getClientConfigParams() != null) && (base.getClientConfigParams().passionSiteCallBack !=null)) {
			passionSiteCallBackFunc             = base.getClientConfigParams().passionSiteCallBack.successCallBack;
			passionSiteErrorCallBackFunc        = base.getClientConfigParams().passionSiteCallBack.errorCallBack;
			passionSiteOverlayCloseCallBackFunc = base.getClientConfigParams().passionSiteCallBack.overlayCloseCallBack;
		}
		currentScreen = 0;

		// we should have at least 1
		if(arrayScreens.length > 0) {
			for(i=0; i<arrayScreens.length; i++) {
				if(arrayScreens[i].applicationSuccessCallBackFunc === undefined) {
					arrayScreens[i].applicationSuccessCallBackFunc = function() {};
				}
			}
			showScreen(getCurrentScreen());
		}
	};
	
	/**
 	 * This method is call when successfully retrieved an xhtml fragment via AJAX call
 	 * @param: overLayWindow {@link  dom}
 	 * @param: fCloseOverlayFunc {@link  Function}
 	 */
	base.overLayWindowAjaxSuccessHook = function (overLayWindow, fCloseOverlayFunc) {
		// Add an onclick handler when a submit button is clicked
		overLayWindow.find("input[type='submit']").click(function() {
			if(!$(this.form).valid()) {
				return;
			}
		
			if(typeof(base.cplatPreProcessHandler) === "function") {
				base.cplatPreProcessHandler(fCloseOverlayFunc);
			}
			$.ajax({
				url: $(this.form).attr("action"),
				type: $(this.form).attr("method"),
				data: BBCWORLDWIDE_CPLAT.createRequestParameters(this.form),
				// If success then either retrieve next screen or call passionSiteCallBackFunction
				success: function(xhtml){
					jQuery.unblockUI();
					// If it is just xhtml fragment then display it
					if( (typeof(xhtml) === 'string') && (xhtml.length > 0)  )  {
						injectXHTMLFragment(xhtml);
					} else {
						currentScreen++;
						if(arrayScreens.length > currentScreen) {
							// if another screen is defined in hook code then get the screen then show it
							var url = getCurrentScreen().retrieveURL;
							showScreen(getCurrentScreen());
						} else {
							// otherwise if a postProcessHandler has been defined then call it
							if(typeof(base.cplatSuccessfulPostProcessHandler) === "function") {
								base.cplatSuccessfulPostProcessHandler(fCloseOverlayFunc);
							} 
							currentScreen = 0;
							if(typeof(passionSiteCallBackFunc) === "function") {
								// if a final callback function has been defined then call it
								passionSiteCallBackFunc.call(overLayWindow);
							}
						}
					}
				},
				error: function(XMLHttpRequest, textStatus, errorThrown) {
					jQuery.unblockUI();
					// If it is just xhtml fragment then display it
					if( (typeof(xhtml) === 'string') && (xhtml.length > 0)  )  {
						injectXHTMLFragment(xhtml);
					} else {
						if(typeof(passionSiteErrorCallBackFunc) === "function") {
							passionSiteErrorCallBackFunc.call(overLayWindow);
						}
					}
				}
			});
			
			return false;
		});
	};
	
	// Override this method if you want to do something different than default
	// this default impl shows a dodgy rotating gif..
	base.cplatPreProcessHandler = function (fCloseOverlayFunc) {
		if($("#cplatPreProcessMessage").get(0) !== undefined) {
			var cplatPreProcessMessage = $("#cplatPreProcessMessage");
			jQuery.blockUI({ message: cplatPreProcessMessage});
		} else {
			jQuery.blockUI({ message: "<img src='"+imgLoader.src+"' />"});
		}
	};
	
	// Override this method if you want to do something different than default
	base.cplatSuccessfulPostProcessHandler = function (fCloseOverlayFunc) {
		if($("#cplatSuccessfulPostProcessMessage").get(0) !== undefined) {
			jQuery.blockUI({ message: $("#cplatSuccessfulPostProcessMessage")});
			$('.cplatSuccessOK').click(function() { 
				jQuery.unblockUI(); 
				return false;
			}); 
		}
		fCloseOverlayFunc.call();
	};
	
	// Override this method if you want to do something different than default
	base.cplatExceptionProcessHandler = function (fCloseOverlayFunc) {
		if($("#cplatExceptionProcessMessage").get(0) !== undefined) {
			jQuery.blockUI({ message: $("#cplatExceptionProcessMessage")});
			$('#ok').click(function() { 
				jQuery.unblockUI(); 
				return false;
			}); 
		}
		fCloseOverlayFunc.call();
	};
	
	// Shows the next screen
	base.showNextScreen =  function () {
		var screen = getNextScreen();
		if (screen!==null){
			showScreen(screen);
		}
	};

	// Returns current Screen
	var getCurrentScreen = function() {
		if(arrayScreens.length > 0) {
			return arrayScreens[currentScreen];
		}
	};

	// Returns next Screen
	var getNextScreen = function() {
		if(arrayScreens.length >= currentScreen+1 ) {
			return arrayScreens[currentScreen+1];
		}
		return null;
	};
    

	/**
	 * This method do the main work of creating/displaying the overlay, make AJAX call, inject xhtml into DOM and 
	 * make calls to the call back function
	 * @param: caption {@link  String}
	 * @param: url {@link  String}
	 */
	var showScreen = function(screen) {
		try {
			var caption = screen.screenTitle;
			var url = screen.retrieveURL;
			var applicationSuccessCallBackFunc = screen.applicationSuccessCallBackFunc;

			// Create the Div that display the OverLay
			if (typeof document.body.style.maxHeight === "undefined") {//if IE 6
				$("body","html").css({height: "100%", width: "100%"});
				$("html").css("overflow","hidden");

				//iframe to hide select elements in ie6
				if (document.getElementById("cplat-HideSelect") === null) {
					$("body").append("<iframe id='cplat-HideSelect'></iframe><div id='cplat-overlay'></div><div id='cplat-window'></div>");
					$("#cplat-overlay").click(removeScreen);
				}
			} else {
				if (document.getElementById("cplat-overlay") === null){
					$("body").append("<div id='cplat-overlay'></div><div id='cplat-window'></div>");
					$("#cplat-overlay").click(removeScreen);
				}
			}
			
			// Set OverLay Background		
			if (BBCWORLDWIDE_CPLAT.detectMacXFF()){
				$("#cplat-overlay").addClass("cplat-overlayMacFFBGHack"); //use png overlay so hide flash
			} else {
				$("#cplat-overlay").addClass("cplat-overlayBG");	//use background and opacity
			}
					
			if (caption===null) {
				caption="";
			}


			// Display an image during load		
			if( base.getClientConfigParams().overlayImgLoader != null) {
				imgLoader.src = base.getClientConfigParams().overlayImgLoader;
			}
			$("body").append("<div id='cplat-load'><img src='"+imgLoader.src+"' /></div>");
			$('#cplat-load').show();
			
			// Set Width and Height of OverLay Window
			CPLAT_WIDTH  = (overLayWidth*1) || 630;
			CPLAT_HEIGHT = ( overLayHeight*1) || 440; 			
			
			// Load OverLay with data returns from AJAX Calls
			if ($("#cplat-window").css("display") != "block") {
				$("#cplat-overlay").unbind();
				$("#cplat-window").append("<div id='cplat-title'><div id='cplat-ajaxWindowTitle'>"+caption+"</div><div id='cplat-closeAjaxWindow'><a href='#' id='cplat-closeWindowButton'>close</a></div></div><div id='cplat-ajaxContent' class='cplat-modal'></div>");
			} else {//this means the window is already up, we are just loading new content via ajax
					$("#cplat-ajaxContent")[0].scrollTop = 0;
					$("#cplat-ajaxWindowTitle").html(caption);
			}

			// Add Handler to Close Button to remove Screen
			$("#cplat-closeWindowButton").click(removeScreen);

			base.ajaxGet(url, "GET", "ajaxRequest=true", injectXHTMLFragment, passionSiteErrorCallBackFunc, applicationSuccessCallBackFunc, null);
			
		} catch(e) {
			console.log(e);
		}
	};
	
	// Private Method to inject content
	var injectXHTMLFragment = function (xhtml) {
		var oTBAjaxContent = $("#cplat-ajaxContent");
		var oTBLoad = $("#cplat-load");
		var oTBWindow = $("#cplat-window");
		oTBAjaxContent.children().remove();
		oTBAjaxContent.append(xhtml);
		$("#cplat-window").css({marginLeft: '-' + parseInt((CPLAT_WIDTH / 2),10) + 'px', width: CPLAT_WIDTH + 'px', height: CPLAT_HEIGHT + 'px'});
		if ( !(jQuery.browser.msie && jQuery.browser.version < 7)) { // take away IE6
			$("#cplat-window").css({marginTop: '-' + parseInt((CPLAT_HEIGHT / 2),10) + 'px'});
		}
		
		oTBLoad.remove();
		oTBWindow.css({display:"block"});
		
		if(typeof(base.overLayWindowAjaxSuccessHook) === 'function') {
			base.overLayWindowAjaxSuccessHook(oTBWindow, removeScreen);
		}
	};
	
	/**
	 * closes the overlay
	 * 
	 * exposes the functionality to the interface
	 */
	base.closeOverlay = function() {
		removeScreen();
	};
	
	// Private Method to remove
	var removeScreen = function () {
		$("#cplat-imageOff").unbind("click");
		$("#cplat-closeWindowButton").unbind("click");
		$("#cplat-window").fadeOut("fast",function(){$('#cplat-window,#cplat-overlay,#cplat-HideSelect').trigger("unload").unbind().remove();});
		$("#cplat-load").remove();
		if (typeof document.body.style.maxHeight == "undefined") {//if IE 6
			$("body","html").css({height: "auto", width: "auto"});
			$("html").css("overflow","");
		}
		document.onkeydown = "";
		document.onkeyup = "";
		
		if (typeof(passionSiteOverlayCloseCallBackFunc) === 'function') {
			passionSiteOverlayCloseCallBackFunc.call();
		}
		
		// Set currentScreen to 0
		currentScreen = 0;
		
		return false;
	};
	
	// Determine whether the window is too small to show in an overlay
	// if window is too small for an overlay then the normal page is displayed (non-overlay)
	var isScreenTooSmallForOverlay = function () {
		var dimensionAllowance = 100;
		var dimension = BBCWORLDWIDE_CPLAT.getWindowDimension();
		return (( dimension.width < (overLayWidth + dimensionAllowance)) || (dimension.height < (overLayHeight + dimensionAllowance)));
	};
	
	return base;
}(BBCWORLDWIDE_CPLAT.BaseObject);
