var locationsModuleObject = Class.create({
	initialize: function(el){
		window.location.hash = '';
	 	this.properties = eHA.elementToObjectLiteral(el);
	 	this.el = $(el);
	 	if($$("div.locations.assetid-"+this.properties.assetid)[0]){
	 		this.locationsDiv = $$("div.locations.assetid-"+this.properties.assetid)[0];
	 		this.locationsDiv.update(eHA.locations.preloader);
	 		this.loadData(function(){
	 			this.createForm();
	 			this.build();
	 			this.selectPage(1);
	 		}.bind(this),{locations:'true'});
	 	}else{
	 		eHA.log.create("no locations for this module");
	 	}
	},
 	loadData: function(callback,packedargs,waitForAJAX){
		if(typeof this.ajaxRequest!=="undefined" && this.isLoading){
			this.ajaxRequest.abort();
			eHA.log.create("aborting previous ajax request",2);
		}
		if(typeof waitForAJAX==="undefined"){
			var waitForAJAX = false;
		}
 		var parameters = {
 			childpagename: eHA.Site+"/eHA_Module_C/"+eHA.Site+"/Locations/json",
 			site: eHA.Site,
 			c: "eHA_Module_C",
 			cid: this.properties.assetid,
 			pagename: eHA.Site+"_default_Wrapper"
 		};
 		var formPackedargs = {};
 		if(typeof this.form!=="undefined"){
 			formPackedargs = this.form.serialize(true);
 			eHA.log.create("packedargs from form = "+Object.toQueryString(formPackedargs),3);
 		}
 		if(typeof packedargs!=="undefined"){
 			Object.extend(formPackedargs,packedargs);
 			parameters.packedargs = Object.toQueryString(formPackedargs);
 		}
 		var localObj = this;
 		var URL = "/cs/Satellite";
 		this.isLoading = true;
		this.ajaxRequest = new Ajax.Request(URL,
			{
				method:'get',
				parameters: parameters,
				onCreate: function(){
					if(waitForAJAX){
						// show loading graphic because there will now be a delay
						localObj.locationsDiv.down("div.pageContainer").update(eHA.locations.preloader);
					}
					eHA.log.create(parameters.cid+": AJAX request for JSON created", 3);
				},
				onSuccess: function(transport){
					eHA.log.create(parameters.cid+": AJAX request for JSON succeeded", 3);
				},
				onComplete: function(transport){
					this.isLoading = false;
					// add transport.responseText to this.properties
					eHA.log.create(parameters.cid+": AJAX request for JSON completed", 3);
					if(transport.responseText){
						eHA.log.create(parameters.cid+": attempting to evaluate JSON and add to locationsModuleObject", 3);
						try{
							var metaData = transport.responseText.evalJSON(true);
							Object.extend(localObj.properties,metaData.configuration);
							localObj.properties.complete = true;
							if(typeof metaData.locations!=="undefined"){
								if(typeof localObj.data==="undefined"){
									localObj.data = {};
								}
								Object.extend(localObj.data,metaData.locations);
							}
						}catch(err){
							eHA.log.create(parameters.cid+":"+err.name+" - "+err.message, 1);
						}
					}else{
						eHA.log.create(parameters.cid+": problem with transport.responseText onComplete", 1);
					}
					if(typeof callback!=="undefined" && callback){
						callback();
					}
				}.bind(this),
				onFailure: function(){
					eHA.log.create(parameters.cid+": AJAX request for JSON resulted in failure", 1);
				}
			});
 	},
 	
	createMap: function(){
 		try{
 			if(typeof GMap2 !=="undefined" && GBrowserIsCompatible()){
 				eHA.log.create("beginning map creation",3);
 				if(typeof this.googleMapDiv!=="undefined"){
 					this.googleMapDiv.update();
 				}else{
 					this.googleMapDiv = new Element("div",{id:"google_map"+this.properties.assetid,className:"GoogleMap"}).setStyle({height:"400px"});
 				}
 				this.el.insert({before:this.googleMapDiv});
 				this.map = new GMap2(this.googleMapDiv,{backgroundColor:"#02254a"});
 				this.geocoder = new GClientGeocoder();
 				
 				// add just the locations on the current page
 				var startItem=(this.currentPageNumber-1)*this.properties.itemsPerPage+1; //add one because index starts at 1
 				var endItem = parseInt(this.properties.itemsPerPage,10)+parseInt(startItem,10)-1; 
 				if(endItem>this.properties.totalItems){
 					endItem = this.properties.totalItems;
 				}
 				
 				// create a set of bounds for these points
 				this.bounds = new GLatLngBounds();
 				this.markers = {};
 				for(var i=startItem;i<(endItem+1) && typeof this.data["item"+i]!=="undefined";i++){
 					this.data["item"+i].parent = this;
 					var thisLoc = this.data["item"+i];
 					if(typeof thisLoc.building.latitude!=="undefined" && typeof thisLoc.building.longitude!=="undefined"){
 						this.addMarker(new GLatLng(thisLoc.building.latitude,thisLoc.building.longitude),thisLoc);
 					}else{
 						var thisAddress = thisLoc.building.address+" "+thisLoc.building.city+" "+thisLoc.building.state+" "+thisLoc.building.zip;
 						var locationHTML = eHA.locations.locationHTML(thisLoc);
 						this.geocoder.getLatLng(thisAddress,function(point,thisLoc){
 							this.addMarker(point,thisLoc);
 						}.bindAsEventListener(this,thisLoc));
 					}
 				}
 				Event.observe(window,"beforeunload", GUnload);
 			}else{
 				eHA.log.create("can't create Google Map",3);
 			}
 		}catch(err){
 			eHA.log.create("problem creating google map for locations module ("+this.properties.assetid+"), "+err.message,1);
 		}
	},
	/**
	 * adds a marker to the google map, also checks to make sure tabs are added to correct markers
	 * @function
	 * @param {GLatLng} point
	 */
	addMarker: function(point,thisLoc){
		 try{
			 eHA.log.create("adding a marker",3);
			 if(typeof point!=="undefined" && point){
				 var pointID = "id"+point.x+""+point.y;
				 eHA.log.create("Adding marker for this Address, pointID: "+pointID, 3);
				 
				 var thisMarker = new GMarker(point)
				 this.map.addOverlay(thisMarker);
				 
				 // create object to contain unique markers (use pointID to identify them)
				 if(typeof this.markers[pointID]==="undefined"){
					 this.markers[pointID] = thisMarker;
				 }
				 
				 // add point to bounds and set zoom & center
				 this.bounds.extend(point);
				 this.zoomFit();
				 
				 // this adds a Control for every point.  not ideal
				 this.map.addControl(new GLargeMapControl());
				 
				 // create an array of HTML tabs for each unique marker
				 if(typeof this.markers[pointID].tabs==="undefined"){
					 this.markers[pointID].tabs = new Array();
				 }
				 var locationHTML = eHA.locations.locationHTML(thisLoc);
				 this.markers[pointID].tabs.push(new GInfoWindowTab(thisLoc.title.strip().substring(0,10)+"..",locationHTML));
				 
				 // add array of tabs to each marker.  
				 //this allows multiple locations per building / address
				 thisMarker.bindInfoWindowTabs(this.markers[pointID].tabs);
			 }else{
				 eHA.log.create("Google Maps can't add marker for this Address", 1);
			 }
		 }catch(err){
			 eHA.log.create("problem adding markers to Google Map ("+this.properties.assetid+"), "+err.message,1);
		 }
	},
	/**
	 * sets zoom and center to current #bounds value on this map
	 * @function
	 */
	zoomFit: function(){
		try{
			var newZoom = this.map.getBoundsZoomLevel(this.bounds);
			var newCenter = this.bounds.getCenter();
			if(newZoom>13){ newZoom = 13;	}
			this.map.setCenter(newCenter,newZoom);
		}catch(err){
			eHA.log.create("problem zooming map ("+this.properties.assetid+"), "+err.message,1);
		}
	},
 	/**
	 * calculates page data, creates page container, selects first page
	 * @function
	 */
	build: function(){
		try{
			// clear old pages & navigation
 			if(this.locationsDiv.select("div.pageMeta")[0]){
 				this.locationsDiv.select("div.pageMeta").invoke("remove");
 			}
			if(this.locationsDiv.down("div.pageContainer")){
				this.locationsDiv.down("div.pageContainer").remove();
			}
			if(this.locationsDiv.down("div.pagination")){
				this.locationsDiv.down("div.pagination").remove();
			}
			if(this.locationsDiv.down("img.preloader")){
				this.locationsDiv.down("img.preloader").remove();
			}
			
			var itemLimit = this.properties.totalItems;
			var pageLimit = 1;
			
			if(typeof this.properties.itemsPerPage!=="undefined"){
				itemLimit = this.properties.itemsPerPage;
				pageLimit = Math.ceil(this.properties.totalItems/this.properties.itemsPerPage);
			}
			
			if(this.properties.showTotal && this.properties.showTotal!=="false"){
				this.locationsDiv.insert({bottom:new Element("div",{className:"pageMeta"}).update("<p><strong>"+this.properties.totalItems+"</strong> Locations found</p>")});
			}
			
			this.locationsDiv.insert({bottom:new Element("div",{className:"pageContainer"})});
			
			this.properties.numberOfPages = pageLimit;
			this.currentPageNumber = 0; // to ensure that jumps from page 1 to 1 always work on build
			//this.selectPage(1);
			
		}catch(err){
			eHA.log.create("problem building pages for locations module ("+this.properties.assetid+"), "+err.message,1);
		}
	},
 	getData: function(startItem,endItem,pageNumber){
		try{
			var dataOK = true;
			var immediatePageOK = true;
			var checkStartItem = startItem;
			var checkEndItem = endItem;
			if(this.properties.itemsPerPage>0){
				// expand returned results to 3 pages if possible (previous page, current page, next page)
				if((checkStartItem+2*this.properties.itemsPerPage)<this.properties.totalItems){
					// set checkEndItem to 2 pages ahead (current page plus one)
					checkEndItem = (checkStartItem+2*this.properties.itemsPerPage);
				}else{
					// set checkEndItem as far ahead as possible
					checkEndItem = parseInt(this.properties.totalItems,10)+parseInt(1,10);
				}
				if(checkStartItem>this.properties.itemsPerPage){
					// set checkStartItem to 1 page back
					checkStartItem = checkStartItem - this.properties.itemsPerPage;
				}
			}
			eHA.log.create("checking items "+checkStartItem+" to "+checkEndItem,3);
			for(var i=checkStartItem;i<checkEndItem;i++){
				if(typeof this.data!=="undefined" && typeof this.data["item"+i]!=="undefined"){
					// data is ok, don't affect boolean
				}else{
					if(i>=startItem && i<=endItem){
						immediatePageOK = false;
					}
					dataOK=false;
				}
			}
			
			if(!immediatePageOK){
				eHA.log.create("need to delay page creation",2);
				this.loadData(function(){
					this.createPage(pageNumber,false);
					if(this.properties.showMap && this.properties.showMap!=="false"){
						this.createMap();
					}
				}.bind(this),{
					startItem:startItem,
					locations:'true'
				},true);
			}else{
				eHA.log.create("no need to delay page creation",3);
				if(this.properties.showMap && this.properties.showMap!=="false"){
					this.createMap();
				}
				if(!dataOK){
					eHA.log.create("prefetching data for neighboring pages",3);
					this.loadData(false,{
						startItem:startItem,
						locations:'true'
					});
				}
			}
			
			return immediatePageOK;
		}catch(err){
			eHA.log.create("problem evaluating page data "+err.toString(),1);
		}
 	},
 	createPage: function(pageNumber,checkData){
 		if(typeof checkData==="undefined"){
 			var checkData = true;
 		}
		if(this.locationsDiv.down("img.preloader")){
			this.locationsDiv.down("img.preloader").remove();
			eHA.log.create("removed loading graphic",3);
		}
		eHA.log.create("attempting to create page "+pageNumber+".  "+(checkData?"Will":"Will not")+" check data",3);
		var startItem=(pageNumber-1)*this.properties.itemsPerPage+1; //add one because index starts at 1
		var endItem = parseInt(this.properties.itemsPerPage,10)+parseInt(startItem,10)-1; 
		if(endItem>this.properties.totalItems){
			endItem = this.properties.totalItems;
		}
		
		if(this.properties.totalItems>=startItem){
			// create new pagination with selected page properly selected
			if(this.properties.showPagination && this.properties.showPagination!=="false"){
				this.createPagination(pageNumber);
			}
			
			// check to see if requesting more data from server is necessary
			var immediatePageOK = false;
			if(checkData){
				immediatePageOK = this.getData(startItem,endItem,pageNumber);
			}
			if(immediatePageOK || !checkData){
				eHA.log.create("proceeding with page creation",3);
				try{
					var thisUL = new Element("ul",{className:"page page"+pageNumber,style:"display:none;"});
					for(var i=startItem;i<(endItem+1) && typeof this.data["item"+i]!=="undefined";i++){
						this.data["item"+i].parent = this;
						var thisLoc = this.data["item"+i];
						var locationHTML  = eHA.locations.locationHTML(thisLoc);
						var thisLI = new Element("li",{className:"location assetid-"+this.data["item"+i].assetid}).update(locationHTML);
						thisUL.insert({bottom:thisLI});
					}
					this.locationsDiv.down("div.pageContainer").insert({bottom:thisUL});
					thisUL.appear({duration:eHA.locations.duration,afterSetup:function(){
						this.adjustPageContainer();
					}.bind(this)});
				}catch(err){
					eHA.log.create("problem with page creation! "+err.toString(),1);
				}
			}
		}else{
			eHA.log.create("requested page, "+pageNumber+", for locations module ("+this.properties.assetid+") is out of range!  Proceeding to page 1 instead",2);
			this.selectPage(1);
		}
	},
	adjustPageContainer: function(){
		var pageDimensions = this.locationsDiv.down("div.pageContainer ul.page").getDimensions();
		new Effect.Morph(this.locationsDiv.down("div.pageContainer"),{
			style:{
				height:pageDimensions.height+"px"
			},
			duration: 0.1
		});
	},
 	/**
	 * creates pagination for the location pages.  visible page numbers roam for simplicity, always showing 3 pages max, prev & next, first & last
	 * @function
	 * @parameter {int} selectedPage
	 * @example
	 * output:
	 * "|< < 1 2 3 > >|"
	 * "|< < 2 3 4 > >|"
	 * "|< < 9 10 12 > >|"
	 */
	createPagination: function(selectedPage){
		try{
			if(typeof selectedPage==="undefined"){
				selectedPage = 1;
			}
			var startPage = Math.round(selectedPage - ((eHA.locations.maxPagesToShow-1)/2));
			if(startPage<1){
				startPage = 1;
			}
			// clear old pagination
			if(this.locationsDiv.down("div.pagination")){
				this.locationsDiv.down("div.pagination").remove();
			}
			
			var paginationDiv = new Element("div",{className:"pagination"});
			var paginationUL = new Element("ul");
			
			var firstLink = new Element("a",{href:""}).update("First").observe("click",function(event){
				event.stop();
				this.selectPage(1);
			}.bind(this));
			var firstLI = new Element("li",{className:"first"}).update(firstLink);
			paginationUL.insert({bottom:firstLI});
			
			var prevLink = new Element("a",{href:""}).update("Previous").observe("click",function(event){
				event.stop();
				if(this.locationsDiv.down("div.pagination li.sel a")){
					var selectedPage = this.locationsDiv.down("div.pagination li.sel a").innerHTML;
					if(selectedPage>1){
						this.selectPage(selectedPage - 1);
					}
				}
			}.bind(this));
			var prevLI = new Element("li",{className:"previous"}).update(prevLink);
			paginationUL.insert({bottom:prevLI});
			
			for(var i=startPage;i<=this.properties.numberOfPages && i<(parseInt(startPage,10)+parseInt(eHA.locations.maxPagesToShow,10));i++){
				var pageLink = new Element("a",{href:""}).update(i).observe("click",function(event){
					event.stop();
					this.selectPage(event.element().innerHTML);
				}.bind(this));
				var pageLIclass = "pageButton"+i;
				if(typeof selectedPage!=="undefined" && i===parseInt(selectedPage,10)){
					pageLIclass += " sel";
				}
				var pageLI = new Element("li",{className:pageLIclass}).update(pageLink);
				paginationUL.insert({bottom:pageLI});
			}
			
			var nextLink = new Element("a",{href:""}).update("Next").observe("click",function(event){
				event.stop();
				if(this.locationsDiv.down("div.pagination li.sel a")){
					var selectedPage = this.locationsDiv.down("div.pagination li.sel a").innerHTML;
					if(selectedPage<this.properties.numberOfPages){
						this.selectPage(parseInt(selectedPage,10) + 1);
					}
				}
			}.bind(this));
			var nextLI = new Element("li",{className:"next"}).update(nextLink);
			paginationUL.insert({bottom:nextLI});
			
			var lastLink = new Element("a",{href:""}).update("Last").observe("click",function(event){
				event.stop();
				this.selectPage(this.properties.numberOfPages);
			}.bind(this));
			var lastLI = new Element("li",{className:"last"}).update(lastLink);
			paginationUL.insert({bottom:lastLI});
			
			paginationDiv.update(paginationUL);
			this.locationsDiv.insert({bottom:paginationDiv});
		}catch(err){
			eHA.log.create("problem creating pagination for locations module ("+this.properties.assetid+"), "+err.message,1);
		}
	},
 	readQueryString:function(queryObject){
 		var oldFormOptions={};
 		if(typeof this.oldFormOptions!=="undefined"){
 			oldFormOptions = this.oldFormOptions;
 		}
 		var pageNumber = queryObject.page;
 		delete queryObject.page;
 		this.oldFormOptions = queryObject;
 		
 		// if query string (without page number) is different, must execute search and change page
 		// later by using a callback
 		if(Object.toQueryString(oldFormOptions)!==Object.toQueryString(queryObject)){
 			this.executeForm(queryObject,function(){
 				this.changePage(pageNumber);
 				this.populateForm();
 			}.bind(this));
 		}else{
 			// otherwise, just change page number
 			this.changePage(pageNumber);
 		}
 		
 		// if there is no form and no pagination, remove hash
 		if(this.noHash){
 			SWFAddress.setValue("");
 		}
 	},
 	selectPage: function(pageNumber){
 		
 		if((!this.properties.showPagination || this.properties.showPagination==="false") && (typeof this.form!=="undefined")){
 			this.noHash = true;
 		}else{
 			this.noHash = false;
 		}
 		
 		// get queryString from forms, add/change page number
 		var formOptions = this.form.serialize(true);
 		Object.extend(formOptions,{page:pageNumber,locations:'true'});
 		if(this.executions===1){ // selectPage is called once onload, so checking for 1 instead of 
 			// this is the first time the form is being executed, setValue of hash to the default
 			// form options.
 			SWFAddress.setValue("/"+this.properties.assetid+"/?"+Object.toQueryString(this.defaultFormOptions));
 		}
 		this.executions++;
 		SWFAddress.setValue("/"+this.properties.assetid+"/?"+Object.toQueryString(formOptions));
 	},
	changePage: function(pageNumber){
		try{
			if(typeof this.currentPageNumber!=="undefined" && this.currentPageNumber===pageNumber){
				eHA.log.create("requested page, "+pageNumber+", is already showing",3);
			}else{
				this.currentPageNumber = pageNumber;
				if(this.locationsDiv.select("ul.page")[0]){
					this.locationsDiv.select("ul.page").invoke("remove");
				}
				this.createPage(pageNumber);
			}
			
			// create new pagination with selected page properly selected
			if(this.properties.showPagination && this.properties.showPagination!=="false"){
				//this.createPagination(pageNumber);
			}
		}catch(err){
			eHA.log.create("problem selecting page for locations module ("+this.properties.assetid+"), "+err.message,1);
		}
	},
 	executeForm: function(queryObject,callback){
 		eHA.log.create("executing location module search form",3);
		if(typeof this.data!=="undefined"){
			delete this.data;
			eHA.log.create("clearing old location module data",3);
		}
		
		this.loadData(function(){
			this.build();
			if(typeof callback!=="undefined"){
				callback();
			}
		}.bind(this), queryObject,true);
 	},
 	populateForm: function(){
 		for(option in this.oldFormOptions){
 			if(typeof this.form[option]!=="undefined"){
 				this.form[option].setValue(this.oldFormOptions[option]);
 			}
 		}
 	},
	createForm: function(){
		try{
			this.form = new Element("form",{method:"",action:"",name:"assetid-"+this.properties.assetid,id:"assetid-"+this.properties.assetid});
			
			var formContents = "";
			
			if(this.properties.showCategoryDropdown && this.properties.showCategoryDropdown!=="false"){
				formContents += "<div class='categoryDropdown'>";
				formContents += "<label for='categoryDropdown-"+this.properties.assetid+"'>Category:</label>";
				formContents += "<select id='categoryDropdown-"+this.properties.assetid+"' name='category'>";
				formContents += "<option value='null'>All</option>";
				for(var i=0;i<this.properties.category.length;i++){
					formContents += "<option value='"+this.properties.category[i].id+"'>"+this.properties.category[i].name+"</option>";
				}
				formContents += "</select>";
				formContents += "</div>";
			}
			if(this.properties.showTitleSearch && this.properties.showTitleSearch!=="false"){
				formContents += "<div class='titleSearch'>";
				formContents += "<label for='titleSearch-"+this.properties.assetid+"'>Title:</label><input type='text' id='titleSearch-"+this.properties.assetid+"' name='title' />";
				formContents += "</div>";
			}
			if(this.properties.showKeywordSearch && this.properties.showKeywordSearch!=="false"){
				formContents += "<div class='keywordSearch'>";
				formContents += "<label for='keywordSearch-"+this.properties.assetid+"'>Keywords:</label><input type='text' id='keywordSearch-"+this.properties.assetid+"' name='keyword' />";
				formContents += "</div>";
			}
			if(this.properties.showSortOrder && this.properties.showSortOrder!=="false"){
				formContents += "<div class='sortOrder'>";
				formContents += "<label for='sortOrder-"+this.properties.assetid+"'>Sort Order:</label>";
				formContents += "<select id='sortOrder-"+this.properties.assetid+"' name='sortOrder'>";
				formContents += "<option value='page_title.ascending'>Alphabetical</option>";
				formContents += "<option value='page_title.descending'>Reverse Alphabetical</option>";
				formContents += "<option value='campus.ascending'>by Campus</option>";
				formContents += "</select>";
				formContents += "</div>";
			}
			
			if(formContents.length>0){
				formContents += "<div class='submit'>";
				formContents += "<input type='submit' class='submit' name='submit' id='submit-"+this.properties.assetid+"' value='Submit' />";
				formContents += "<input type='reset' class='reset' name='reset' id='reset-"+this.properties.assetid+"' value='Reset' />";
				formContents += "</div>";
				
				this.form.update(formContents);
				
				$$("div.locationsModule.assetid-"+this.properties.assetid+" h3")[0].insert({after:this.form});
				
 		 		this.defaultFormOptions = this.form.serialize(true);
 				this.defaultFormOptions.page = 1;
 				this.defaultFormOptions.locations = 'true';
 				this.executions = 0;

				
 				this.form.observe("submit",function(event){
 					event.stop();
 					eHA.log.create(this.properties.assetid+": form submitted",3);
 					this.selectPage(1);
 				}.bind(this));
				
			}
			
		}catch(err){
			eHA.log.create("problem creating locations module form, "+this.properties.assetid+".  "+err.message,1);
		}
	}
});



