//<%--
//********************************************************************
//*-------------------------------------------------------------------
//* Licensed Materials - Property of IBM
//*
//* WebSphere Commerce
//*
//* (c) Copyright IBM Corp.  2007
//* All Rights Reserved
//*
//* US Government Users Restricted Rights - Use, duplication or
//* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
//*
//*-------------------------------------------------------------------
//*
//--%>
dojo.require("dojo.event.*");
dojo.require("dojo.widget.*");
dojo.require("dojo.lang.*");
dojo.require("dojo.io.*");

// This object triggers various Coremetrics events upon user actions. The following four events are supported: 
//    1. pageview: This event is triggered when a new page is loaded, part of a page is refreshed, or an accordion 
//       is opened. 
//    2. productview: This event is triggered when a catalog entry is viewed
//    3. cartview: This event is triggered when a user's cart is updated in any way, such as item being added, item being
//       deleted, quantity being updated, shipping being updated, and payment being updated. 
//    4. element: This event is triggered when filtering criteria or sorting criteria in a fast finder is updated. 
// One and only one global analyticsJS should be created. Therefore, we create this object only when it is not present in 
// in the global namespace. 
if(typeof(analyticsJS) == "undefined" || !analyticsJS || !analyticsJS.topicNamespace){
	analyticsJS = {
		// The storeId this object is used for.
		storeId: 0, 
		
		// The catalogId the user uses
		catalogId: 0, 
		
		// The URL prefix used for invoking JSON views
		urlPath: null, 
		
		// The AccordionTitle will be used in publishStoreAccordionPageView
		
		AccordionTitle: "miniQuickCart",
		// The name of the view that will be used to retrieve JSON data for Coremetrics page view
		jsonPageView: "AnalyticsPageView", 
		
		// The name of the view that will be used to retrieve JSON data for Coremetrics product view
		jsonProductView: "AnalyticsProductView", 
		
		// The name of the view that will be used to retrieve JSON data for Coremetrics element view
		jsonElementView: "AnalyticsElementView", 
		
		// The name of the view that will be used to retrieve JSON data for Coreemtrics cart view
		jsonShopcartView: "AnalyticsShopcartView", 

		// The namespace of any Commerce implementation of Coremetrics event. For example, if an element event 
		// will be of form "/wc/analytics/element". To generalize, each Coremetric topic/event follows this 
		// grammar: <topicNamespace><event name>
		topicNamespace: "/wc/analytics/",
		
		// The name of the page view event
		pageView: "pageview",
		
		// The name of the product view event
		productView: "productview",
		
		// The name of the cart view event
		cartView: "cartview",	
		
		// The name of the element view 
		element: "element",
		
		// The minimum time for which a tooltip has to stay before a product view event is generated.
		tooltipDelay: 3000, //3 seconds
		
		// The list of service requests that should result in a page view. Each item in the list is 
		// an legitimate action ID used in a service. Refer to the wc.service.* for details.
		// Assumption: Each service topic will be of form "modelChanged/<actionID>"
		pageViewActionIdList: [
			"AJAXResetPassword",
			"AjaxAddOrderItem",
			"AjaxDeleteOrderItem",
			"AjaxInterestItemAdd",
			"AjaxInterestItemDelete",
			"AjaxSubmitOrder",
			"AjaxUpdateOrderItem",
			"FastCheckOutOrderCopy",
			"FastCheckOutPrepareOrder",
			"OrderItemShipmentBlockUpdate",
			"AjaxAddOrderItemWithShipingInfo"
		],
		
		// The list of service requests that should result in a cart view event. Each item in the list
		// is an legitimate action ID used in a service. Refer to the wc.service.* for details. 
		// Assumption: Each service topic will be of form "modelChanged/<actionID>".
		cartViewActionIdList: [
			"AjaxAddOrderItem",
			"AjaxDeleteOrderItem",
			"AjaxUpdateOrderItem",
			"AjaxAddOrderItemWithShipingInfo"
		],
		
		// The list of refresh areas this object monitors. If any of the refresh areas refreshes, 
		// the object will re-scan for all the tooltips, as refreshing those areas may result in 
		// new tooltip contents. Each item in the list is a refresh area widget ID. Refer to 
		// wc.widget.RefreshArea for details.
		tooltipRefreshAreaIdList: [
			"StoreAccordian_CheckOut_Widget",
			"StoreAccordian_QuickCart_Widget",
			"StoreAccordian_WishList_Widget", 
			"catalogSearchResultDisplay_Widget", 
			"fastFinderResultsRefreshArea", 
			"EMarketingSpot_Widget"
		],

		// All the fast finder events that should result in an element view. Each item list is a pair. 
		// The first element of a pair is a function name defined in fastFinderJS object. The second 
		// element is the type of the resulted element view. For example, if fastFinderJS.fiterResultsWithBrands()
		// is called, we will generate an element event, whose pageId wil indicate that the element view is 
		// for filtering brands. The third value would be the function that returns user selected value, aka elementId. 
		fastFinderEvents: [
			["filterResultsWithOrderBy", 
			 "orderby",
			 function(selectBoxNode){
			 	var optionText = "";
			 	if(selectBoxNode && selectBoxNode!= null && selectBoxNode.options != null)
			 		optionText = selectBoxNode.options[selectBoxNode.selectedIndex].text;
			 		
				return optionText;
			 }
			],
			["filterResultsWithPrice", 
			 "price slider range", 
			 function(slider){
				 var values = slider.getFormattedValues();
				 return ['[', values.lower, ' - ', values.upper, ']'].join("");
			 }
			],
			["filterResultsWithView", "view change"]
		],
		
		// Each form in the following table contains checkboxes that we need 
		// to capture in element view. 
		fastFinderCheckboxForms: [
			["BrandsForm", "brands"],
			["FeatureNamesForm", "features"]
		], 
		
		publishAnalyticsView: function(jsonViewName, urlParams, publisher){
			// summary: retrieves all the required data for cart view event, and then publishes a cart view event with
			//          with the retrieved data.
			// description: The data is retrieved from the given view. 
			// parameters: 
			//   jsonViewName: name of the view that will be called to get Coremetrics event data
			//   urlParams: The URL parameters passed to the jsonViewName when it is be called.
			//              For example: {storeId: 0, shopperStoreId: 10001}
			//   publisher: A function that takes a single parameter. The parameter will be the
			//              retrieved data. It is up to this function to decide if a Coremetrics view
			//              will be published. This function will be invoked under the context of this
			//              object. For example: 
			//                function(data){this.publishTopic("/wc/analytics/cartview", data);}
			
			var scope = this;
			dojo.io.bind({
				url:        jsonViewName, 
				encoding: 'utf-8',
				mimetype:   "application/json",
				content:    dojo.lang.mixin({storeId:scope.storeId, catalogId:scope.catalogId}, urlParams), 
				error:      function(type, errObj){
					// Hidden tags should not interrupt user interactions. Therefore, no error will be reported to user.
					dojo.debug("error with type = "+type+" and error message: "+errObj.message);
				},
				load:function(type, data, evt){
					publisher.call(scope, data);
				}
			});
		},

		getStoreAccordionPageName: function(){
			// summary: returns the page name for any accorion page. 
			// description: The default implementation returns "store accordion: <page title>"
			return ["store accordion: ", document.getElementsByTagName("title")[0].innerHTML].join("");
		},

		getStoreAccordionPageCategory: function(){
			// summary: returns the page category of store accordion page view. 
			// description: returns "store accordion" by default to indicate that this page view is for store accordion
			// panes.
			return "store accordion";
		},
		getStoreAccordionTitle: function(storeAccordion){
				// summary: returns the Accordion title. 
				
				var scope = this;
				
				dojo.event.connect('after', storeAccordion, 'selectChild', function(child){
					var title =  "miniQuickCart";
					if(child.label.indexOf("miniCheckOut")!=-1)  title =  "miniCheckOut";
					if(child.label.indexOf("miniWishList")!=-1)  title =  "miniWishList";
					if(child.label.indexOf("miniQuickCart")!=-1) title =  "miniQuickCart";
					if(child.label.indexOf("compareTitle")!=-1)  title =  "compareTitle";
					scope.AccordionTitle = title ; 
				});
					
		},
		getStoreAccordionPageViewData: function(AccordionTitle){
			// summary: returns the page view data for viewing store accordion panes
			// description: The default implementation provides page name and category. The page name is obtained
			// by calling this.getStoreAccordionPageName(), and the page category is obtained by calling 
			// this.getStoreAccordionPageCategory().
			// returns: an object with field pagename, and field category. 
			var pageName = this.getStoreAccordionPageName() + ":" + AccordionTitle;
			var pageCategory = this.getStoreAccordionPageCategory();

			return {pagename: pageName, category: pageCategory};
		},

		makeTopic: function(/*String*/topicName){
			// summary: assembles full topic  with the given topic name. 
			// returns: A string of the form <topicNamespace><topicName>
			return [this.topicNamespace, topicName].join("")
		},
		
		publishTopic: function(/*String*/topicName, /*Object*/topicData){
			// summary: publishes a toptic with the given topic data. 
			var topic = this.makeTopic(topicName);
			dojo.debug(["publishing topic: ", topic].join(""));
			dojo.event.topic.publish(topic, topicData);
		},

		
		refreshTooltipPageViewRegistration: function(/*Array*/refreshAreaList){
			// summary: This function registers functions to refresh available tooltips on a page. 
			// description: This function monitors the given refresh areas. If any of the 
			//              given refresh areas refreshes, a registered function will
			//              scan the whole page again to grab any newly added tooltips. if no refres area list
			//              if given, the default list, this.tooltipRefreshAreaIdList will be used. 
			// parameters: 
			//    refreshAreaList: A list of refresh area IDs we want to monitor for refreshing tooltip list.
			if(typeof(refreshAreaList) == "undefined" || refreshAreaList == null){
				refreshAreaList = this.tooltipRefreshAreaIdList;
			}
			
			// The scope this object. We need to explicitly assign it because "this" will always points to 
			// the scope where a closure is *actually* used. 
			var scope = this; 
			dojo.lang.forEach(refreshAreaList, function(refreshAreaId){
				var refreshArea = dojo.widget.byId(refreshAreaId);
				dojo.event.kwConnect({
					srcObj: refreshArea, 
					// setInnerHTML is the last function called when a refresh area is being updated. It is
					// synchronous, so we can ensure after this function, a refresh area is fully updated. 
					srcFunc: "setInnerHTML", 
					adviceFunc: function(){
						dojo.debug([refreshAreaId, "is refreshed. Re-scanning all the tooltips..."].join(" "));
						
						scope.registerTooltipPageView();
					}, 
					once: true
				});
			});
			
			// Updating of category display may result in new tooltips too. However, we care about it only 
			// when there is category display. 
			dojo.lang.forEach(["categoryDisplayJS", "fastFinderJS"], function(objStr){
				var srcObj = dojo.lang.getObject(objStr);
				if(srcObj){
					dojo.event.kwConnect({
						srcObj: srcObj, 
						// This is the function that is last called when category display is being refreshed. 
						srcFunc: "showResults", 
						adviceFunc: function(){
							dojo.debug(objStr+".showResults() is called. Re-scanning all the tooltips...");
							scope.registerTooltipPageView();
						}, 
						once: true
					});
				}
			});
		}, 
		
		getTooltips: function(){
			var tooltips = dojo.lang.reduce(
				["dojo:ToolTipContent", "wc:ToolTipContent"], 
				{}, 
				function(results, type){
					var found = dojo.widget.getWidgetsByType(type);
					dojo.lang.forEach(found, function(tooltip){
						results[tooltip.widgetId] = tooltip;
					});
					
					return results;
				}
			);
			
			var results = []
			for(id in tooltips){
				results.push(tooltips[id]);
			}
			
			return results;
		}, 
		
		_registeredTooltips: {}, 
		
		registerTooltipPageView: function(){
			// summary: This monitors each tooltip. It generates product view if a tooltip stays visible for more than
			//          this.tooltipDelay(default is 3) seconds. 
			// description: One and only one product view will be generated for an open tooltip hanging more than
			//              this.tooltipDelay seconds. After that, no matter how long the tooltip remains visible, 
			//              no new product view will be generated, unless this tooltip re-appears. Each product view
			//              contains productId, productName, type of the view (search or category display), and 
			//              catalogId.			
			
			// Get all the tooltips. Each tooltip is of widget type ToolTipContent (set by CategoryDisplayJS) or
			// wc:ToolTipContent(set directly in JSP files)
			var tooltips = this.getTooltips();
			var scope = this;

			var startTime = 0;
			// Note srcObj does handle list of object in one shot. However, we need to retrieve the productObj of 
			// each tooltip, so we explicitly use a loop. 
			dojo.lang.forEach(tooltips, function(tooltip){
				dojo.debug([tooltip, " is being registered for page view. "].join(""));
				// Register only new tooltips as sometimes dojo event framework can't distinguish
				// two identical tooltip widget
				if(scope._registeredTooltips[tooltip.widgetId]){
					dojo.event.kwDisconnect(scope._registeredTooltips[tooltip.widgetId]);
				}
				
				var eventData = {
					srcObj: tooltip,
					srcFunc: "_onHover",
					adviceFunc: function(e){
						if(startTime < 0){
							return;
						}
						if(startTime == 0){
							startTime = new Date().getTime();
						}else if(new Date().getTime() - startTime >= scope.tooltipDelay){
							var productInfo = tooltip.productObj;
							var catEntryId = productInfo?productInfo.catentryId:tooltip.extraArgs['catalogentryid'];
							scope.publishAnalyticsView(
								scope.jsonProductView,		
								{
									productId: catEntryId,
									storeId: scope.storeId
								}, 
								function(data){
									scope.publishTopic(scope.productView, data);
									startTime = -1;

								}
							);
							// No more event should be generated afterwards. 
							startTime = -1;
						}
					}, 
					once:true
				};
				dojo.event.kwConnect(eventData);
				// We keep the event data so that we can disconnect it later
				scope._registeredTooltips[tooltip.widgetId] = eventData; 
				
				// Enable product view generation since the tooltip will re-appear.
				dojo.event.kwConnect({
					srcObj: tooltip, 
					srcFunc: "_onUnHover",
					
					adviceFunc: function(e){
						startTime = 0;
					},
					once: true
				});
			});
		},

		registerStoreAccordionPageView: function(/*wc.widget.WCStoreAccordion*/storeAccordion){
			// summary: generates page view event for each newly opened accordion pane. 
			// description: An accordion pane is newly opened if its state changes from close to open upon 
			//              being clicked. Otherwise, no page view should be generated. 
			// parameters: 
			//    storeAccordion: The store accordion widget to monitor
			var wasOpen = false;
			var scope = this;

			// Reserve the state of a clicked accordion pane before the accordion is opened. 
			dojo.event.connect('before', storeAccordion, 'selectChild', function(child){
				dojo.debug(["before store accordion selecting child: ", child]);
				wasOpen = child.selected;
			});

			// Make sure an event is open only when the state changes from closed to open.
			dojo.event.connect('after', storeAccordion, 'selectChild', function(child){
					if(child.selected && !wasOpen){
						scope.publishStoreAccordionPageView(scope.AccordionTitle);
					}
			});

			dojo.debug("accordion page view registered");
		},

		publishStoreAccordionPageView: function(/*Object*/pageViewData){
			//summary: publishes a store accordion page view event.
			//parameters: name-value pairs that contain all the page view event data
			var data = this.getStoreAccordionPageViewData(pageViewData);
			if(typeof(pageViewData) != "undefined" && pageViewData != null){
				dojo.lang.mixin(data, pageViewData);
			}
			
			this.publishPageView(data);
		}, 

		publishPageView: function(/*Object*/pageViewData){
			//summary: publishes a page view event
			//parameters: name-value pairs that contain all the page view event data
			var scope = this;
			this.publishAnalyticsView(
				scope.jsonPageView, 
				pageViewData, 
				function(data){
					scope.publishTopic(scope.pageView, data);
				}
			);
		}, 

		registerActionPageViews: function(){
			// summary: generates page views for predefined list of service actions
			// description: We can control which list by setting the value of this.pageViewActionIdList. Each
			// item in the list is an actionId. This function listens to topic "modelChanged/<actionId>", and 
			// generates page view event accordingly.
			var scope = this;

			var fromAccordion = true;
			if(typeof(shipmentPageJS) != "undefined" && shipmentPageJS != null){
				dojo.event.connect("before", shipmentPageJS, "updateCartWait", function(){
						fromAccordion = false;
					});
			}
		
			dojo.lang.forEach(this.pageViewActionIdList, function(actionId){
				dojo.event.topic.subscribe("postRefresh/"+actionId, function(response){
						if(fromAccordion){
							scope.publishStoreAccordionPageView(scope.AccordionTitle);
						}else{
							scope.publishPageView({pagename: document.getElementsByTagName("title")[0].innerHTML});
						}
				});
			});
		},

		registerComparisonPanePageView: function(){
			var scope = this;
			// summary: generates page view for dropping items to comparison pane. 	
			dojo.lang.forEach(["compareDropEventHandler", "deleteFromCompareZone"], function(func){
				dojo.event.connect("after", storeAccordionJS, func, function(e){
					scope.publishStoreAccordionPageView(scope.AccordionTitle);
				});
			});
		
		},

		publishCartView: function(){
			// summary: publishes cart view data.
			var scope = this; 
			this.publishAnalyticsView(
				scope.jsonShopcartView, 
				{storeId:scope.storeId}, 
				function(data){
					scope.publishTopic(scope.cartView, data);
				}
			);
		}, 
		
		registerActionCartViews: function(){
			// summary: generates cart view event if any of the actions defined in this.cartViewActionIdList
			//          happens. 
			// paramters:
			//    cartViewActionIdList: The ID of the DIV that contains cart view data.
			var scope = this;
			dojo.lang.forEach(this.cartViewActionIdList, function(actionId){
				dojo.debug("subscribing to modelChanged/"+actionId);
				dojo.event.topic.subscribe("modelChanged/"+actionId, function(){
					dojo.debug(["cart view with action Id = ", actionId].join(" "));
					scope.publishCartView();
				});
			});
		},

		registerShipmentPageView: function(/*Object*/shipmentController){
			// summary: generates page view event when order shipment is updated. 
			// description: This function will publish page view events when number of shipments changes. The category
			//              of page view event will be "shipment". 
			// parameters: 
			//    shipmentController: This could be any object that contains a function named "numberOfShipmentsChanged". 
			//                        Once that function is called, we will think that shipment is changed. 
			var scope = this;
			dojo.event.connect("after", shipmentController, "numberOfShipmentsChanged", function(shipmentSelection){
				dojo.debug(["shipment changed to ", shipmentSelection.value].join(""));
				scope.publishPageView({pagename:shipmentSelection.value, category: "shipment"});
				shipmentSelection = null; //Avoid circular reference to DOM objects
			});
		},

		registerPaymentPageView: function(/*Object*/paymentController){
			// summary: generates page view event when order payment methods is updated. 
			// description: This function will publish page view events when number of payment methods  changes. 
			//              The category of page view event will be "payment method". 
			// parameters: 
			//    paymentController: This could be any object that contains a function named "setNumberOfPaymentMethods". 
			//                        Once that function is called, we will think that shipment is changed. 
			var scope = this;
			dojo.event.connect("after", 
							   paymentController, 
							   "setNumberOfPaymentMethods", 
							   function(totalPaymentMethods, selection, divName){
								   dojo.debug(["payment number is changed to", selection.value].join(" "));
								   scope.publishPageView({pagename:selection.value, category:"payment method"});
								   selection = null;
							   });
		},

		registerFastFinderEventHandlers: function(/*String*/categoryId){
			// summary: registers handlers that will respond to events in fast finder page. Corresponding
			//          element views will be published. 
			// parameters: 
			//    categoryId: The category ID used by this fast finder.
			var scope = this;
			dojo.lang.forEach(scope.fastFinderEvents, function(pair){
				var func = pair[0];
				var elementType = pair[1];
				var valueFunc = pair[2];
				dojo.event.kwConnect({
					srcObj: fastFinderJS,
					srcFunc: func,
					adviceFunc: function(value){
						
						scope.publishAnalyticsView(
							scope.jsonElementView, 
							{
								elementId: valueFunc? valueFunc(value): value, 
								category: ["Fast Finder:", elementType].join(""), 
								pageId: document.getElementsByTagName("title")[0].innerHTML, 
								pageCategory: categoryId
							}, 
							
							function(data){
								scope.publishTopic(scope.element, data);
							}
						); 
					},
					once:true
				});
			});
		}, 
		
		registerFastFinderFormHandlers: function(){
			// summary: registeres handlers that respond to changes in Fast Finder forms. Element views
			//          will be triggered accordingly.
			var scope = this; 
			dojo.lang.forEach(scope.fastFinderCheckboxForms, function(pair){
				var formName = pair[0]; 
				var category = pair[1]; 
				dojo.lang.forEach(document.forms[formName].elements, function(input){
					dojo.event.kwConnect({
						srcObj: input, 
						srcFunc: "onchange", 
						adviceFunc: function(){
							scope.publishAnalyticsView(
								scope.jsonElementView, 
								{
									elementId: dojo.string.escapeJavaScript(input.value),  
									category: ["Fast Finder: ", dojo.string.escapeJavaScript(category)].join(""), 
									pageId: dojo.string.escapeJavaScript(document.getElementsByTagName("title")[0].innerHTML), 
									pageCategory: "Fast Finder", 
									state: (function(input){
										if(input.checked){
											return "checked";
										}
										
										return "unchecked";
									})(input)
								}, 
								function(data){
									scope.publishTopic(scope.element, data);
								}
							); 
						}
					});
				});
			}); 
		}, 
		
		
		registerSearchResultPageView: function(refreshAreaId, resultInfoDivId){
			// summary: generates page view for each search or search result paging.
			// description: This function assumes that all the search result will be contained in 
			//              a refresh area, and the related page view data is inside a DIV with 
			//              ID = resultInfoDivId
			// parameters:
			//    refreshAreaId: The ID of the refresh area that contains all the search result
			//    resultInfoDivId: The ID of the DIV element that contains page view data.
			var realSearch = true;
			var scope = this;
			
			dojo.lang.forEach(["goToResultPage", "submitJumpToSearch"], 
							  function(func){
								  dojo.event.connect("before", CatalogSearchDisplayJS, func, function(){
									  realSearch = false; 
								  });
							  });
		

			dojo.event.connect("before", CatalogSearchDisplayJS, "submitAdvancedSearch", function(){
				realSearch = true;
			});

			dojo.event.connect("after", dojo.widget.byId(refreshAreaId), "setInnerHTML", function(){
				var resultInfo = eval('('+dojo.byId(resultInfoDivId).innerHTML+')').searchResult;
				var pageViewData = {pagename: "Search Result:"+resultInfo.currentPageNumber};

				if(realSearch){
					pageViewData.searchTerms = resultInfo.searchTerms;
					pageViewData.searchCount = resultInfo.totalResultCount;

				};
				scope.publishPageView(pageViewData);
			});
		},

		loadPagingHandler: function(){
			var scope = this; 
			dojo.addOnLoad(function(){
				var movement = {forward: "page forward", backward: "page backward"};
				var monitoredEvents = [
					["CatalogSearchDisplayJS", "goBack", movement.backward], 
					["CatalogSearchDisplayJS", "goForward", movement.forward], 
					["CatalogSearchDisplayJS.HistoryTracker.prototype", "back", movement.backward], 
					["CatalogSearchDisplayJS.HistoryTracker.prototype", "forward", movement.forward], 
					["fastFinderJS", "goBack", movement.backward], 
					["fastFinderJS", "goForward", movement.forward], 
					["fastFinderJS", "filterResultsWithPrevIndex", movement.backward], 
					["fastFinderJS", "filterResultsWithNextIndex", movement.forward],
					["fastFinderJS.HistoryTracker.prototype", "back", movement.backward], 
					["fastFinderJS.HistoryTracker.prototype", "forward", movement.forward], 
					["MyAccountDisplay", "goBack", movement.backward], 
					["MyAccountDisplay", "goForward", movement.forward], 
					["MyAccountDisplay.HistoryTracker.prototype", "back", movement.backward], 
					["MyAccountDisplay.HistoryTracker.prototype", "forward", movement.forward], 
					["Common", "goBack", movement.backward], 
					["Common", "goForard", movement.forward], 
					["Common.HistoryTracker.prototype", "back", movement.backward], 
					["Common.HistoryTracker.prototype", "forward", movement.forward], 
					["categoryDisplayJS", "goBack", movement.backward], 
					["categoryDisplayJS", "goForward", movement.forward], 
					["categoryDisplayJS.HistoryTracker.prototype", "back", movement.backward], 
					["categoryDisplayJS.HistoryTracker.prototype", "forward", movement.forward],
					["", "filterResultsWithBeginIndex", "paging"]
				]; 
				
				dojo.lang.forEach(monitoredEvents, function(target){
					dojo.debug("target = "+target);
					var srcObj = dojo.lang.getObject(target[0]);
					var srcFunc = target[1];
					var movement = target[2];
					dojo.event.kwConnect({
						srcObj: srcObj, 
						srcFunc: srcFunc, 
						adviceFunc: function(){
							scope.publishPageView(
								{pagename: document.getElementsByTagName("title")[0].innerHTML, 
								 category: movement
								}
							);
						}, 
						once: true
					});
				});
			});
			
		}, 
		loadStoreAccordionHandlers: function(/*String*/storeAccordionId, /*String*/orderInfoDivId){
			// summary: loads all the handlers that will be able to generate Coremetrics tags 
			//          for changes made to a store accordion. The loading is done after the page
			//          is fully loaded. 
			// parameters: 
			//   storeAccordionId: The ID of the store accordion that this function will monitor. 
			//   orderInfoDivId: The ID of the DIV that contains possible cart view data.
			var scope = this;
			dojo.addOnLoad(function(){
				scope.getStoreAccordionTitle(dojo.widget.byId(storeAccordionId));
				scope.registerStoreAccordionPageView(dojo.widget.byId(storeAccordionId));
				scope.registerActionPageViews();
				scope.registerComparisonPanePageView();
				scope.registerActionCartViews(orderInfoDivId);
			});
		},

		loadFastFinderHandlers: function(/*String*/categoryId){
			// summary: convenient function that loads event handlers that generates Coremetrics events
			//          for changes made to fast finder. 
			// description: This function loads the function that handles all the Coremtrics events for changes
			//              made to fast finder. 
			// parameters:
			//    categoryId: The ID of the category under which this fast finder is used.
			var scope = this;
			dojo.addOnLoad(function(){
				scope.registerFastFinderEventHandlers(categoryId);
				scope.registerFastFinderFormHandlers();
			});
		},

		loadSearchResultHandlers: function(/*String*/refreshAreaId, /*String*/resultInfoDivId){
			// summary: loads the function that handles all the Coremetrics event for searching. 
			// parameters: 
			//    refreshAreaId: The ID of the refresh area that contains all the search result. 
			//    resultInfoDivId: The ID of the DIV that contains information about search result. 
			var scope = this;
			dojo.addOnLoad(function(){
				scope.registerSearchResultPageView(refreshAreaId, resultInfoDivId);
			});
		},

		loadTooltipHandlers: function(){
			// summary: loads the function that handles all the Coremetrics event for hovering over tooltip.
			var scope = this;
			dojo.addOnLoad(function(){
				scope.refreshTooltipPageViewRegistration();
				scope.registerTooltipPageView();
			});
		},

		loadShipmentPageView: function(/*Object*/shipmentController){
			// summary: loads the function that handles all the Coremetrics events for changing shipments. 
			// parameters: 
			//    shipmentController: The object that is used to determine if shipment is changed or not. 
			var scope = this;
			dojo.addOnLoad(function(){
				scope.registerShipmentPageView(shipmentController);
			});
		},

		loadPaymentPageView: function(/*Object*/paymentController){
			// summary: loads the function that handles all the Coremetrics events for changing payments. 
			// parameters:
			//     paymentController: the object used to determine if payment  method is changed or not. 
			var scope = this;
			dojo.addOnLoad(function(){
				scope.registerPaymentPageView(paymentController);
			});
		}
	}
}
