
var myIMPC = null;

var CJP = {Version: '1.0'}
CJP.InteractiveMapPageController = Class.create();
CJP.InteractiveMapPageController.prototype = {

	initialize: function() {		
		myIMPC = this;	
		
		/*this.isFF = (/Firefox/.test(navigator.userAgent));
		//this.isFF35 = (/Firefox\/3.5/.test(navigator.userAgent));
		this.isIE = (/MSIE/.test(navigator.userAgent));
		this.isIE7 = (/MSIE 7/.test(navigator.userAgent));
		//this.isMac = (!(/Win32/.test(window.navigator.platform)));
		
		if( (!this.isFF || this.isFF35) && !this.isIE && !this.isIE7){
			var message = 'The web browser you are using will not run our Interactive Maps properly.';
			message += ' Our Help section has further information on the compatible web browsers.\n\n';
			
			if( this.isFF35){
				message += 'Currently the Interactive Map does not function with\n';
				message += 'the latest Firefox 3.5 update. We are working to fix\n';
				message += 'this problem. Thank you for your patience.\n\n';
			}

			message += '================================\n\n';
			message += 'Click OK to view our Help section\n\n';
			message += 'Click CANCEL to go to our Home Page\n\n';
			message += '================================\n';
			
			if(confirm(message)){
				window.top.header.processNavigationRequest('/contentManaged/help/help-MinimumRequirements.aspx');					
			}else{
				window.top.header.processNavigationRequest('/contentManaged/home/home.aspx');			
			}			
		}*/
		
		this.useBlackForMapDots = useBlackForMapDots;
		this.mapDotBlackColorCode = mapDotBlackColorCode;
		this.profiles = new Array();
		
		this.startProfilingRecord('initialize');
		
		//Transitional loading flags for ajax and frame loading statuses
		this.temporaryMapLocationSetLookupKey = '';
		this.temporaryMapXML = null;
		this.temporaryLocationXML = null;
		this.mapIndexPreLoaded = false;
		this.mapIndexLoadingData = false;
		this.mapIndexPostLoadReady = false;
		this.mapDisplayPreLoaded = false;
		this.mapDisplayLoadingData = false;
		this.mapDisplayPostLoadReady = false;
		this.mapLocationDataWaitingProcessing = false;
		this.mapLoaded = false;
		
		//Create references to the frames containing controlled page types
		this.mapDisplayFrame = null;
		this.mapIndexFrame = null;
		
		//Create references to the pages controlled by the map page controller
		this.mapDisplay = null;
		this.mapIndex = null;
		
		//Create the data object constructs for holding data retrieved from the server
		this.mapLocationSets = new CJP.MapLocationSetCollection();
		
		//Create all AJAX requests and register them for all XML document types
		ajaxEngine.registerRequest('GetDefaultMapXML', '/_webservices/mapLocationUtility.asmx/GetDefaultMapXML' );
		ajaxEngine.registerRequest('GetDefaultMapAdvertiserLocationsXML', '/_webservices/mapLocationUtility.asmx/GetDefaultMapAdvertiserLocationsXML' );
		ajaxEngine.registerAjaxObject('interactiveMap', myIMPC);
		ajaxEngine.registerAjaxObject('interactiveMapAdvertiserLocations', myIMPC);	
		
		//Attach all event handlers
		this.attachEventHandlers();	
		
		//Load the default map location set based on the request search parameters
		this.loadDefaultMapLocationSet();
		this.endProfilingRecord('initialize');		
	},
	
	attachEventHandlers: function(){
		this.startProfilingRecord('attachEventHandlers');
		if(typeof document.implementation != "undefined" &&
			document.implementation.hasFeature("HTML",   "1.0") &&
			document.implementation.hasFeature("Events", "2.0") &&
			document.implementation.hasFeature("CSS",    "2.0") ) {
			
			window.addEventListener("load", this.loadPageFrames.bindAsEventListener(this), true);
		}else{
			window.attachEvent("onload", this.loadPageFrames.bindAsEventListener(this), true);
		}
		this.endProfilingRecord('attachEventHandlers');
	},
	
	loadPageFrames:	function(){
		this.startProfilingRecord('loadPageFrames');
		this.mapDisplayFrame = document.getElementById('mapDisplay');
		this.mapIndexFrame = document.getElementById('mapIndex');
		
		this.preloadMapDisplay();
		this.preloadMapIndex();
		this.endProfilingRecord('loadPageFrames');
	},
	
	loadDefaultMapLocationSet: function(){
		this.startProfilingRecord('loadDefaultMapLocationSet');
		var mapID = document.location.search;
		mapID = parseInt(mapID.substring(mapID.indexOf('dr=') + 3));
		
		//Reset the temporary storage variables
		this.temporaryMapLocationSetLookupKey = 'map'+mapID;
		this.temporaryMapXML = document.loadXMLContent(initialMapData);
		this.temporaryLocationXML = document.loadXMLContent(initialMapLocationData);		
		this.mapLocationDataWaitingProcessing = false;
		
		this.mapLocationSets.addMapLocationSet(this.temporaryMapLocationSetLookupKey, this.temporaryMapXML, this.temporaryLocationXML);
		this.temporaryMapLocationSetLookupKey = '';
		this.temporaryMapXML = null;
		this.temporaryLocationXML = null;
		this.mapLocationDataLoadingIsComplete();
		this.endProfilingRecord('loadDefaultMapLocationSet');
	},
	
	loadMap: function(mapID){
		this.startProfilingRecord('loadMap');
		var link = document.location.href;
		link = link.substring(link.indexOf('.com/')+4);
		link = link.substring(0, link.lastIndexOf('dr=')+3);
		link += mapID;
		window.top.header.processNavigationRequest(link);
		this.endProfilingRecord('loadMap');
		
		
		/*var mapLocationSet = this.mapLocationSets.getMapLocationSet('map'+mapID);
		if(mapLocationSet != null){
			this.mapLocationSets.currentMapLocationSet = mapLocationSet;
			this.mapLocationDataLoadingIsComplete();
		}else{
			this.temporaryMapLocationSetLookupKey = 'map'+mapID;
			this.temporaryMapXML = null;
			this.temporaryLocationXML = null;		
			this.mapLocationDataWaitingProcessing = false;
			
			ajaxEngine.sendRequest('GetDefaultMapXML', 'mapID='+mapID);
			ajaxEngine.sendRequest('GetDefaultMapAdvertiserLocationsXML', 'mapID='+mapID);
		}*/		
	},
	
	
	
	
	ajaxUpdate: function(ajaxResponse) {
		//Need to filter for the response type
		switch(ajaxResponse.getAttribute('id')){
			case 'interactiveMap':
				this.temporaryMapXML = ajaxResponse;
				break;
			case 'interactiveMapAdvertiserLocations':
				this.temporaryLocationXML = ajaxResponse;
				break;
		}
		
		if(this.temporaryMapXML != null && this.temporaryLocationXML != null){
			this.mapLocationSets.addMapLocationSet(this.temporaryMapLocationSetLookupKey, this.temporaryMapXML, this.temporaryLocationXML);
			this.temporaryMapLocationSetLookupKey = '';
			this.temporaryMapXML = null;
			this.temporaryLocationXML = null;
			this.mapLocationDataLoadingIsComplete();
		}
	},	
	
	
		
	preloadMapIndex: function(){
		this.startProfilingRecord('preloadMapIndex');
		if(this.mapIndex == null){
			this.mapIndexFrame.contentWindow.initializeInteractiveMapIndex();
			this.mapIndex = this.mapIndexFrame.contentWindow.interactiveMapIndex;
			this.mapIndex.pageController = this;	
		}		
		
		this.mapIndexPreLoaded = false;	
		this.mapIndexLoadingData = false;
		this.mapIndexPostLoadReady = false;
		this.mapIndex.preloadMapIndex();	
		this.endProfilingRecord('preloadMapIndex');
	},
	
	preloadMapDisplay: function(){
		this.startProfilingRecord('preloadMapDisplay');
		if(this.mapDisplay == null){
			this.mapDisplayFrame.contentWindow.initializeInteractiveMapDisplay();
			this.mapDisplay = this.mapDisplayFrame.contentWindow.interactiveMapDisplay;
			this.mapDisplay.pageController = this;
		}		
		
		this.mapDisplayPreLoaded = false;
		this.mapDisplayLoadingData = false;
		this.mapDisplayPostLoadReady = false;
		this.mapDisplay.preloadMapDisplay();
		this.endProfilingRecord('preloadMapDisplay');
	},
			
	postloadPage: function(){	
		//window.status = 'indexPreload='+this.mapIndexPreLoaded+' : displayPreload='+this.mapDisplayPreLoaded+' : dataLoaded='+this.mapLocationDataWaitingProcessing+' : indexPostload='+this.mapIndexPostLoadReady+' : displayPostload='+this.mapDisplayPostLoadReady;	
		if(this.mapIndexPostLoadReady && this.mapDisplayPostLoadReady){
			this.startProfilingRecord('postloadPage');
			this.mapIndex.postloadMapIndex();
			this.mapDisplay.postloadMapDisplay();
			//this.selectDefaultLocation();
			this.endProfilingRecord('postloadPage');
			//alert(this.createProfilingDataMessage());
			this.mapLoaded = true;
		}	
	},
		
	prepareForPostloadPage: function(){
		//window.status = 'indexPreload='+this.mapIndexPreLoaded+' : displayPreload='+this.mapDisplayPreLoaded+' : dataLoaded='+this.mapLocationDataWaitingProcessing+' : indexPostload='+this.mapIndexPostLoadReady+' : displayPostload='+this.mapDisplayPostLoadReady;
		if(this.mapLocationDataWaitingProcessing && this.mapIndexPreLoaded && !this.mapIndexLoadingData){
			this.startProfilingRecord('prepareForPostloadPage');
			this.mapIndexLoadingData = true;
			this.mapIndex.loadCurrentMapLocationsSet();
			this.endProfilingRecord('prepareForPostloadPage');}
		if(this.mapLocationDataWaitingProcessing && this.mapDisplayPreLoaded && !this.mapDisplayLoadingData){
			this.startProfilingRecord('prepareForPostloadPage');
			this.mapDisplayLoadingData = true;
			this.mapDisplay.loadCurrentMapLocationsSet();
			this.endProfilingRecord('prepareForPostloadPage');}
	},
	
	
	mapLocationDataLoadingIsComplete: function(){this.mapLocationDataWaitingProcessing = true;this.prepareForPostloadPage();},
	mapIndexPreLoadComplete: function(){this.mapIndexPreLoaded = true;this.prepareForPostloadPage();},	
	mapDisplayPreLoadComplete: function(){this.mapDisplayPreLoaded = true;this.prepareForPostloadPage();},
	mapIndexPreparedForPostLoad: function(){this.mapIndexPostLoadReady = true;this.postloadPage();},
	mapDisplayPreparedForPostLoad: function(){this.mapDisplayPostLoadReady = true;this.postloadPage();},
	
	
	defaultLocationRequested: function(){return (document.location.search.indexOf('businessLocationID=') > -1);},
	
	selectDefaultLocation: function(){
		var s = document.location.search;
		if(myIMPC.defaultLocationRequested()){
			var locationID = parseInt(s.substr(s.indexOf('businessLocationID=') + 19));
			var location = myIMPC.mapLocationSets.currentMapLocationSet.locations.getLocationByID(locationID);
						
			if( s.toLowerCase().indexOf('nohighlight') > -1 ){
				if(!location.category.categoryIsExpanded()){
					myIMPC.mapIndex.layoutManager.switchCategoryExpandedState(location.category);
				}
			}else{
				myIMPC.selectLocationFromMapIndex(location);
				myIMPC.selectLocationFromMapDisplay(location);
			}
		}
	},
	
	selectLocationFromMapDisplay: function(location){
		this.mapDisplay.layoutManager.disablePopMenuRollover = true;
		//Check if the location's category is expanded
		if(!location.category.categoryIsExpanded()){
			this.mapIndex.layoutManager.switchCategoryExpandedState(location.category);
		}
		
		//Check if the location's advertiser is collapsing locations and if the locations are collapsed
		if(location.advertiser.collapseLocationInWebsite && !location.advertiser.locationsAreExpanded()){
			this.mapIndex.layoutManager.switchAdvertiserLocationExpandedState(location.advertiser);
		}
	
		//Deselect all locations then select the current location
		this.mapLocationSets.currentMapLocationSet.locations.deselectAll();
		location.select();
		
		//Determine the page element to use as a scroll reference point
		var operativeContainer = location.LocationContainer;
		var relativeScrollItem = null;
		var operativeContainerOffsetTop = null;
		
		//Scroll the page based on the scroll reference point's relation to the visible content
		var categoryContainer = location.category.LocationContainer;
		operativeContainerOffsetTop = operativeContainer.offsetTop + ((location.advertiser.collapseLocationInWebsite && location.advertiser.AdvertiserLocationsContainer != null)?operativeContainer.offsetParent.offsetTop:0);
		relativeScrollItem = (parseInt(operativeContainerOffsetTop)-parseInt(categoryContainer.scrollTop) < 0) ? operativeContainer.previousSibling : operativeContainer.nextSibling;
		relativeScrollItem = (relativeScrollItem == null) ? operativeContainer : relativeScrollItem;
		var itemHidden = ( ((parseInt(operativeContainerOffsetTop)+parseInt(operativeContainer.offsetHeight))-parseInt(categoryContainer.scrollTop) > parseInt(categoryContainer.offsetHeight)) || (parseInt(operativeContainerOffsetTop)-parseInt(categoryContainer.scrollTop) < 0) );
		
		var loopLimiter = 0;
		while(itemHidden && loopLimiter < 10){
			//Schitzophrenic bit of code here....tells the relative item to scrollIntoView from the top and bottom alternating based on the modulus of loopLimiter
			//This is because sometimes IE can't decide if an item is in view or not if it is really close to a scroll bar

			relativeScrollItem.scrollIntoView( ((loopLimiter % 2) == 1) );
			operativeContainerOffsetTop = operativeContainer.offsetTop + ((location.advertiser.collapseLocationInWebsite && location.advertiser.AdvertiserLocationsContainer != null)?operativeContainer.offsetParent.offsetTop:0);
			itemHidden = ( ((parseInt(operativeContainerOffsetTop)+parseInt(operativeContainer.offsetHeight))-parseInt(categoryContainer.scrollTop) > parseInt(categoryContainer.offsetHeight)) || (parseInt(operativeContainerOffsetTop)-parseInt(categoryContainer.scrollTop) < 0) );
			loopLimiter++;
		}
	},
	
	selectLocationFromMapIndex: function(location){
		this.mapDisplay.layoutManager.showSingleLocation = true;
		this.mapDisplay.layoutManager.disablePopMenuRollover = true;
		
		if(location.areaMaps[this.mapDisplay.layoutManager.zoom.currentZoomLevel.id].click != null){
			location.areaMaps[this.mapDisplay.layoutManager.zoom.currentZoomLevel.id].click();
		}else{
			var eventObject = document.createEvent('MouseEvents');
			eventObject.initEvent('click', true, true);
			location.areaMaps[this.mapDisplay.layoutManager.zoom.currentZoomLevel.id].dispatchEvent(eventObject);
		}
	
		//Deselect all locations then select the current location
		this.mapLocationSets.currentMapLocationSet.locations.deselectAll();
		location.select();
	},
	
	
	reloadMap: function(mapID){
		this.mapLocationSets.currentMapLocationSet.map.hideMap();
		this.mapLocationSets.currentMapLocationSet.locations.hideLocations();
		this.loadMap(mapID);
		
		this.preloadMapDisplay();
		this.preloadMapIndex();
	},
	
	
	
	
	
	startProfilingRecord: function(operationName){
		this.profiles[this.profiles.length] = new CJP.SystemProfile(operationName);
	},
	endProfilingRecord: function(operationName){
		for(var i = this.profiles.length - 1; i > -1 ; i--){
			if(this.profiles[i].operationName == operationName){
				this.profiles[i].addEndTimeStamp();
				break;
			}
		}
		
		//alert(this.createProfilingDataMessage());
	},
	createProfilingDataMessage: function(){
		var profilingDataMessage = '';
		for(var i = 0; i < this.profiles.length; i++){
			profilingDataMessage += this.profiles[i].operationName + ' -- ' + this.profiles[i].getStartTimeString() + ' -- ' + this.profiles[i].getEndTimeString() + '\n';
		}
		return profilingDataMessage;
	}
};



CJP.SystemProfile = Class.create();
CJP.SystemProfile.prototype = {

	initialize: function(operationName, inset) {
		this.operationName = operationName;
		this.startTime = new Date();
		this.endTime = this.startTime;
	},
	
	addEndTimeStamp: function(){
		this.endTime = new Date();
	},
	
	getStartTimeString: function(){
		return this.startTime.getMinutes() + ':' + this.startTime.getSeconds() + ':' + this.startTime.getMilliseconds();
	},
	
	getEndTimeString: function(){
		return this.endTime.getMinutes() + ':' + this.endTime.getSeconds() + ':' + this.endTime.getMilliseconds();
	}
};
	
	
		

