/*
	File: DakisDHE.js
	Provide a complete DHE application ready to be integrated into a website.

	Javascript Dependencies:

	- DakisAPI.js
	- dhtmlHistory.js
	- lightbox.js
	- behavior.js
*/
//***************************************************
//	Class: DakisDHEApplication
// 	Use this class to integrate the DHE into your webpage
//***************************************************
var DakisDHEApplication = Class.create();
DakisDHEApplication.prototype = {

	// Group: Configure your application

	/*
		Method: initialize
		Create the application.  Make sure to call the <dakisInit> function before.
	*/
	initialize: function()
	{
		dakisAssert(g_dakisDHEApplication === null, "Only one instance of the DakisDHEApplication can be created");
		g_dakisDHEApplication = this;
		g_dheEvents.onCartIndicatorUpdated = (this.onCartIndicatorUpdated).bind(this);
		g_dakisGlobalExecutionGuard.execute(    (function(){ this.onWindowLoaded();}).bind(this),
												[g_dakisGlobalExecutionGuard.windowLoadedEvent] );

	},

	/*
		Method: loadCartIndicator
		Display a cart indicator in the specified html element.  May load multiple
		cart indicators in the same web page.

		Parameters:

		htmlElementId - where to display the component.  The inner html of the element will be
						replaced by the component's html.
	*/
	loadCartIndicator: function(htmlElementId)
	{
		var dakisCartIndicator = new DakisCartIndicator(htmlElementId);
		dakisCartIndicator.onClick = (this.onCartIndicatorClick).bind(this);
		dakisCartIndicator.paint();
		this.cartIndicators.push(dakisCartIndicator);

		//using page load event would cause a bug when the cart would not update before the page load
		g_dakisGlobalExecutionGuard.execute((function(){ this.updateCartIndicatorsVisibility();}).bind(this), [g_dakisGlobalExecutionGuard.dakisCartLoadedEvent] );
		//g_dakisGlobalExecutionGuard.execute((function(){ this.updateCartIndicatorsVisibility();}).bind(this), [g_dakisGlobalExecutionGuard.windowLoadedEvent] );
	},

	/*
		Method: loadProductLineMenu
		Display a product line menu in the specified html element.  ** Only one
		product line menu allowed in the same web page.

		Parameters:

		htmlElementId - where to display the component.  The inner html of the element will be
						replaced by the component's html.
	*/
	loadProductLineMenu: function(htmlElementId, preloadSearch)
	{
		dakisAssert(this.productLineMenu === null, "Only one product line menu can be loaded in the DakisDHEApplication");
		this.productLineMenu = new DakisProductLineMenu(htmlElementId, preloadSearch);
		this.productLineMenu.onClick = (this.onProductLineMenuClick).bind(this);
		this.productLineMenu.paint();
		this.productLineMenu.onSearchSubmitted = (this.onSearchSubmitted).bind(this);

		if( this.searchPanelProductLineId != null && this.searchPanelDepartmentId != null )
			this.showSearchPanel( this.searchPanelProductLineId, this.searchPanelDepartmentId );
	},

	/*
		Method: loadAdRotator
		Display an add rotator in the specified html element.  May load multiple
		ad rotator in the same web page.

		Parameters:

		htmlElementId - where to display the component.  The inner html of the element will be
						replaced by the component's html.
	*/
	loadAdRotator: function(htmlElementId, timeout)
	{
		var dakisAdRotator = new DakisProductAdvertiser( htmlElementId, timeout );
		dakisAdRotator.onShowSpecSheet = (this.onAdRotatorShowSpecSheet).bind(this);
		dakisAdRotator.onAddToCart = (this.onAdRotatorAddToCart).bind(this);
		dakisAdRotator.load();

		this.adRotators.push(dakisAdRotator);
	},

	/*
		Method: loadKeyboard
	Creates the flashKeyboard element
	Parameters:
	htmlElementId - where to display the component.  The inner html of the element will be
						replaced by the flash keyboard
	w - desired width of the keyboard
	h - desired height of the keyboard
	*/
	loadKeyboard: function(callbackObj,flashUrl,w,h,htmlElementId,cssUrl)
	{
		this.flashKeyboard = new DakisDHEKeyboard(callbackObj,flashUrl,w,h,htmlElementId,cssUrl);
	},
	callKeyboard: function(htmlElementId, helpText)
	{
		if(this.flashKeyboard)
			this.flashKeyboard.promptObject(htmlElementId, helpText);
	},
	renderOutput: function(msg)
	{
		if(this.flashKeyboard)
			this.flashKeyboard.renderOutput(msg);
	},
	hideKeyboard: function()
	{
		if(this.flashKeyboard)
			this.flashKeyboard.hideObject();
	},
	/*
		Method: setMaxComparedProducts
		Set the maximum number of products to compare in the comparison screen.
	*/
	setMaxComparedProducts: function(nbProducts)
	{
		this.maxComparedItems = nbProducts;
	},
	
	// Group: DHE specific

	/*
		Method: showSearchPanel
	*/
	showSearchPanel: function(productLineId, departmentId)
	{
		this.searchPanelProductLineId = productLineId;
		this.searchPanelDepartmentId = departmentId;

		if( this.productLineMenu != null )
			this.productLineMenu.showSearchPanel(productLineId, departmentId);
	},

	// Private

	// Called once at the window load event
	onWindowLoaded: function()
	{
		g_comparison_manager = new DakisComparisonManager( this.maxComparedItems );
		startDakis(g_dakisLang, this.maxComparedItems);
		initPopupWindow();
		initRSH();
		/*
		if(this.flashKeyboard){
			this.flashKeyboard.createObject();}*/
	},

	// Paint all cart indicators
	paintCartIndicators: function()
	{
		for(var i=0; i<this.cartIndicators.length; i++)
		{
			this.cartIndicators[i].paint();
		}
	},

	paintProductLineMenu: function()
	{
		if( this.productLineMenu != null )
		{
			this.productLineMenu.paint();
		}
	},

	// Show or hide all cart indicators
	updateCartIndicatorsVisibility: function()
	{
		if( g_dakisRetailerInfo && g_dakisRetailerInfo.hasCheckout )
			this.showCartIndicators();
		else
			this.hideCartIndicators();
	},

	showCartIndicators: function()
	{
		for(var i=0; i<this.cartIndicators.length; i++)
		{
			this.cartIndicators[i].show();
		}
	},

	hideCartIndicators: function()
	{
		for(var i=0; i<this.cartIndicators.length; i++)
		{
			this.cartIndicators[i].hide();
		}
	},

	// Event handlers
	onCartIndicatorUpdated : function()
	{
		this.paintCartIndicators();
	},


	onCartIndicatorClick: function()
	{
		showCart(true);
	},

	onProductLineMenuClick: function(productLineId, departmentId)
	{
		DakisPositionner.scrollToElement( 'dhe_content' );
		showCatalog(productLineId, true, 1, null, departmentId, true);
	},

	onAdRotatorShowSpecSheet: function(merchandiseId)
	{
		showSpecSheet(merchandiseId, true, "ad_rotator");
	},

	onAdRotatorAddToCart: function(merchandiseId, currentPrice)
	{
		addToCart(merchandiseId, currentPrice);
	},

	onSearchSubmitted: function( form_obj, product_line_id, department_id )
	{
		submitSearch( form_obj, product_line_id, department_id );
	},

	cartIndicators: [],
	productLineMenu: null,
	adRotators: [],
	flashKeyboard: null,
	maxComparedItems: 3,
	searchPanelProductLineId: null,
	searchPanelDepartmentId: null

};