/**
 * manages data and functions for embedded Google Maps in Location Detail pages
 * @requires inclusion of google maps js
 * @namespace
 */
eHA.locations = {
	/**
	 * @function
	 */
	init: function(){
		if($$("div.locationsModule")[0]){
			this.preloader = new Element("img",{src:eHA.resourcepath+"images/wide-preloader.gif",alt:"please wait",className:"preloader"});
			this.locationsModuleObjects = {};
			$$("div.locationsModule").each(function(element){
				var locationsModuleID = eHA.elementToObjectLiteral(element).assetid;
				this.locationsModuleObjects[locationsModuleID] = new locationsModuleObject(element);
			}.bind(this));
			
			// adding SWFaddress listeners
			
			 // EXTERNAL_CHANGE is used for back button
			 SWFAddress.addEventListener(SWFAddressEvent.EXTERNAL_CHANGE, function(event){
					eHA.log.create("SWFAddress event: "+Object.toJSON(event), 3);
					if(typeof event.pathNames!=="undefined"){
						if(typeof this.locationsModuleObjects[event.pathNames[0]]!=="undefined" && typeof event.parameters!=="undefined"){
							this.locationsModuleObjects[event.pathNames[0]].readQueryString(event.parameters);
						}
					}
				 }.bind(this));

			 SWFAddress.addEventListener(SWFAddressEvent.INTERNAL_CHANGE, function(event){
					eHA.log.create("SWFAddress event: "+Object.toJSON(event), 3);
					if(typeof event.pathNames!=="undefined"){
						if(typeof this.locationsModuleObjects[event.pathNames[0]]!=="undefined" && typeof event.parameters!=="undefined"){
							this.locationsModuleObjects[event.pathNames[0]].readQueryString(event.parameters);
						}
					}
				 }.bind(this));
			 
		}
	},
	dateFormat: "yyyy-MM-dd HH:mm:ss",
	maxPagesToShow: 3,
	duration: 0.5,
	/**
	 * makes sure that rendermode is added to URL
	 * @function
	 * @returns theURL
	 */
	formatURL: function(obj){
		var theURL = obj.url;
		var pageQueryParams = window.location.href.toQueryParams();
		if(typeof pageQueryParams.rendermode!=="undefined"){
			if(theURL.indexOf("?")!==-1){
				var urlQueryParams = theURL.toQueryParams();
				Object.extend(urlQueryParams,{rendermode:pageQueryParams.rendermode});
				theURL = theURL.split("?")[0] +"?"+ Object.toQueryString(urlQueryParams);
			}
			theURL = theURL +"?"+ Object.toQueryString({rendermode:pageQueryParams.rendermode});
		}
		return theURL;
	},
	locationHTML: function(obj){
		var thisURL = this.formatURL(obj);
		var locationHTML = "";
		if(obj.parent){
			if((obj.parent.properties.showThumbnails && obj.parent.properties.showThumbnails!=="false") && typeof obj.thumbnailURL!=="undefined"){
				locationHTML += "<div class='page_body_media'><img src='"+obj.thumbnailURL+"' alt='"+obj.title.strip()+"' /></div>";
			}
		}
		locationHTML += "<div class='vcard'>";
		locationHTML += "<div class='fn'><a href='"+thisURL+"'>"+obj.title.strip()+"</a></div>";
		locationHTML += (typeof obj.building.title!=="undefined")?"<div class='adr'><div class='org'>"+obj.building.title.strip()+"</div>":"";
		locationHTML += "<div class='street-address'>";
		locationHTML +=	(typeof obj.building.address!=="undefined")?"<span class='building_address'>"+obj.building.address+"</span>":"";
		locationHTML += (typeof obj.building.address2!=="undefined")?"<span class='building_address2'>"+obj.building.address2+"</span>":"";
		locationHTML += (typeof obj.suite!=="undefined")?"<span class='separator'>,</span><span class='suite'><span class='suite_title'>Suite</span>"+obj.suite+"</span>":"";
		locationHTML +=	"</div>";
		locationHTML += (typeof obj.building.city!=="undefined")?"<span class='locality'>"+obj.building.city+"</span>":"";
		locationHTML += (typeof obj.building.state!=="undefined")?"<span class='region'>"+obj.building.state+"</span>":"";
		locationHTML += (typeof obj.building.zip!=="undefined")?"<span class='postal-code'>"+obj.building.zip+"</span>":"";
		locationHTML += "</div>";
		return locationHTML;
	},
	getMapData: function(callback){
		
			// use AJAX to get JSON object and set as thisLoc
			
	 		var parameters = {
	 	 			childpagename: eHA.Site+"/eHA_Location_C/"+eHA.Site+"/Location/json",
	 	 			site: eHA.Site,
	 	 			c: "eHA_Location_C",
	 	 			cid: this.mapID,
	 	 			pagename: eHA.Site+"_default_Wrapper"
	 	 		};
			var URL = "/cs/Satellite";
			this.ajaxRequest = new Ajax.Request(URL,
				{
					method:'get',
					parameters: parameters,
					onCreate: function(){
						eHA.log.create(parameters.cid+": AJAX request for JSON created", 3);
					},
					onSuccess: function(transport){
						eHA.log.create(parameters.cid+": AJAX request for JSON succeeded", 3);
					},
					onComplete: function(transport){
						// add transport.responseText to this.properties
						eHA.log.create(parameters.cid+": AJAX request for JSON completed", 3);
						if(transport.responseText){
							eHA.log.create(parameters.cid+": attempting to evaluate JSON", 3);
							try{
								this.mapLocation = transport.responseText.evalJSON(true);
							}catch(err){
								eHA.log.create(parameters.cid+":"+err.name+" - "+err.message, 1);
							}
							if(typeof callback!=="undefined"){
								eHA.log.create(parameters.cid+": executing callback function", 3);
								callback();
							}
						}else{
							eHA.log.create(parameters.cid+": problem with transport.responseText onComplete", 1);
						}
					}.bind(this),
					onFailure: function(){
						eHA.log.create(parameters.cid+": AJAX request for JSON resulted in failure", 1);
					}
				});
		
	
	},
	startMap: function(callback){
		eHA.log.create("start building single google map",3);
		this.getMapData(function(){this.createMap(callback);}.bind(this));
	},
	/* creates a map for a single location, directly on the page, beneath the page general body
	 * 
	 * @function
	 * @requires this.mapID
	 */
	createMap: function(callback){
 		try{
 			if(typeof this.mapLocation!=="undefined" && typeof GMap2 !=="undefined" && GBrowserIsCompatible()){
 				eHA.log.create("beginning map creation",3);
 				
 				if(typeof this.googleMapDiv!=="undefined"){
 					this.googleMapDiv.update();
 				}else{
 					this.googleMapDiv = new Element("div",{id:"google_map"+this.mapID,className:"GoogleMap"}).setStyle({height:"268px"});
 				}
 				
 				var mapContainerDiv = new Element('div',{'className':'google_map_container'});
 				var mapContainerHeader = new Element('h3').update("Maps &amp; Directions");
 				var getDirectionsDiv = new Element("div",{id:"google_map_directions"+this.mapID,className:"google_directions"});
 				this.getDirectionsForm = new Element("form");
 				this.inputMessage = "Enter Your Address";
 				this.getDirectionsInput = new Element("input",{type:"text",value:this.inputMessage,'className':'text_input'});
 				var getDirectionsSubmit = new Element("input",{type:"submit",value:"Get Directions",'className':'submit'});
 				
 				this.directionsPanel = new Element("div",{id:"directionsPanel"+this.mapID,className:"directionsPanel"});
 				
 				this.getDirectionsInput.observe("focus",function(event){
 					if(Event.element(event).value===this.inputMessage){
 						Event.element(event).value = "";
 					}
 				}.bind(this));
 				
 				this.getDirectionsInput.observe("blur",function(event){
 					if(Event.element(event).value===""){
 						Event.element(event).value = this.inputMessage;
 					}
 				}.bind(this));
 				
 				getDirectionsDiv.update(this.getDirectionsForm);
 				this.getDirectionsForm.insert({bottom:this.getDirectionsInput}).insert({bottom:getDirectionsSubmit});
 				
 				this.getDirectionsForm.observe("submit",function(event){
 					event.stop();
 					this.getDirections();
 				}.bind(this));
 				$("content_body").down("div.location").insert({after:mapContainerDiv});
 				mapContainerDiv.insert({top:mapContainerHeader});
 				mapContainerDiv.insert(getDirectionsDiv);
 				mapContainerDiv.insert(this.googleMapDiv);
 				mapContainerDiv.insert(this.directionsPanel);
 				this.map = new GMap2(this.googleMapDiv,{backgroundColor:"#ffffff"});
 				this.geocoder = new GClientGeocoder();
 				
 				// create a set of bounds for these points
 				this.bounds = new GLatLngBounds();
 				this.markers = {};
 				
				if(typeof this.mapLocation.building.latitude!=="undefined" && typeof this.mapLocation.building.longitude!=="undefined"){
					this.addMarker(new GLatLng(this.mapLocation.building.latitude,this.mapLocation.building.longitude),this.mapLocation);
				}else{
					var thisBuilding = Object.clone(this.mapLocation.building);
					if(typeof thisBuilding.assetid!=="undefined"){
						delete thisBuilding.assetid;
					}
					if(typeof thisBuilding.title!=="undefined"){
						delete thisBuilding.title;
					}
					this.address = Object.values(thisBuilding).join(" ");
					eHA.log.create("mapping address: "+this.address,3);
					this.geocoder.getLatLng(this.address,function(point){
						this.addMarker(point);
					}.bind(this));
				}
 				Event.observe(window,"beforeunload", GUnload);
 			}else{
 				eHA.log.create("can't create Google Map",3);
 			}
 			if(typeof callback!=="undefined"){
 				callback();
 			}
 		}catch(err){
 			eHA.log.create("problem creating google map for single location ("+this.mapID+"), "+err.message,1);
 		}
	},
	/**
	 * adds a marker to the google map, also checks to make sure tabs are added to correct markers
	 * @function
	 * @param {GLatLng} point
	 */
	addMarker: function(point){
		 try{
			 eHA.log.create("adding a marker",3);
			 if(typeof point!=="undefined" && point){
				 var pointID = "id"+point.x+""+point.y;
				 eHA.log.create("Adding marker for this Address, pointID: "+pointID, 3);
				 
				 var thisMarker = new GMarker(point)
				 this.map.addOverlay(thisMarker);
				 
				 // create object to contain unique markers (use pointID to identify them)
				 if(typeof this.markers[pointID]==="undefined"){
					 this.markers[pointID] = thisMarker;
				 }
				 
				 // add point to bounds and set zoom & center
				 this.bounds.extend(point);
				 
				 var newZoom = this.map.getBoundsZoomLevel(this.bounds);
				 var newCenter = this.bounds.getCenter();
 				 if(newZoom>13){ newZoom = 13;	}
 				 this.map.setCenter(newCenter,newZoom);
				 
				 // this adds a Control for every point.  not ideal
				 this.map.addControl(new GLargeMapControl());
				 
				 // create an array of HTML tabs for each unique marker
				 if(typeof this.markers[pointID].tabs==="undefined"){
					 this.markers[pointID].tabs = new Array();
				 }
				 var locationHTML = this.locationHTML(this.mapLocation);
				 this.markers[pointID].tabs.push(new GInfoWindowTab(this.mapLocation.title.strip().substring(0,10)+"..",locationHTML));
				 
				 // add array of tabs to each marker.  
				 //this allows multiple locations per building / address
				 thisMarker.bindInfoWindowTabs(this.markers[pointID].tabs);
			 }else{
				 eHA.log.create("Google Maps can't add marker for this Address", 1);
			 }
		 }catch(err){
			 eHA.log.create("problem adding markers to Google Map ("+this.mapID+"), "+err.message,1);
		 }
	},
	/**
	 * Clears overlays on Google Map, selects the "map" info tab (using this.selectorIDs), loads
	 * directions from hidden inputs and computes directions with GDirections, adds to map, populates
	 * directions list.
	 * @function
	 */
	getDirections: function(){
		try{
	      	this.map.clearOverlays();
	      	this.directionsPanel.update(); // make sure it's empty
			var directions = new GDirections(this.map, this.directionsPanel);
			if(typeof this.address=="undefined"){
				this.address=this.mapLocation.building.address +", " +this.mapLocation.building.city +", " +this.mapLocation.building.state +", " +this.mapLocation.building.zip +", " +this.mapLocation.building.longitude +", " +this.mapLocation.building.latitude;
				}
			
			var directions_string = $F(this.getDirectionsInput) + " to " + this.address;
			eHA.log.create("Attempting to get directions for "+directions_string, 3);
			directions.load(directions_string);
		}catch(err){
			eHA.log.create("Directions error: "+err.message, 1);
		}
	}
};

