/* 
 * Written by Chris Schroeder 6/22/2007
 * Copyright 2007 Johns Hopkins University. All rights reserved.
 * 
 * This is our group of Ajax functions.
 * 
 * Edited and expanded on 7/21/2007 CS
 */

/* vars initialized */

/* the map */
    var map = null; //Google API object

/* the Google geocoder */
    var geocoder = null; //Google API object

/* all the points on the map */
	var mapPoints= []; //array of points plotted with marker data
	
/* counter */
	counter = null; //counts points
	
/* the categories */
	var categoriesList = []; //Array of Category JSON data
	var category_id = null;
	var sm = null;

/* the AJAX includes */
	var detailInclude = null;//for detailed info about a service
	var addressInclude = null;//for address info about a service


/* this is the AJAX request. 
 * We can remove this once we go 
 * live and use the common lib one.
 */
function createRequest() {
	var request = null;
	try {
		request = new XMLHttpRequest();
	} catch (trymicrosoft) {
		try {
			request = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (othermicrosoft) {
			try {
				request = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (failed) {
				request = null;
			}
		}
	}
	if (request == null) {
		alert ("Error creating request object");
	} else {
		return request;
	}
}

	function setCFVars(pages) {
		if(pages) {
			for (key in pages) {
				eval(key+"='"+pages[key]+"'");
			}
		}
	}


/* 
 * Here's where we use AJAX
 * to request our JSon URL
 * We can give it a category ID
 * or it will return each category
 * in a packet.
 * 
 * The query can have as many vars
 * as we need - in JSon format.
 */
	function startRequest(url,query) {
		var urlQuery = "?";
		if(query) {
			for (key in query) {
				if(key) {
					myName = key;
					myValue = query[key];
					urlQuery += myName + "=" + myValue + "&";
				}
			}
		}
		if(!url) {
			url = "";
			alert("we've lost our URL somewhere");
			exit;
		}
		var myURL = url + urlQuery;
		JSONRequest = createRequest();
		JSONRequest.open("GET", myURL, true);
		JSONRequest.onreadystatechange = putOnPage;
		JSONRequest.send(null);
  	}

/* For testing
	function clearDiv() {
		document.getElementById("contentContainer").innerHTML = "";
	}
*/

/*
 * This function checks to see whether
 * the checkbox that ran it was checked
 * or unchecked and then runs the 
 * corresponding function.
 */
	function checkFunction (url,category_id,formField) {
		if(!formField.checked) {
			formField.checked = false;
		}
		if(formField.checked == 'checked') {
			startRequest(url,{'category_id':category_id});
			formField.checked = 'checked';
		} else {
			unplotPoints(category_id); 
			formField.checked = false;
		}
	}

/*
 * Here is where we deconstruct 
 * the JSon data. We assign values 
 * to each of our javascript vars.
 * 
 * Two loops here. One through the
 * categories and one through the 
 * services for each category...
 */
	function putOnPage() {
		if(JSONRequest.readyState == 4) { 



/* 
 * m is the internal counter, 
 * counter is the global counter
 * 
 * on function start, 
 * counter sets m's value
 * 
 * at document start,
 * counter is null 
 */
			m = 0;
			if(counter!=null) {
				m = m + counter;
			} else {
				counter = 0;
			}
			var myCategories = eval("(" + JSONRequest.responseText + ")");
			for(i=0; i <= myCategories.categories.length; i++) {
				if(myCategories.categories[i]) {
					categoriesList.push(myCategories.categories[i]);


/*
 * for testing. no need to remove.
 * 
 * 					document.getElementById("contentContainer").innerHTML += "<h1>" + myCategories.categories[i].name + "<" + "h1/>"; 
 */


					for(n=0; n<= myCategories.categories[i].services.length; n++) {
						var q = 0;
						if(myCategories.categories[i].services[n]) {

/*
 * values set here:
 * address, title, category_id, location_id
 */
							address = myCategories.categories[i].services[n].address1 + " ";
							address += myCategories.categories[i].services[n].address2 + " ";
							address += myCategories.categories[i].services[n].city + ", ";
							address += myCategories.categories[i].services[n].state + " ";
							address += myCategories.categories[i].services[n].zip;
							mtitle = myCategories.categories[i].services[n].service_name;
							//window.alert(mtitle);
							category_id = myCategories.categories[i].category_id;
							location_id = myCategories.categories[i].services[n].location_id;
							plotPoint(address,mtitle,category_id,location_id,m);
							m++;
							q++;
							counter = m;
						}
						if(q > 1) {
							document.getElementById(myCategories.categories[i].category_id).checked = true;
						}
					}
				}
			}
		}
	}
	
/* Primary map function - loads on 
 * pageload and initializes the map 
 * and geocoder, loads the map 
 * onto the map div
 */
    function load(longitude,latitude,zoom) {
      if (GBrowserIsCompatible()) {
        map = new GMap2(document.getElementById("map"));
        map.setCenter(new GLatLng(latitude,longitude), zoom, G_HYBRID_MAP);
        geocoder = new GClientGeocoder();
      }
    }

/*
 * We use this function to geocode AND plot
 * the points on the map. It also pushes
 * the location_id and marker into the 
 * array we are holding on to, which contains
 * all our points.
 * 
 * it also calls addressHandler and clickHandler 
 * to display our includes. we call them here
 * because the click event is part of the marker
 * attributes.
 */
	function plotPoint(address,title,category_id,location_id,counter) {
		if (geocoder) {
			geocoder.getLatLng(
				address, function(point) {
				if (point) {
					myicon = createIcon();
					var marker = new GMarker(point, {icon: myicon, title: title + "\r\n" + address});
					mapPoints[counter] = [];
					mapPoints[counter].push(category_id,location_id,marker);
					map.addOverlay(marker);
					GEvent.addListener(marker, "click", function() {
						clickHandler(marker, location_id, "click", detailInclude,sm);
						addressHandler(marker, location_id, "click", addressInclude); 
					});
					return marker;
					}
				}
			);
		}		
	}

/*
 * Here's where we remove points from the map.
 * We're using a second array, which has the marker
 * in it, to keep track of all the current points 
 * on the map.
 * 
 * If a category is supplied, we only remove the
 * points who have that category ID as part of 
 * their array. If not, we remove all points.
 */	
	function unplotPoints(category_id) {
		for(x=0;x<=mapPoints.length;x++) {
			if(mapPoints[x]) {
				if(mapPoints[x][0]==category_id) {
					map.removeOverlay(mapPoints[x][2]);
				} else {
					if(category_id==null) {
						map.removeOverlay(mapPoints[x][2]);
						document.getElementById(mapPoints[x][0]).checked = false;
					}
				}
			}
		}
	}
/*
	function unplotPoints(category_id) {
		for(x=0;x<=mapPoints.length;x++) {
			if(mapPoints[x]) {
				if(mapPoints[x][0]==category_id) {
					map.removeOverlay(mapPoints[x][2]);
					document.getElementById(mapPoints[x][0]).checked = false;
				} else if(category_id == null) {
					map.removeOverlay(mapPoints[x][2]);
				}
			}
		}
		if(category_id == null) {
			for(i=0;i<=categoriesList.length;i++) {
				document.getElementById(categoriesList[i].category_id).checked = false;
			}
		}
	}
*/

/*
 * showAddress finds the address returned
 * from the search form.
 */
    function showAddress(address,zoom) {
      if (geocoder) {
        geocoder.getLatLng(
          address,
          function(point) {
            if (!point) {
              alert(address + " not found");
            } else {
              map.setCenter(point,15);
            }
          }
        );
      }
    }


/*
 * Simple function to create and return icon 
 * 
 * There's the default if one is not supplied.
 */
	function createIcon(iconImage,iconShadow) {
		var icon = new GIcon();
		if(!iconImage) {
			icon.image = "/custom/mod_services/_images/pinPoint.png";
		} else {
			icon.image = iconImage;
		}
		if(!iconShadow) {
			icon.shadow = "/custom/mod_services/_images/mm_20_shadow.png";
		} else {
			icon.shadow = iconShadow;			
		}

		icon.iconSize = new GSize(12, 20);
		icon.shadowSize = new GSize(22, 20);
		icon.iconAnchor = new GPoint(6, 6);
		icon.infoWindowAnchor = new GPoint(5, 1);
		return icon;
	}

/*
 * This function is a carryover from Chris's v2 map. 
 * It creates the request for the details about
 * the selected service
 * 
 * Note: We'll eventually want to combine the following
 * four functions into one or two or a class, but for now
 * in the interest of saving time, we'll leave it this way
 * CS 7/20/2007
 */
	function clickHandler(marker, location_id, mode, detailInclude,sm){
		detailInclude = detailInclude + "?location_id=" + location_id + "&sm=" + sm;
		pointRequest = createRequest();
		pointRequest.open("GET", detailInclude, true);
		pointRequest.onreadystatechange = getInfo;
		pointRequest.send(null);
  	}

/*
 * This is the function that loads the 
 * listing into the itemContainer div
 */
	function getInfo() {
		if(pointRequest.readyState == 4) {
			document.getElementById("itemContainer").innerHTML = pointRequest.responseText;
		}
	}

/*
 * This is the AJAX request for the 
 * listing address
 */
	
	function addressHandler(marker, location_id, mode, addressInclude){
		addressInclude = addressInclude + "?location_id=" + location_id;
		addressRequest = createRequest();
		addressRequest.open("GET", addressInclude, true);
		addressRequest.onreadystatechange = getAddressInfo;
		addressRequest.send(null);
  	}

/*
 * This is the function that loads the 
 * listing address into the addressContainer div
 */
	function getAddressInfo() {
		if(addressRequest.readyState == 4) {
			document.getElementById("addressContainer").innerHTML = addressRequest.responseText;
			document.getElementById("addressContainer").style.visibility = "visible";			
		}
	}

/* 
 * Removes content from the text divs
 */
	function clearAddressInfo() {
		document.getElementById("addressContainer").innerHTML = "";
		document.getElementById("itemContainer").innerHTML = "";
	}


/* all of the map controls are in this function.
 * 
 * we will eventually replace this with a control class -
 * or at least a more useful function - but for now it works
 * and wastes about 40 lines.
 */	
	function loadControls(width,height,navwidth,navheight) {
/* Our zoom controls One for Zoom in, Zoom out, Global View, and Close up */
		var zin = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(10,10));
		zin.apply(document.getElementById("zoomInControl"));
		document.getElementById("map").appendChild(document.getElementById("zoomInControl"));	
		document.getElementById("zoomInControl").style.visibility = "visible";

		var zout = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(31,10));
		zout.apply(document.getElementById("zoomOutControl"));
		document.getElementById("map").appendChild(document.getElementById("zoomOutControl"));	
		document.getElementById("zoomOutControl").style.visibility = "visible";

		var zoomclose = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(52,10));
		zoomclose.apply(document.getElementById("closeupControl"));
		document.getElementById("map").appendChild(document.getElementById("closeupControl"));	
		document.getElementById("closeupControl").style.visibility = "visible";

		var zoomglobal = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(73,10));
		zoomglobal.apply(document.getElementById("globalControl"));
		document.getElementById("map").appendChild(document.getElementById("globalControl"));	
		document.getElementById("globalControl").style.visibility = "visible";