//***************************************************
//	Class: DakisDHECart
// 	Represents content of the cart
//***************************************************
var DakisDHECart = Class.create();
DakisDHECart.prototype = {

	/*
		Method: initialize
		Constructor

		Parameters:

		htmlElementId - html element id where to display the cart
	*/
	initialize: function(htmlElementId, itemsHtmlElementId)
	{
		this.htmlElementId = htmlElementId;
	this.itemsHtmlElementId = itemsHtmlElementId;
		this.listenerId = g_dakisListenerManager.getListenerId(this);
	},

	/*
		Method: paint
		Display the cart inside the specified html element
	*/
	paint: function()
	{
		var self = this;
		var url = getActionUrl({ controller: 'cart', action: 'cart_screen' });
		dakisAjaxUpdater( this.htmlElementId, url , { onLoading:onLoading, onComplete: function(){self.onPaintCompleted();} }  );
	},

	paintItems: function()
	{
		var self = this;
		var url = getActionUrl({ controller: 'cart', action: 'cart_items' });
	
		dakisAjaxUpdater( this.itemsHtmlElementId, url, { postBody: this.findCustomerPostBody(), onLoading:onLoading, onComplete: function(){self.onPaintItemsCompleted();}});
	},

	// Private event handlers

	onAddItem: function(merchandiseId, currentPrice)
	{
		addToCart(merchandiseId, currentPrice, true);
	},

	onRemoveItem: function(merchandiseId)
	{
		removeFromCart(merchandiseId);
	},

	onChangeRegion: function()
	{
		//this.paintItems();
				var self = this;
		var url = getActionUrl({ controller: 'cart', action: 'cart_screen' });
		dakisAjaxUpdater( this.htmlElementId, url , { postBody: this.findCustomerPostBody(), onLoading:onLoading, onComplete: function(){self.onPaintCompleted();} }  );

	},

	onValidateCustomer: function()
	{
		var self = this;
		var url = getActionUrl({ controller: 'cart', action: 'validate_customer' });
		dakisAjaxUpdater( 'dhe_cart_validation_container', url, { postBody: this.findCustomerPostBody(), onLoading:onLoading, onComplete: function(){self.onValidateCustomerCompleted();}});
	},

	onValidateCustomerCompleted: function()
	{
	onComplete();

	var cartForm = $(CART_PAYPAL_FORM);
	if( cartForm )
	{
		
		//get the client's session id
		var original_session_id = cartForm.original_session_id.value;
		//be sure that this url is accessible from outside
		var url = getActionUrl({ controller: 'cart', action: 'handle_paypal_notify', client_session_id: original_session_id });
		//$(CART_PAYPAL_FORM).notify_url.value = "http://webdhe.dakisdev.com:8080/app_base/cart/7cbaef23-5337-4e85-894e-5cb873265d5c/handle_paypal_notify?client_session_id=e52dae6d1b9ba79e41b1670a4bc200ce";
		cartForm.notify_url.value = url;
		url = getActionUrl( { controller: 'cart', action:'clear_cart_after_payment'} );
				
		for( i=0; i<cartForm.childNodes.length; i++)
		{
			if( cartForm.childNodes[i].name == "return" )
			{
				cartForm.childNodes[i].value = url;
				break;
			}
		}
		
		submitForm(CART_PAYPAL_FORM);
	}

	},

	onPaintCompleted: function()
	{
		replaceListener(this.htmlElementId, this.listenerId);
		onComplete();
		initLightboxAnchors();
	},

	onPaintItemsCompleted: function()
	{
		replaceListener(this.itemsHtmlElementId, this.listenerId);
		onComplete();
		//initLightboxAnchors();
	},

	findCustomerPostBody: function()
	{
	var form = $(CART_CUSTOMER_FORM);

	if( form != null )
	{
		return Form.serialize(form);
	}
	else
	{
		return null;
	}
	},

	// Private attributes

	listenerId: null,
	htmlElementId: null,
	itemsHtmlElementId: null

};


//***************************************************
//	Section: Internal functionnalities
//***************************************************

/*
	Function: dakisHasCheckout
	Get whether the retailer has a checkout method.

	Parameters:

	callback -  function to be executed when the response arrive.
				Prototype: callback(bool value)
*/
function dakisHasCheckout(callback)
{
	var url = getActionUrl({ action:'has_checkout'});
	dakisAjaxRequest( url, { method:'get', onComplete: function( request ){
		var bool = (request.responseText == "TRUE");
		callback(bool);
	}});
}

