/*
 * All java script logic for the application.
 *
 * The code relies on the jQuery JS library to
 * be also loaded.
 */

var app = (function(jQuery){
	// Global dw private data goes here
	// TODO: hard coded strings

	return { // dw scope public
		LogRequestID	: null,
		URLs			: {},
		resources		: null,
		containerId		: "content",
		ProductCache	: null,
		Templates		: {}, // cache to hold html templates
		currentCursor	: null, // holds the current product position within the product nav on product detail page
		productCount	: null, // represents the max number of products in a search resultset
		currentPageObj	: null, // holds the currently displayed objects associated with next/prev
		clearDivHtml	: "<div class=\"clear\"><!-- W3C Clearing --></div>",
		dialogSettings	: { // default dialog box settings
				autoOpen: false,
				buttons: {
				},
				modal: true,
				overlay: {
		    		opacity: 0.5,
		     		background: "black"
				},
		    	height: 530,
		    	width: 800,
		    	title: '',
		    	show: "slow",
		    	hide: "normal",
		    	resizable: false
		},

		// default tooltip settings
		tooltipSettings: {
				delay: 0,
				showURL: false,
				extraClass: "pretty fancy",
				top: 15,
				left: 5
		},
		// form validator global settings
		validatorSettings: {
			errorClass : 'error_message',
			// rules are defined as name value pairs
			// name must be element's name
			// for equalTo the value must be the id of the element!
			// TODO think about a better way to define rules so that we can avoid
			// dependency on the server side form definition, see the names below!
			rules: {
			   // dwfrm_profile_login_passwordconfirm: {
			   // 	equalTo: "#Id_dwfrm_profile_login_password"
			   // },
			    dwfrm_profile_customer_emailconfirm: {
			    	equalTo: "#Id_dwfrm_profile_customer_email"
			    },
			    dwfrm_sendtofriend_confirmfriendsemail: {
			    	equalTo: "#Id_dwfrm_sendtofriend_friendsemail"
			    },
			    dwfrm_giftcert_confirmRecipientEmail: {
			    	equalTo: "#Id_dwfrm_giftcert_recipientEmail"
			    },
			    dwfrm_svsgiftcards_purchasevcard_confirmemail: {
			    	equalTo: "#Id_dwfrm_svsgiftcards_purchasevcard_email"
			    }
			},		    
		    onfocusout: function(element) {
				if ( !this.checkable(element) ) {
					this.element(element);
				}
			}
		},
		
		// app initializations called from jQuery(document).ready at the end of the file
		init: function() {
			/*
			 * Register initializations here
			 */
		
			jQuery("<div/>").attr("id", "msgDiv").html(" ").appendTo(document.body);
			jQuery("#msgDiv").ajaxError(app.ajax.printAjaxError);
			
			jQuery("<div/>").attr("id", "QuickViewDialog").html(" ").appendTo(document.body);
			
			// TODO this is obsolete, since container is load lazily now
			jQuery(document.body).append("<div id=\"dialogcontainer\"></div>");
		
			// initialize form validator customizations
			// TODO this should be loaded lazily upon request by using logic in order to prevent 
			// loading overhead in pages where we dont need client side validation
			app.validator();
			// extract hidden data and turn them into jQuery data objects
			app.hiddenData();
		},
		
		// sub namespace app.ajax.* contains application specific ajax components
		ajax : {
			Success: "success",
			currentRequests: {}, // request cache

			getJson: function(options) {
				var thisAjax = this;
				// do not bother if the request is already in progress
				// and let go null reqname
				if (!options.reqName || !this.currentRequests[options.reqName]) {
					this.currentRequests[options.reqName] = true;
					// make the server call
					jQuery.ajax({
						//type	: "get",
						contentType: "application/json; charset=utf-8",
						dataType: "json",
						url		: options.url,
						cache	: false,
						data	: options.data,
						success	: function(response, textStatus) {
							thisAjax.currentRequests[options.reqName] = false;

							// get the request ID for log
							app.LogRequestID = response.LogRequestID;

							// handle failure
							if (!response.Success) {
								// TODO show error? or do something else
								app.ajax.printAjaxError({}, {}, {url: options.url});
							}

							options.callback(response, textStatus);
						},

						error	: function(request, textStatus, error) {
							if (textStatus === "parsererror") {
								// TODO show error? or do something else
								alert('bad response, parser error='+request+", options.url="+options.url);
							}
							// get the request ID for log
							//app.LogRequestID = response.LogRequestID;

							// TODO, maybe we should show a generic global error message

							options.callback({Success: false, data:{}});
						},

						complete: function(XMLHttpRequest, textStatus){
					  	}
					});
				}
			},

			load: function(options) {

				//jQuery(options.selector).load(options.url, options.data, options.callback);

				var thisAjax = this;
				// do not bother if the request is already in progress
				// and let go null reqname
				if (!options.reqName || !this.currentRequests[options.reqName]) {
					this.currentRequests[options.reqName] = true;
					// make the server call
					jQuery.ajax({
						//type	: "POST",
						dataType: "html",
						url		: options.url,
						cache	: false,
						data	: options.data,
						success	: function(response, textStatus) {
							thisAjax.currentRequests[options.reqName] = false;

							// get the request ID for log

							// handle failure
							/*if (!response.Success) {
								// TODO show error? or do something else
								app.ajax.printAjaxError({}, {}, {url: url});
							}*/
							if (options.selector) {
								jQuery(options.selector).html(response);
							}
							(options.callback != undefined ? options.callback(response, textStatus): null)
						},

						error	: function(request, textStatus, error) {
							if (textStatus === "parsererror") {
								// TODO show error? or do something else
								alert('bad response, parser error');
							}
							// get the request ID for log
							//app.LogRequestID = response.LogRequestID;

							// TODO, maybe we should show a generic global error message

							options.callback(null, textStatus);
						},

						complete: function(XMLHttpRequest, textStatus){
					  	}
					});
				}
			},
			
			printAjaxError : function(event, request, settings) {
				if (jQuery("#msgDiv") == null) {
					jQuery("<div/>").attr("id", "msgDiv").appendTo(document.body);
				}
				jQuery("#msgDiv").append("<li>Error requesting page " + settings.url + "</li>")
				.append("<a href='javascript:app.openDWLog();'> Open Log </a>");
		 	}
		},

		getProduct: function(options) { // id, source, start
			var cId 		= options.containerId || app.containerId;

			jQuery("#"+cId).html(app.wait(2));

			options.start = options.start || -1;
			app.ajax.load({selector: "#"+cId, url: (options.url ? options.url : app.URLs.getProductUrl+"?pid="+options.id)+"&source="+options.source+"&start="+(options.start - 0)+"&searchUrl="+app.URLs.ContinueShop, callback: function(responseText, textStatus){

				if (textStatus == app.ajax.Success) {
				}
			}});
		},

		// sub name space app.minicart.* provides functionality around the mini cart
		minicart : {
			// flag, whether cart is open or not
			state: 0,

			// during page loading, the Demandware URL is stored here
			url: '',

			// timer for automatic close of cart item view
			timer: null,
			
			// initializations
			init: function() {
				app.minicart.reset(); // reset all the existing event bindings
				
				jQuery('#minicartcontent').bind("mouseenter", function() {
					clearTimeout(app.minicart.timer)
					app.minicart.timer = null;
				});
				
				jQuery('#minicartcontent').bind("mouseleave", function() {
					// after a time out automatically close it
					app.minicart.timer = setTimeout( 'app.minicart.close()', 30 );
				});
				
				// register close button event
				jQuery('#minicartcontent #minicartclose, #minicart-layer .mini-close').bind("click", function() {
					// reset all the events bindings
					app.minicart.reset();
					app.minicart.close(0);
				});
			},
			// reset minicart
			reset: function() {
				jQuery('#minicartcontent').unbind("mouseenter");
				jQuery('#minicartcontent').unbind("mouseleave");
				jQuery('#minicartcontent #minicartclose').unbind("click");
			},
			
			// shows the given content in the mini cart 
			show: function( html )
			{
				jQuery('#minicart-summary').html(html);

				if( app.minicart.suppressSlideDown && app.minicart.suppressSlideDown() )
				{
					// do nothing
					// the hook 'MiniCart.suppressSlideDown()' should have done the refresh
				}
				else
				{
					// show the item
					jQuery('#minicartcontent').show("slide", { direction: "up" }, 1000);

					// after a time out automatically close it
					app.minicart.timer = setTimeout( 'app.minicart.close()', 6000 );
				}
			},

			// adds a product to the mini cart
			add: function( form, progressImageSrc, postdata, callback )
			{
				
				var previousImageSrc;
				// get the data of the form as serialized string
				var postdata = postdata || jQuery(form).serialize();
				//alert(postdata);
				// get button reference
				var addButtons = []; //Form.getInputs(form, 'image', 'add');

				// the button to update
				var addButton = jQuery("button", form);

				// disable form
				//Form.disable(form);

				// it is an array of buttons, but we need only one all
				// other combinations are strange so far
				if (addButtons.length == 1)
				{
					addButton = addButtons[0];
				}

				var previousImageSrc = null;

				// show progress indicator
				if (addButton != null)
				{
					previousImageSrc = addButton.css('background-image');
					addButton.css('background-image', 'url('+progressImageSrc+')');
				}

				var handlerFunc = function(req)
				{
					// hide progress indicator
					if (addButton != null)
					{
						addButton.css('background-image', previousImageSrc);
					}
					//Form.enable(form);

					// replace the content
					jQuery('#minicart-summary').parent().parent().html(req);
					
					// bind all the events
					app.minicart.init();

					if( app.minicart.suppressSlideDown && app.minicart.suppressSlideDown() )
					{
						// do nothing
						// the hook 'MiniCart.suppressSlideDown()' should have done the refresh
					}
					else
					{
						//hide quickshop after adding items (demanded in bug 1372)
						$('.quick-shop-dialog').css('display','none');
						// show the item						
						$('#minicart-layer').show();
						// jQuery('#minicart-layer').show("slide", { direction: "up" }, 1000);

						// after a time out automatically close it
						app.minicart.timer = setTimeout( 'app.minicart.close()', 6000 );

						if (callback) callback();
					}
					
					initMiniCartMouseOvers(true);
					
					if($('body').attr('className').indexOf('cart') > -1)
					{
						window.location.href = window.location.href;
					}
				}

				var errFunc = function(req)
				{
					// hide progress indicator
					if (addButton != null)
					{
						addButton.css('background-image', previousImageSrc);
					}
					// Form.enable(form);
				}

				// close a product QuickView
				// if ( QuickView ) QuickView.closeQuickView();

				// cloes a previous mini cart
				app.minicart.close();

				// add the product
				jQuery.ajax({
								type	: "POST",
								//dataType: "json",
								url		: app.minicart.url,
								cache	: false,
								data	: postdata,
								success	: handlerFunc,
								error	: errFunc
							});
			},

			// closes the mini cart
			close: function(delay)
			{
				if ( app.minicart.timer != null || delay == 0)
				{
					clearTimeout( app.minicart.timer );
					app.minicart.timer = null;
					$('#minicart-layer').hide();				
					// jQuery('#minicart-layer').hide("slide", { direction: "up" }, delay || 1000);
				}
			},

			// hook which can be replaced by individual pages/page types (e.g. cart)
			suppressSlideDown: function()
			{
				return false;
			}
		},

		refreshCart: function() {
			jQuery('#QuickViewDialog').dialog('close');

			// refresh without posting
			location.href = location.href;
		},
		
		quickView: {
			bindEvents: function(options) {
				// hide quickview buttons
				jQuery(options.buttonSelector).hide();
				
				// hovering
				jQuery(options.imageSelector).hover(
					function(e) {
						jQuery(this).children(options.buttonSelector).show();
						return false;
					},
					function(e) {
						jQuery(this).children(options.buttonSelector).hide();
						return false;
					}
				);
				
				// clicking
				jQuery(options.buttonLinkSelector).click(function(e) {
					app.quickView.show({url: this.href, source: "quickview"});
					return false;
				});
				
				// product name link click binding
				jQuery(options.productNameLinkSelector).click(function(e) {
					app.currentCursor = parseInt(this.href.substring(this.href.lastIndexOf('=')+1)) - 0;
					app.getProduct({id: app.util.trimPrefix(this.id, "pdp-"), start: app.currentCursor, source: "search"});
					return false;
				});
			},
		
			show: function(options) {
				//QuickViewDialog
				app.createDialog({id: 'QuickViewDialog', options: {
			    	height: 530,
			    	width: 800,
			    	dialogClass: 'quickview',
			    	title: 'Product Quickview',
			    	resizable: false
				}});
	
			    jQuery('#QuickViewDialog').dialog('open');
			    app.getProduct({containerId: "QuickViewDialog", source: options.source, url: options.url});
			}
		},

		// TODO this needed to be renamed from "dialog" to "createDialog", since it conflicts 
		// with the name space app.dialog.*; can we merge this into the new namespace somehow?
		createDialog: function(options) {
			jQuery('#'+options.id).dialog(jQuery.extend({}, app.dialogSettings, options.options));
		},

		tooltip: function(options) {
			if (options.id.charAt(0) !== '#') {
				options.id = "#"+options.id;
			}
			jQuery(options.id).tooltip(jQuery.extend({}, app.tooltipSettings, options.options));
		},

		wait: function (size) {
			var imgSrc = app.URLs.loadingImg;
			if (size == 1) { // large image
			}
			else if (size == 2){ // small loading image
				imgSrc = app.URLs.loadingSamllImg;
			}

			return jQuery("<img/>").attr("src", imgSrc);
		},

		/*
			Opens a new window with the provided url and dimension. Used
			for Scene7 and other situations.

			@param url the url to open
			@param width the window width
			@param height the window height
		*/
		openPopup: function( url, width, height ) {
			if (url != null)
			{
				if (width != null && height != null)
				{
					window.open(url, "", "width=" + width +", height=" + height +", scrollbars=no, resizable=yes");
				}
				else
				{
					window.open(url, "", "scrollbars=no, resizable=yes");
				}
			}
		},

		validator: function() {
			// override default required field message
			jQuery.validator.messages.required = function($1, ele, $3) {
				return 'Please Enter '+jQuery(ele).data("data");
			};
			
			// register form validator for form elements
			// TODO may be we should do on specific forms?
			jQuery.each(jQuery("form"), function() {
				jQuery(this).validate(app.validatorSettings);
			});
		},
		// grab anything inside a hidden span and append it to its immediate prev sibling
		hiddenData : function() {
			jQuery.each(jQuery(".hidden"), function() {
				jQuery(this).prev().data("data", jQuery(this).html());
			});
		},

		openDWLog: function(){

			// generate the URL to load the log data
			var url = document.URL;
			var urlSegs = url.split( "/" );

			// check, if the demandware URL is complete
			if (urlSegs.length >= 6)
			{
				siteSegs = urlSegs[5].split( "-" );

				// check, if a valid site name is given
				if ((siteSegs.length > 0) && (siteSegs[0].length > 0))
				{
					var logURL = "https://" + urlSegs[2] + "/" + urlSegs[3] + "/" + urlSegs[4]
					+ "/" + siteSegs[0] + "-Site/-/ViewRequestLog-Start?LogRequestID=" + app.LogRequestID;

					// open the window
					var logWindow = window.open( logURL, "DemandwareLogView",
					"height=600,width=800,scrollbars=1,resizable=1,status=1" );
					logWindow.focus();

					// clear the interval for delayed execution
					window.clearInterval( openDelayID );
				}
			}
		},

		// sub namespace app.util.* contains utility functions
		util : {
			// turns off browser autocompletion
			acOff : function(elemId) {
				jQuery("#"+elemId).attr("autocomplete", "off");
			},
			
			// trims a prefix from a given string, this can be used to trim
			// a certain prefix from DOM element IDs for further processing on the ID
			trimPrefix : function(str, prefix) {
				return str.substring(prefix.length)
			},
			
			// appends the parameter with the given name and 
			// value to the given url and returns the changed url
			appendParamToURL : function(url, name, value) {
				var c = "?";
				if(url.indexOf(c) != -1) {
					c = "&";
				}
				return url + c + name + "=" + encodeURIComponent(value);
			}
		},
		
		// sub namespace app.dialog.* provides convenient functions to handle dialogs
		// note, that this code relies on single dialog modals (multi dialog, e.g. modal in modal is not supported)
		dialog : {
			// opens a dialog using the given url
			open : function(url, title) {
				// create the dialog container if not present already
				if(jQuery("#dialogcontainer").length == 0) {
					jQuery(document.body).append("<div id=\"dialogcontainer\"></div>");
				}
				
				// set a default title
				if(!title) {
					var title = "Dialog";
				}
				
				// finally load the dialog, set the dialog titel
				app.ajax.load({
					selector: "#dialogcontainer", 
					url: url, 
					callback: function() {
						app.dialog.checkOpen();
						app.dialog.setTitle(title);
					}
				});
			},
			
			// initializes the dialog with common dialog actions, like closing upon cancelling
			// use this function in the dialog rendering template to rebind common actions
			// upon dialog reload
			init : function() {
				jQuery(document).ready(function() {
					// binds the action to all buttons defining an action through the "name" attribute
					jQuery("#dialogcontainer button").each(function() {
						jQuery(this).click(function() {
							var action = jQuery(this).attr("name");
							if(action) {
								app.dialog.submit(action);
							}
							return false;
						});
					});					
					// cancel button binding
					jQuery("#dialogCancelBtn").click(function() {
						app.dialog.close();
						return false;
					});
				});
			},
			
			// sets the title of the dialog
			setTitle : function(title) {
				jQuery("#dialogcontainer").dialog("option", "title", title);
			},
			
			// checks, if the dialog is in the state "open" and sets the state if not presently set
			// this function is implicitly called by app.dialog.open(url, title) in order to initialize
			// the dialog properly; use this function to recover the "open" state of a dialog
			checkOpen : function() {
				if(!jQuery("#dialogcontainer").dialog("isOpen"))
				{
					jQuery("#dialogcontainer").dialog({
						autoOpen: false,
						modal: true,
						overlay: {
				    		opacity: 0.5,
				     		background: "black"
						},
				    	height: 425,
				    	width: 425,
				    	resizable: false
					});
					jQuery("#dialogcontainer").dialog("open");
				}
			},
			
			// closes the dialog and triggers the "close" event for the dialog
			close : function() {
				jQuery("#dialogcontainer").dialog("close");
				jQuery(document.body).trigger("dialogClosed");
			},
			
			// attaches the given callback function upon dialog "close" event
			onClose : function(callback) {
				if(callback != undefined) {
					jQuery(document.body).bind("dialogClosed", callback);
				}
			},
			
			// triggers the "apply" event for the dialog
			triggerApply : function() {
				jQuery(document.body).trigger("dialogApplied");
			},
			
			// attaches the given callback function upon dialog "apply" event
			onApply : function(callback) {
				if(callback != undefined) {
					jQuery(document.body).bind("dialogApplied", callback);
				}
			},
			
			// triggers the "delete" event for the dialog
			triggerDelete : function() {
				jQuery(document.body).trigger("dialogDeleted");
			},
			
			// attaches the given callback function upon dialog "delete" event
			onDelete : function(callback) {
				if(callback != undefined) {
					jQuery(document.body).bind("dialogDeleted", callback);
				}
			},
			
			// submits the dialog form with the given action
			submit : function(action) {
				// set the action
				jQuery("#dialogcontainer form").append("<input name=\"" + action + "\" type=\"hidden\" />");
				// serialize the form and get the post url
				var post = jQuery("#dialogcontainer form").serialize();
				var url = jQuery("#dialogcontainer form").attr("action");
				// post the data and replace current content with response content
		  		jQuery.ajax({
				   type: "POST",
				   url: url,
				   data: post,
				   dataType: "html",
				   success: function(data){
				   		jQuery("#dialogcontainer").empty().html(data);
				   },
				   failure: function(data) {
				   		alert("Server connection failed!");
				   }
				});
			}
		},
		
		// ##########################################################################
		//
		//            specific for the Columbia project
		//
		// ##########################################################################
		/**
		 *  StringHelper:  
		 *		trim : cuts of ' ', \t, \r and \n from the beginning and the end of a String
		 */
		StringHelper: {
			EMPTY_CHAR : " \t\r\n",
			trim: function( str ){
				if ( str == null )
					return null;
				var i = str.length - 1;
				var n = 0;
				for ( ; i >= 0; i-- )
					if ( this.EMPTY_CHAR.indexOf( str.charAt( i ) ) == -1 )
					{
						i++;
						break;
					}
				if ( i > -1 )
				{
					for ( ; n < i; n++ )
						if ( this.EMPTY_CHAR.indexOf( str.charAt( n ) ) == -1 )
							break;
				}
				return str.substring( n, i );
			}
		},
		
		/**
		  submit any kind of form via AJAX request.
		  options:
		  {
		  	triggeredObject :  HTML DOM Object that triggered the event
		  	modal           :  optional # Modal dialog (used for the RF function; default true
		  	title           :  Title for the popup (also used by RF for the DIV ID)
		  	width           :  optional # used for RF popup; default 450
		  	hookItHereDivId :  optional # Do not use RF popup, just put the return value here
		  	actionName      :  optional # submit that action name; default taken from the triggered object name; will return the used actionName
		  	actionValue     :  optional # submit that value for the action; default taken from triggered object ID or if not set value; will return the used actionValue
		  	method          :  optional # default taken from the triggered object's parent form method of if not set 'GET'; will return the used method
		  	url             :  optional # default taken from the triggered object's parent form action; will return the used URL
		  	callBack        :  optional # used only for popups; function to be called after popup is shown (initialize the functions on popups)
		  	beforeCloseCallBack: optional # used only for popups; function called before closing the dialog
		  	
		  	// return
		  	form            :  jQuery object representing the form that was modified 
		  	popupId         :  returns the ID that was used when working with RF popup
		  }
		  if neither title nor hookItHereDivId are provided, only the callBack method will be called
		  with the response.  The coder is then responsible to do with it whatever is needed
		*/
		ajaxSubmitAndShow: function ( options ){
			var ELEMENT_ID = "QWEqweQWE";
			var form = app.__prepareFormForSubmit( options, ELEMENT_ID );
			if ( form != null )
			{
				var data = form.serialize();
				
				jQuery( '#' + ELEMENT_ID ).remove();
				
				try
				{
					var func = (options.method == 'get' ? jQuery.get : jQuery.post );
					var oldDisabled = jQuery( options.triggeredObject ).attr( 'disabled' );
					
					if ( options.hookItHereDivId )
					{
						// put it in an existing DIV
						// put here the code to put the response into any existing DIV
						func( options.url, data, function(result) { 
								options.result = result; 
								jQuery( '#' + options.hookItHereDivId ).html( result ); 
								if ( options.callBack ) options.callBack( options );
								jQuery( options.triggeredObject ).attr( 'disabled', oldDisabled ); 
								document.body.style.cursor = "default";  
						});
					}
					else
					{
						if ( options.title )
						{
							// we got a title - must be for RF
							if ( !options.modal && options.modal != false )
								options.modal = true;
								
							func( options.url, data, function(result) { 
									options.result = result; 
									app.__handleAjaxResponseRfPopup( options ); 
									jQuery( options.triggeredObject ).attr( 'disabled', oldDisabled ); 
									document.body.style.cursor = "default";  
							});
						}
						else
						{
							// just a call to the server - let the call back handle the data
							func( options.url, data, function(result) { 
									options.result = result;
									if ( options.callBack )
										 options.callBack( options );
									document.body.style.cursor = "default";  
							});
							//enable it right way, we do not know here what is going to happen
							jQuery( options.triggeredObject ).attr( 'disabled', oldDisabled );
						}
					}
					document.body.style.cursor = "wait";
					jQuery( options.triggeredObject ).attr( 'disabled', 'disabled' );
				}
				catch ( ex )
				{
					//alert( "This should be in an https page!\n" + ex );
				}
				
			}
		},
		
		/*
		This method submits a form using the triggering object as a starting point
		for finding the surrounding form, action name and action value.
		options:
		{
			triggeredObject :  DOM Object that triggered the event
			actionName      :  optional # submit that action name; default taken from the triggered object name; will return the used actionName
			actionValue     :  optional # submit that value for the action; default taken from triggered object ID or if not set value; will return the used actionValue
			url             :  optional # default taken from the triggered object's parent form action
			method          :  optional # default taken from the triggered object's parent form method of if not set 'GET'
			form            :  jQuery object representing the form that was modified 
		}
		*/
		submitForm: function ( options ){
			var form = app.__prepareFormForSubmit( options, "QWEqweQWE" );
			if ( form != null )
			{
				if ( options.method )
					form.attr( 'method', options.method );
				form.submit();
				return false;
			}
		},
		
		
		// This function takes the response of an Ajax call and puts it in 
		// a putup dialog using the original Razorfish coding
		/**
		 options:
		 {
			modal     : optional # used by RF; flag indicating if it is a modal popup; default false (modal == false is not implemented!)
			title     : used by RF; title to be be shown in the popup AND also the DIV's ID of the popup 
			result    : used by RF; the HTML string showing in the popup 
		  	width     :  optional # used for RF popup; default 450; will return the width used
		  	callBack  :  optional # function to be called after popup is shown (initialize the functions on popups)
		  	beforeCloseCallBack: optional # used only for popups; function called before closing the dialog
		  	
		  	// returns the follwing attributes
		  	popupId   : the DIV's where the popup dialog is shown
		  	reloadUrl : the URL what was used to reload the main window after popup was closed
		}
		 */
		__handleAjaxResponseRfPopup: function( options ){
			if ( options.modal )
			{
				options.popupId = '#' + buildPopupDivId( options.title );
				var closeMarker = "<!--   C~L~O~S~E   I~T   -->";
				if ( options.result.substring( 0, closeMarker.length ) == closeMarker )
				{
					if ( options.beforeCloseCallBack )
						options.beforeCloseCallBack( options );
					app.colDialog.close( options.popupId );
					options.reloadUrl = jQuery( options.result ).filter( '#ReloadURL' ).val();
					
					if ( options.reloadUrl != null && options.reloadUrl.length > 0 )
					{
						window.location.href = options.reloadUrl;
					}
				}
				else
				{
					if ( jQuery( options.popupId ).length == 1 )
					{
						var updatemodal = document.getElementById(buildPopupDivId( options.title ));
						updatemodal.innerHTML = options.result;
					}
					else
					{
						modal( {
									title: options.title
									,body: options.result
									,width: (options.width ? options.width : options.width = 450 )
					            });
					}
					if ( options.callBack )
						options.callBack( options );
				}
			}
			else
			{
				alert( "GOT ANSWER:\nNot-modal popup is not implemented yet!\n\n" + result);
			}
		},
		
		// this function prepares a form for the submit by setting
		// the action tag and action value for the submitting object
		// derived from the trigger object.
		/*
		options:
		{
		  	triggeredObject :  DOM Object that triggered the event
		  	actionName      :  optional # submit that action name; default taken form the triggered object name; will return the used actionName
		  	actionValue     :  optional # submit that value for the action; default taken from triggered object ID or if not set value; will return the used actionValue
		  	
		  	// return
		  	form            :  jQuery object representing the fomr that was modified
		  	method          :  optional # the method used to submit the form; will return the used method type 
		}
		*/
		__prepareFormForSubmit: function ( options, dummyId ){
			if ( !options.actionName )
				options.actionName = options.triggeredObject.name;
				
			if ( !options.actionValue )
				options.actionValue = jQuery( options.triggeredObject ).attr( 'value' ) ? jQuery( options.triggeredObject ).attr( 'value' ) : options.triggeredObject.id;
				
			options.form = jQuery( options.triggeredObject ).parents( 'form:last' );
			
			var el   = document.createElement("INPUT");
			el.type  = "hidden";
			el.name  = options.actionName;
			el.id    = dummyId;
			el.value = (options.actionValue == null || options.actionValue == '' ? options.actionValue = "x" : options.actionValue); // whatever

			options.form.append( el );

			if ( !options.method )
				options.method = options.form.attr( 'method' ) ? options.form.attr( 'method' ) : method = 'get';
			options.method = options.method.toLowerCase();
			
			if ( !options.url ) 
				options.url = options.form[0].action;
				
			return options.form;
		},
		
		// dw scope public
		// note, that this code relies on single dialog modals (multi dialog, e.g. modal in modal is not supported)
		colDialog : {
			// closes the dialog and triggers the "close" event for the dialog
			close : function( popupId ) {
				jQuery( popupId ).dialog("close");
				// jQuery(document.body).trigger("dialogClosed");
				// window.location.href = window.location.href;
			}
		},
		
		compareProductsEnabled : false ,
		
		enableProductCompare : function() {
		  document.getElementById('enableCompare').style.display = "none";
	      document.getElementById('disableCompare').style.display = "inline";
	      compareProductsEnabled = true;
	      
	      jQuery('.compare-product-flag').toggle();
		},
		
		disableProductCompare : function() {
		  document.getElementById('enableCompare').style.display = "inline";
	      document.getElementById('disableCompare').style.display = "none";
	       compareProductsEnabled = false;
	       jQuery('.compare-product-flag').toggle();
		}
		
	}
})(jQuery);

jQuery(document).ready(function(){
	app.init();
});