/* Our directional controls One for North, South, East and West */
		var northNav = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(((width-navwidth)/2),0));
		northNav.apply(document.getElementById("northControl"));
		document.getElementById("map").appendChild(document.getElementById("northControl"));	
		document.getElementById("northControl").style.visibility = "visible";
		
		var westNav = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(0,((height-navwidth)/2)));
		westNav.apply(document.getElementById("westControl"));
		document.getElementById("map").appendChild(document.getElementById("westControl"));	
		document.getElementById("westControl").style.visibility = "visible";
		
		var eastNav = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize((width-navheight),((height-navwidth)/2)));
		eastNav.apply(document.getElementById("eastControl"));
		document.getElementById("map").appendChild(document.getElementById("eastControl"));	
		document.getElementById("eastControl").style.visibility = "visible";
		
		var southNav = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(((width-navwidth)/2),(height-navheight)));
		southNav.apply(document.getElementById("southControl"));
		document.getElementById("map").appendChild(document.getElementById("southControl"));	
		document.getElementById("southControl").style.visibility = "visible";		
	}
	
/*
 * These functions are carryovers from past map versions.
 */

/* for the custom controls */

function resetMap()
{
	map.setCenter(new GLatLng(startLat, startLng));
	map.setZoom(startZoom);

}

/* Redefining an existing function is bad pratice - especially if 
 * its does the same thing in a more limiting way the original function. 
 * Bad idea. Commented out. Good example of what NOT to do.
 * 
 * function zoomIn()
 * {
 * 	map.zoomIn();
 * }	
 * 
 * function zoomOut()
 * {
 * 	map.zoomOut();
 * }
 */

function resetCenter(latitude,longitude, zoom)
{
	var center = new GLatLng(latitude, longitude);
	map.setCenter(center, zoom);
}