/*
	Function: initPopupWindow
	Initialize the pop-up window (Lightbox component)
*/
function initPopupWindow()
{
	myLightbox = new Lightbox();
	dakisAjaxUpdater( myLightbox.bottom_controls_id, getActionUrl({action:'popup_controls'}) );
}

/*
	Function: StartDakis
	Draws the various DHE components once the window has loaded

	Parameters:
	lang - default language
*/
function startDakis( lang)
{
	dakisSetLanguage( lang );
	setLightboxImages(lang);
	addLoaderDiv();
	addCartSignalDiv();
}

function onCatalogBeforeUpdate( xmlHttpReq, obj )
{
	Element.update("dhe_content", "<div id=\"dhe_catalog\"></div>");
}

function getCatalogBeforeCallback()
{
	catalog = $('dhe_catalog');
	if (catalog === undefined || $('dhe_accessories') !== undefined )
	{
		return onCatalogBeforeUpdate;
	}
}

/*
	Function : submitSearch
	Submits a search form and updates the catalog with the search parameters
*/
function submitSearch( form_obj, product_line_id, department_id )
{
	var formData = Form.serialize( form_obj );
	//No extra http requests.
	//sendActionRequest( 'execute_dhe_search', { postData:formData } );
	var onBeforeUpdate = getCatalogBeforeCallback();
	updateCatalogWithOptions({product_line_id: product_line_id,
							reset_search: false,
							department_id: department_id,
							add_to_history: true,
							onBeforeUpdate: onBeforeUpdate,
							postBody: formData });

	current_product_line = product_line_id;
}

/*
	Function: showCatalog
	Prepares query object for updateCatalogWithOptions function

	Parameters:
	product_line_id - Id of the product line to be displayed (Integer)
	reset_search - Decides if the search parameters should be reset (Boolean)
	page - Page number to be shown (Integer)
	sort_on - Which parameter the list should be sorted on (String)
	department_id - Id the product line's department (used in case the same product line is in more than one department) (Integer)
	add_to_history - Decides if the event will be added to history (Boolean)
*/
function showCatalog( product_line_id, reset_search, page, sort_on, department_id, add_to_history)
{
	var onBeforeUpdate = getCatalogBeforeCallback();
	updateCatalogWithOptions({product_line_id: product_line_id,
							reset_search: reset_search,
							page: page,
							sort_on: sort_on,
							department_id: department_id,
							add_to_history: add_to_history,
							onBeforeUpdate: onBeforeUpdate });

	current_product_line = product_line_id;
}

/*
	Function: showCatalogByDmGuid
	Show the catalog corresponding to this decision model which is a retailer independent id.

	Parameters
	dm_guid - guid format identifying digital cameras, bags and cases
	reset_search - Decides if the search parameters should be reset (Boolean)
	page - Page number to be shown (Integer)
	sort_on - Which parameter the list should be sorted on (String)
	department_id - Id the product line's department (used in case the same product line is in more than one department) (Integer)
	add_to_history - Decides if the event will be added to history (Boolean)
*/
function showCatalogByDmGuid( dm_guid, reset_search, page, sort_on, department_id, add_to_history)
{
	if( g_dakisRetailerInfo )
	{
		product_line_id = g_dakisRetailerInfo.decisionModelProductLineMap[dm_guid];
		showCatalog( product_line_id, reset_search, page, sort_on, department_id, add_to_history );
	}
	else
	{
		var onBeforeUpdate = getCatalogBeforeCallback();
		updateCatalogWithOptions({decision_model_id: dm_guid,
								reset_search: reset_search,
								page: page,
								sort_on: sort_on,
								department_id: department_id,
								add_to_history: add_to_history,
								onBeforeUpdate: onBeforeUpdate});
	}
}

/*
	Function: showRecommendation
	Prepares query object for updateCatalogWithOptions method

	Parameters:

	product_line_id - Id of the product line to be displayed (Integer)
	reset_search - Decides if the search parameters should be reset (Boolean)
	page - Page number to be shown (Integer)
	sort_on - Which parameter the list should be sorted on (String)
	department_id - Id the product line's department (used in case the same product line is in more than one department) (Integer)
	needs - concatenated string of need guids (String)
	add_to_history - Decides if the event will be added to history (Boolean)

*/
function showRecommendation( product_line_id, reset_search, page, needs, budget, add_to_history)
{
	sendActionRequest( 'get_dhe_recommendation', { postData:needs } );
	var onBeforeUpdate = getCatalogBeforeCallback();
	updateCatalogWithOptions({product_line_id: product_line_id,
							reset_search: reset_search,
							page: page,
							sort_on: "rec",
							add_to_history: add_to_history,
							questionnaire_budget: budget,
							needs: needs,
							onBeforeUpdate: onBeforeUpdate});

	current_product_line = product_line_id;
}

/*
	Function - updateCatalogWithOptions
	This is where the actual visual updating of the catalog is done (called in the RJS related to showCatalog)

	Parameters:
	options - Javascript Hash containing the necessary parameters to create the objects on the server-side (same as showCatalog plus for_merchandise_id and no_pages [for accessories]) (Hash)
*/
function updateCatalogWithOptions( options )
{
	options = $H(options);

	options.action = 'update_catalog';
	var add_to_history = options.add_to_history === true || options.add_to_history === "true";
	var onBeforeUpdate = options.onBeforeUpdate;
	var postBody = options.postBody;
	var needs = options.needs;
	
	var scrollOnComplete = options.scrollOnComplete === true || options.scrollOnComplete === "true";

	if( options.page == null )
	{
		options.page = 1;
	}

	if( options.sort_on == null || options.sort_on.length <= 0 )
	{
		options.sort_on = "brand"
	}

	if( options.needs != null )
	{
		postBody = "needs=" + needs;
	}

	options.add_to_history = options.needs = options.postBody = options.onBeforeUpdate = null;

	var url = getActionUrl(options);

	if( add_to_history )
	{
		var key = 'DHE:Catalog:Line:'+ options.product_line_id +':Page:'+ options.page + ':SortOn:' + options.sort_on + ':Dept:' + options.department_id;
		dhtmlHistory.add( key, {h_product_line_id:options.product_line_id, h_reset_search:options.reset_search, h_page:options.page, h_sort_on:options.sort_on, h_dept:options.department_id } );
	}

	// when providing the decision model guid, the product line id is undefined...
	if( options.product_line_id !== undefined)
	{
		g_dakisDHEApplication.showSearchPanel( options.product_line_id, options.department_id );
	}
	
	if( postBody === undefined )
	{
		if(scrollOnComplete)
			dakisAjaxUpdater( CATALOG, url , { asynchronous:true, method:'get', onBeforeUpdate:onBeforeUpdate, onLoading:onLoading, onComplete: function(){OnCatalogUpdate();onComplete();OnProductUpdate();g_comparison_manager.setCurrentChecks(options.product_line_id);initLightboxAnchors();} } );
		else
			dakisAjaxUpdater( CATALOG, url , { asynchronous:true, method:'get', onBeforeUpdate:onBeforeUpdate, onLoading:onLoading, onComplete: function(){onComplete();OnProductUpdate();g_comparison_manager.setCurrentChecks(options.product_line_id);initLightboxAnchors();} } );
	}
	else
	{
		if(scrollOnComplete)
			dakisAjaxUpdater( CATALOG, url , { asynchronous:true, method:'post', postBody: postBody, onBeforeUpdate:onBeforeUpdate, onLoading:onLoading, onComplete: function(){OnCatalogUpdate();onComplete();OnProductUpdate();g_comparison_manager.setCurrentChecks(options.product_line_id);initLightboxAnchors();} } );
		else
			dakisAjaxUpdater( CATALOG, url , { asynchronous:true, method:'post', postBody: postBody, onBeforeUpdate:onBeforeUpdate, onLoading:onLoading, onComplete: function(){onComplete();OnProductUpdate();g_comparison_manager.setCurrentChecks(options.product_line_id);initLightboxAnchors();} } );
	}
		
}

/*
	Function: addToCart
	Sends an Ajax.Request that will add a merchandise to the shopping cart

	Parameters:
	merchandise_id - Id of the merchandise to add to the shopping cart (Integer)
	noSignal - if true, no signal will be displayed.  Usually a signal is displayed to let the
				user knows that an item has been added.
*/
function addToCart( merchandise_id, currentPrice, noSignal )
{
	var url = getActionUrl({ controller: 'cart', action: 'add_to_cart', merchandise_id: merchandise_id, price:currentPrice});
	var onCompleteAction = function(request)
	{
		updateCart();
		g_dheEvents.onCartIndicatorUpdated();
	};
	
	if( noSignal )
	{
		dakisAjaxRequest( url, {onComplete: onCompleteAction});
	}
	else
	{
		//myLightbox.popup(url, '', true, ok_fct, cancel_fct, 500 );
		myLightbox.popupExtended( url, 
			{
				onRequestComplete: onCompleteAction,
				onOk: function(){ showCart(true); }, 
				onCancel: null,
				dialogMode: true,
				showButtons: false
			});
	}
	
/*	
	dakisAjaxRequest( url, {onComplete:
			function(request)
			{
				updateCart();
				g_dheEvents.onCartIndicatorUpdated();
				if( !noSignal ){
					var self = this;
					var ok_fct = function(){ alert('ok'); };
					var cancel_fct = function(){ alert('cancel'); };
					myLightbox.popup(url, '', true, ok_fct, cancel_fct, 500 );
					
					signalCartModification(request.responseText);
				}
			} } );
*/
}

function removeFromCart( merchandise_id )
{
	var url = getActionUrl({ controller: 'cart', action: 'remove_from_cart', merchandise_id: merchandise_id });
	dakisAjaxRequest( url, {onComplete: function(){updateCart(); g_dheEvents.onCartIndicatorUpdated();}} );
}


/*
	Function: showCart
	Navigates to the cart screen

	Parameters:
	add_to_history - Decides if the event will be added to history (Boolean)
*/
var cart = null;
function showCart(add_to_history)
{
	if(add_to_history)
	{
		dhtmlHistory.add( 'DHE:Cart', null );
	}

	if( cart == null )
	{
		cart = new DakisDHECart(CONTENT, CART_CONTENT_ITEMS);
	}
	else
	{
	}

//    var cart = new DakisDHECart(CONTENT);
	cart.paint();
}

/*
	Function: updateCart
	Update the cart (when the cart is modified from the Cart screen)
*/
function updateCart()
{
	if( $(CART_CONTENT_ITEMS) && (cart != null) )
	{
		cart.paintItems();
	}
}

/*
	Function showQuestionnaire
	Navigates to the questionnaire screen

	Parameters:
	product_line_id - Id of the product line to display the questionnaire for (Integer)
	add_to_history - Decides if the event will be added to history (Boolean)
*/
function showQuestionnaire( product_line_id, add_to_history )
{
	if ( add_to_history )
	{
		dhtmlHistory.add( 'DHE:Questionnaire:Line:'+ product_line_id, {h_product_line_id:product_line_id } );
	}

	g_questionnaire = new DakisQuestionnaire(product_line_id);
	g_questionnaire.onQuestionnaireFinished = function(product_line_id, needs, budget) {
		showRecommendation(product_line_id, false, 0, needs, budget, "true");
	};
	//flashAppOpenArgs('pl=' + product_line_guid);
}

/*
	Function: showSpecSheet
	Navigates to the spec sheet screen

	Parameters:
	merchandise_id - Id of the merchandise to display the spec sheet for (Integer)
	add_to_history - Decides if the event will be added to history (Boolean)
	previous_action - Used for reports
*/
function showSpecSheet( merchandise_id, add_to_history, previous_action, accessoryOf )
{
	var url = getActionUrl({ action: 'spec_sheet_screen', merchandise_id: merchandise_id, previous_action: previous_action, accessory_of:accessoryOf });
	dakisAjaxUpdater( CONTENT, url , { onLoading:onLoading, onComplete: function(){onComplete();OnSpecSheetUpdate();initLightboxAnchors(); showSpecifications(merchandise_id, add_to_history); } }  );
}

/*
	Function: showSpecSheetByProductGuid
	Show merchandise spec sheet from a product guid (the retailer guid is automatically sent)

	Parameters:
	product_guid - guid for the product to be displayed (String)
*/
function showSpecSheetByProductGuid( product_guid )
{
	var url = getActionUrl({ action: 'spec_sheet_screen', product_guid: product_guid });
	dakisAjaxUpdater( CONTENT, url , { onLoading:onLoading, onComplete: function(){onComplete();OnSpecSheetUpdate();initLightboxAnchors(); showSpecificationsByProductGuid(product_guid); } }  );
}

/*
	Function: showAccessories
	Navigate to the accessory list for a given merchandise

	Parameters:
	merchandise_id - Id of the merchandise to fetch accessories for (Integer)
	product_line_id - Id of the product line of the merchandise to fetch accessories for (Integer)
	add_to_history - Decides if the even will be added to history (Boolean)
*/

function showAccessories( merchandise_id, product_line_id, add_to_history )
{
	var url = getActionUrl({ action: 'spec_sheet_screen', merchandise_id: merchandise_id });
	dakisAjaxUpdater( CONTENT, url , { onLoading:onLoading, onComplete: function(){onComplete(); OnSpecSheetUpdate(); updateAccessories(merchandise_id, product_line_id, null, add_to_history); } }  );
}

/*
	Function: updateAccessories
	Updates the specsheet sub content with the accessories

	Parameters:
	merchandise_id - Id of the merchandise to fetch accessories for (Integer)
	product_line_id - Id of the product line of the merchandise to fetch accessories for (Integer)
	add_to_history - Decides if the even will be added to history (Boolean)
*/
function updateAccessories( merchandise_id, product_line_id, sort_on, add_to_history )
{
	var options = { action: "update_accessories",
				product_line_id: product_line_id,
				reset_search: false,
				merchandise_id: merchandise_id,
				sort_on: sort_on,
				no_pages: true };

	if( add_to_history )
	{
		var key = 'DHE:Specsheet:Id:'+merchandise_id+':Section:Accessories:' + product_line_id;
		dhtmlHistory.add( key, {h_id:merchandise_id, h_section:'Accessories', h_product_line:product_line_id} );
	}

	var url = getActionUrl( options );
	dakisAjaxUpdater( "dhe_spec_sheet_sub_content", url, { onLoading:onLoading, onComplete: function(){onComplete();activateTab('dhe_accessories_section_tab');OnProductUpdate();g_comparison_manager.setCurrentChecks(product_line_id);initLightboxAnchors();} } );
}

/*
	Function: showSpecifications
	Show the specsheet for a product (called after showSpecSheet)

	Parameters:
	merchandise_id - Id of the merchandise for which the specs will be displayed(Integer)
	add_to_history - Decides if the even will be added to history (Boolean)
*/
function showSpecifications( merchandise_id, add_to_history )
{
	var url = getActionUrl({ action: 'product_specifications', merchandise_id: merchandise_id });

	var key = 'DHE:Specsheet:Id:'+merchandise_id+':Section:Specs';
	if(add_to_history)
	{
		dhtmlHistory.add( key, {h_id:merchandise_id, h_section:'Specs'} );
	}

	dakisAjaxUpdater( SPECSHEET_CONTENT, url , { onLoading:onLoading, onComplete: function(){onComplete();initLightboxAnchors();activateTab( 'dhe_spec_section_tab' );} }  );
}

/*
	Function: showSpecificationsByProductGuid
	Show merchandise spec from its product guid

	Parameters:
	product_guid - Guid of the product for which the specs will be displayed (String)
*/
function showSpecificationsByProductGuid( product_guid )
{
	var url = getActionUrl({ action: 'product_specifications', product_guid: product_guid });
	dakisAjaxUpdater( SPECSHEET_CONTENT, url , { onLoading:onLoading, onComplete: function(){onComplete();initLightboxAnchors();activateTab( 'dhe_spec_section_tab' );} }  );
}



//***************************************************
//	Section: Callbacks
//	Callback functions
//***************************************************
/*
	Function: activateTab
	Activates a tab (in the spec sheet/accessory screen)

	Parameters:
	id - id of the HTML element to be switched over (String)
*/
function activateTab( id )
{
	var inactiveClass = 'dhe_spec_sheet_tab';
	var activeClass = 'dhe_spec_sheet_tab_active';

	$('dhe_spec_section_tab').className = inactiveClass;

	if( $('dhe_accessories_section_tab') )
	{
		$('dhe_accessories_section_tab').className = inactiveClass;
	}

	$( id ).className = activeClass;
}

//	Function: onLoading
//	Displays the loading screen
function onLoading()
{
	addOverlay();
	showLoader();
}

//	Function: onComplete
//	Removes the loading screen
function onComplete()
{
	hideLoader();
	removeOverlay();
}

//***************************************************
//	Section: Helpers
//	Helper functions
//***************************************************

/*
	Function: radioValue
	Returns value of radio button within select div (used in comparison editor)

	Parameters:
	div_id - id of div to be inspected (String)

	Returns:
	Value for a checked radio button or empty string
*/
function radioValue( div_id )
{
	var container = $(div_id);
	var radios = container.getElementsByTagName('input');

	for( i=0; i<radios.length; i++)
	{
		if( radios[i].type == "radio" && radios[i].checked )
		{
			return radios[i].value;
		}
	}

	return '';
}

//	Function: toggleHeader
//	It doesn't do anything. No really, it doesn't, see for yourself.
function toggleHeader( id )
{
	//If we want to add bullets, use css
	//so that we can then change the image according
	//to the client
}

//	Section: Shopping Cart Functions

//	Function: addCartSignalDiv
//	Adds a div on the page that will be used to notify the user of changes made in the cart
function addCartSignalDiv()
{
	var bodyElem = document.getElementsByTagName("body")[0];
	var objSignal = document.createElement("div");
	objSignal.setAttribute('id', 'dhe_cart_signal');
	objSignal.style.zIndex = '101';
	objSignal.style.position = "absolute";
	objSignal.style.display = "none";
	bodyElem.appendChild(objSignal);
}

//	Function: signalCartModification
//	Signal a change in the cart to the user
function signalCartModification(html)
{
	stophideCartSignal();

	$('dhe_cart_signal').innerHTML = html;

	window.onscroll = function(){ PositionTopRight( $('dhe_cart_signal') ); };
	new Effect.Appear( 'dhe_cart_signal', { duration: 0.4, queue:'end', beforeStart:function(){ PositionTopRight( $('dhe_cart_signal') ); } } );
	hideTimeoutId = self.setTimeout( hideCartSignal , signal_timeout );
}

//	Variable: hideTimeoutId
//	Timeout ID of hiding function
var hideTimeoutId = null;

//	Variable: cartSignalFadeEffect
//	Used to cancel Fade effect
var cartSignalFadeEffect = null;

//	Function: hideCartSignal
//	Hides the cart signal
function hideCartSignal()
{
	cartSignalFadeEffect = new Effect.Fade('dhe_cart_signal', { duration: 1, queue:'end', afterFinish:stophideCartSignal } );
}

//	Function: stophideCartSignal
//	Stops the fade effect on the cart signal
function stophideCartSignal()
{
	if( hideTimeoutId != null )
	{
		self.clearTimeout(hideTimeoutId);
		hideTimeoutId = null;
	}

	if( cartSignalFadeEffect != null )
	{
		cartSignalFadeEffect.cancel();
		window.onscroll = null;
		cartSignalFadeEffect = null;
	}

}
//***************************************************
//	Section: Loader
//	Functions related to the loading screen
//***************************************************

//	Function: addLoaderDiv
//	Adds the DIV  that will be used everytime the loading screen is called (loading image)
function addLoaderDiv()
{
	var bodyElem = document.getElementsByTagName("body")[0];
	var objLoader = document.createElement("div");
	objLoader.setAttribute( 'id', 'dhe_loader_div' );
	objLoader.className = "dhe_loader";
	objLoader.style.zIndex = '101';
	objLoader.style.position = "absolute";
	objLoader.style.visibility = "hidden";
	bodyElem.appendChild( objLoader );
}

//	Function: hideLoader
//	Hides (using css styling) the loader and removes onscroll event
function hideLoader()
{
	$("dhe_loader_div").style.visibility = "hidden";
	window.onscroll = null;
}

//	Function: showLoader
//	Shows (using css styling) the loader and adds onscroll event that will move the loader
function showLoader()
{
	var loader = $("dhe_loader_div");
	PositionTopRight( loader );
	loader.style.visibility = "visible";
	window.onscroll= function(){ PositionTopRight( loader ); };
}

//***************************************************
//	Section: RSH Functions
//	Functions handling the back, forward and bookmark access
//***************************************************
/*
	Function: browseBack
	Deprecated, Called when user clicks on back links in order to go back to the product line even if the user accessed the page as a bookmark (or else)

	Parameters:
	default_back - Default function to called if a certain server-side parameters has been defined (Function)
*/
/*
function browseBack( default_back )
{
	var minLength = 0;
	if( dhtmlHistory.firstLoad == true )
		minLength = 1;

	if( dhtmlHistory.GetHistoryLength() > minLength )
	{
		var oldLoc = document.location.href;
		historyBack();

		setTimeout( function(){
			var newLoc = document.location.href;
			if( oldLoc.match( newLoc ) )
			{
				default_back();
			}
		}, 300 );
	}
	else if ( default_back != null )
	{
		default_back();
	}
}
*/

function historyBack()
{
	if( ie )
	{
		parent.history.go(-1);
	}
	else
	{
		history.back();
	}
}

//	Function: initRSH
//	Initialize the history management system
function initRSH()
{
	// initialize RSH
	dhtmlHistory.initialize();

	// add ourselves as a listener for history
	// change events
	dhtmlHistory.addListener( onHistoryChange );
	dhtmlHistory.addOnAddListener( onHistoryAdd );

	// determine our current location so we can
	// initialize ourselves at startup
	var initialLocation = dhtmlHistory.getCurrentLocation();

	// if no location specified, use the default
	onHistoryChange(initialLocation, null);
}

/*
	Function: onHistoryAdd
	Listens for every call adding history events

	Parameters:
	newLocation - The new URL (String)
*/
function onHistoryAdd( newLocation )
{
	current_history_loc = newLocation;
}

/*
	Function: onHistoryChange
	Listens for history changing events (back, forward and bookmark access)

	Parameters:
	newLocation - The new URL (String)
	historyData - History data (parameters) necessary to access the page (RSH Instance)
*/
function onHistoryChange( newLocation, historyData )
{
	if( newLocation != null && newLocation != '' && newLocation != current_history_loc )
	{
		 setWebDheLocation( newLocation, historyData );
	}
	else
	{
		// if nothing to show, display the default product line catalog
		if( ( newLocation == null || newLocation == '' ) && current_history_loc != "default" )
		{
			current_history_loc = "default";
			showCatalogByDmGuid(g_defaultDecisionModelGuid, true, 1,null, 2, false);
		}
	}

}

/*
	Function setWebDheLocation
	Handles history changes and calls the necessary navigation functions

	Parameters:
	newLocation - The new URL (string)
	historyData - History data (parameters) necessary to access the page (RSH Instance)
*/
function setWebDheLocation( newLocation, historyData )
{
	var params_array = [];
	current_history_loc = newLocation;
	closeLightbox();

	if( newLocation.match('DHE:Catalog'))
	{
		if(historyData)
		{
			if(current_product_line == historyData.h_product_line_id)
			{
				showCatalog( historyData.h_product_line_id, historyData.h_reset_search, historyData.h_page, historyData.h_sort_on, historyData.h_dept, false );
			}
			else
			{
				showCatalog( historyData.h_product_line_id, historyData.h_reset_search, historyData.h_page, historyData.h_sort_on, historyData.h_dept, false );
			}
		}
		else
		{
			params_array = newLocation.split(":");

			// may be accessed from a decision model id or product line id...
			if( newLocation.indexOf("dm_guid", 0) != -1 )
			{
				showCatalogByDmGuid(params_array[3], true, params_array[5], params_array[7], params_array[9], false);
			}
			else
			{
				showCatalog(params_array[3], true, params_array[5], params_array[7], params_array[9], false);
			}

		}
	}
	else if(newLocation.match('DHE:Comparison'))
	{
		var line = '';
		var comparedItems = null;
		var comparedItemsCount = 0;

		if( historyData )
		{
			comparedItems = historyData.h_compared;
			comparedItemsCount = historyData.h_count;
			line = historyData.h_product_line;
		}
		else
		{
			params_array = newLocation.split(":");
			comparedItemsCount = params_array.length - 4;
			comparedItems = new Array(comparedItemsCount);
			line = params_array[3];		
			for( i=4; i<params_array.length && i-4<comparedItems.length; i++ )
			{
				comparedItems[i-4] = params_array[i];
			}		
		}

		g_comparison_manager.setCurrentState( line, comparedItems, comparedItemsCount );
		g_comparison_manager.showComparison(line, false);
	 }
	else if(newLocation.match('DHE:Specsheet'))
	{
		 if(historyData)
		 {
			 if( historyData.h_section == "Accessories" )
			 {
				 showAccessories( historyData.h_id, historyData.h_product_line, false );
			 }
			 else
			 {
				 showSpecSheet(historyData.h_id, false, "history");
			 }
		 }
		 else
		 {
			params_array = newLocation.split(":");

			if( params_array[5] == "Accessories" )
			{
				showAccessories( params_array[3], params_array[6], false );
			}
			else
			{
				// spec may be accessed by merchandise's id or product's guid
				if( newLocation.indexOf("guid", 0) != -1 )
				{
					showSpecSheetByProductGuid(params_array[3]);
				}
				else
				{
					showSpecSheet(params_array[3], false, "history");
				}
			}
		}
	}
	else if(newLocation.match('DHE:Cart'))
	{
		showCart(false);
	}
	else if( newLocation.match('DHE:Questionnaire'))
	{
		if(historyData)
		{
			showQuestionnaire( historyData.h_product_line_id, historyData.h_department_id, false );
		}
		else
		{
			params_array = newLocation.split(":");
			showQuestionnaire(params_array[3], params_array[5], false);
		}
	}
}


//***************************************************
//	Class: DakisComparisonManager Class
// 	Manages comparison list for each product lines
//***************************************************
var DakisComparisonManager = Class.create();

DakisComparisonManager.prototype = {

	comparedProductsLimit: 3, //The maximum number of products that can be compared
	comparedProducts: [], //The compared products indexed by productLines
	comparedProductsCount: [], //The compared products count indexed by productLines

	initialize: function( comparedProductsLimit )
	{
		if( comparedProductsLimit != null )
		{
			this.comparedProductsLimit = comparedProductsLimit;
		}
	},

	setCurrentState: function( productLineId, comparedProducts, comparedProductsCount )
	{
		this.comparedProducts[productLineId] = comparedProducts;
		this.comparedProductsCount[productLineId] = comparedProductsCount;
	},

	// Method: initProductLineMap
	// Initialize the Array for the given product line
	initProductLineMap: function( productLineId )
	{
		this.comparedProducts[productLineId] = new Array( this.comparedProductsLimit );
		this.comparedProductsCount[productLineId] = 0;
	},

	// Method: addProduct
	// Add a merchandise in the array for the product line
	addProduct: function( productLineId, merchandiseId )
	{
		var index = this.comparedProductsCount[productLineId]++;
		this.comparedProducts[productLineId][index] = merchandiseId;
	},

	// Method: removeProduct
	// Removes a merchandise from the array for the product line
	removeProduct: function( productLineId, merchandiseId )
	{
		var newArray = new Array( this.comparedProductsLimit );
		var pos = 0;

		for( i=0; i<this.comparedProductsCount[productLineId]; i++ )
		{
			if( this.comparedProducts[productLineId][i] != merchandiseId )
			{
				newArray[pos++] = this.comparedProducts[productLineId][i];
			}
		}

		this.comparedProductsCount[productLineId]--;
		this.comparedProducts[productLineId] = newArray;
	},

	// Method: onProductCheck
	// Handles comparison logic
	onProductCheck: function( productLineId, merchandiseId )
	{
		if( this.comparedProducts[productLineId] == null )
		{
			this.initProductLineMap( productLineId );
		}

		var checked = this.productChecked(merchandiseId);

		if( checked && this.comparedProductsCount[productLineId] < this.comparedProductsLimit )
		{
			this.addProduct( productLineId, merchandiseId );
		}
		else if( checked && this.comparedProductsCount[productLineId] >= this.comparedProductsLimit )
		{
			this.showEditComparison( productLineId, merchandiseId );
		}
		else if( !checked )
		{
			this.removeProduct( productLineId, merchandiseId );
		}
	},

	// Method: showEditComparison
	// Displays the pop-up for the "too many products in comparison list" event
	showEditComparison: function( productLineId, merchandiseId )
	{
		var url = this.comparisonUrl( 'edit_comparison', productLineId );
		url += "&merchandise_over=" + merchandiseId;

		var self = this;
		var ok_fct = function(){ self.replaceInComparison( productLineId, radioValue('dhe_comparison_edit'), merchandiseId ); };
		var cancel_fct = function(){ self.uncheckMerchandise( merchandiseId ); };
		myLightbox.popup(url, '', true, ok_fct, cancel_fct, 500 );
	},

	// Method: showComparison
	// Creates the url for the comparison page and navigates there
	showComparison: function( productLineId, addToHistory )
	{
		if( this.comparedProductsCount[productLineId] <= this.comparedProductsLimit && this.comparedProductsCount[productLineId] > 0 )
		{
			var url = this.comparisonUrl( 'comparison_screen', productLineId );
			url += "&product_line_id=" + productLineId;

			if(addToHistory)
			{
				var historyData = { h_product_line: productLineId, h_compared: this.comparedProducts[productLineId], h_count: this.comparedProductsCount[productLineId] };
				dhtmlHistory.add( 'DHE:Comparison:Line:' + productLineId + this.toString( productLineId ), historyData );
			}

			dakisAjaxUpdater( CONTENT, url , { onLoading:onLoading, onComplete:function(){ onComplete();OnComparisonUpdate();initLightboxAnchors();} } );
		}
	},
	/*
	  Method: productChecked
	  Checks if merchandise is selected for comparison

	  Returns:
	  check value of given merchandise (Boolean)
	*/
	productChecked: function( merchandiseId )
	{
		var check = $('check_' + merchandiseId );
		return check.checked;
	},

	/*
	  Method: comparisonUrl

	  Returns:
	  the url for the comparison page (String)
	*/
	comparisonUrl: function ( action, productLineId )
	{
		var url = getActionUrl({ action: action });

		url += "merchandise_0=" + this.comparedProducts[productLineId][0];
		for( i=1; i<this.comparedProductsCount[productLineId]; i++ )
		{
			url += "&merchandise_" + i + "=" + this.comparedProducts[productLineId][i];
		}

		return url;
	},

	// Method: replaceInComparison
	// Replaces selected with removed after the comparison edit screen has closed
	replaceInComparison: function( productLineId, removed, selected )
	{
		this.uncheckMerchandise( removed );
		if( removed != selected )
		{
			this.removeProduct( productLineId, removed );
			this.addProduct( productLineId, selected );
		}
	},

	/*
	 Method: toString
	 Returns:
	 a stringed comparison list
	*/
	toString: function ( productLineId )
	{
		var linear = "";

		for( i=0; i<this.comparedProductsCount[productLineId]; i++ )
		{
			linear += ":" + this.comparedProducts[productLineId][i];
		}

		return linear;
	},

	// Method: uncheckMerchandise
	// Unchecks the merchandise if it is displayed
	uncheckMerchandise: function( merchandiseId )
	{
		var check = $('check_' + merchandiseId );
		if( check )
		{
			check.checked = false;
		}
	},

	// Method: uncheckMerchandise
	// Checks the merchandise if it is displayed
	checkMerchandise: function( merchandiseId )
	{
		var check = $('check_' + merchandiseId );
		if( check )
		{
			check.checked = true;
		}
	},

	// Method: clear
	// Clears the comparison list for a given product line
	clear: function( productLineId )
	{
		for( i=0; i<this.comparedProductsCount[productLineId]; i++ )
		{
			this.uncheckMerchandise( this.comparedProducts[productLineId][i]);
		}

		this.initProductLineMap( productLineId );
	},

	// Method: setCurrentChecks
	// Sets the checks for a product line (used with product lists)
	setCurrentChecks:function( productLineId )
	{
		for( i = 0; i<this.comparedProductsCount[productLineId]; i++ )
		{
			this.checkMerchandise( this.comparedProducts[productLineId][i] );
		}
	}
};

// Old methods that were defined in behavior.js

function OnSpecSheetUpdate() {}
function OnComparisonUpdate() {}
function OnCartIndicatorUpdate() {}
function OnCartUpdate() {}
function OnProductUpdate() {}
function OnSearchUpdate() {}
function OnProductLineUpdate() {}
function OnQuestionnaireUpdate() {}
function OnCatalogUpdate()
{
	DakisPositionner.scrollToElement( 'dhe_catalog' );	
}
function OnSectionChanged()
{
	DakisPositionner.scrollToElement( 'dhe_content' );
}


//***************************************************
//	Class: DheEvents Class
//	Responsible for handling events and callbacks
//***************************************************
var DheEvents = Class.create();
DheEvents.prototype = {
	initialize: function(){},

//	Method: onCartIndicatorUpdated
//	Called when the cart indicator need to be refreshed
	onCartIndicatorUpdated : function(){ alert("allo"); }
};

//	Variable: g_dheEvents
//	Override its methods to provide your own event handling logic (DheEvents)
var g_dheEvents = new DheEvents();


// Section: Private variables and definitions

// Section: Gloabal variables

// Variable: g_defaultDecisionModelGuid
// Default decision model to show when opening the catalog without argument
var g_defaultDecisionModelGuid = "a58a8268-4946-4121-8912-f53ba8efa0ea";

// Variable: g_dakisDHEApplication
// Unique instance of the dhe application
var g_dakisDHEApplication = null;

var compared_items_count = 0;
var compared_items;
var signal_timeout = 1500; //milliseconds

var SPECSHEET_CONTENT = "dhe_spec_sheet_sub_content";
var CATALOG = "dhe_catalog";
var CONTENT = 'dhe_content';
var PRODUCT_LINES = 'dhe_product_lines';
var SEARCH = 'dhe_search_';
var CART_CONTENT = 'dhe_cart';
var CART_CONTENT_ITEMS = 'dhe_cart_items_container';
var CART_CUSTOMER_FORM = 'dhe_cart_customer_form';
var CART_PAYPAL_FORM = 'dhe_cart_paypal_form';
var ACCESSORY_MENU = 'dhe_accessories_menu';
//var AD_ROTATOR = 'dhe_ad_rotator';
//var CART_INDICATOR = 'dhe_cart_indicator';

var current_search_panel_id = '';
var current_product_line = '';
var current_history_loc = '';

var g_comparison_manager;
var g_questionnaire;
