//<![CDATA[

	/**
 	 * mapAPI.js
 	 * Initializes the cluster maetadata array, processes and handles
	 * map events, and deals with map display and interfacing issues.
	 * 
	 * @author Ross 
	 */
 
	// Array to hold various map zoom level XML Files
    var zoomClusterXMLArray = new Array(11);
    
    // Array to hold image and location repository
    var xmlDoc;
    
    //Load XML repository and cluster listings
   	importClusters();

	// used to track which marker was last clicked for highlighting
	// of icons
	var prevSelectedMarker;
	
	// used to track which image is currently in focus 
	var currentlySelectedImage;
	
	/**
	 * Legacy function used to debug marker data during execution
	 * gives alert windows for all data contained within a clicked
	 * marker
	 */
	function clickMarker()
	{
	    /*    this.icon.select();
	    this.redraw(true);
	    alert("clickMarker() "+this.icon);
	    /*    
	    if (prevSelectedMarker)
		{
		    prevSelectedMarker.deselect();
		    prevSelectedMarker = this;
		}
	    */
	}

	/**
	 * What is bingme() you ask?
	 * Bingme is a reference to Groudhog day starring Bill Murray
	 * This function is a stub called whenever XML is loaded which 
	 * does not need a callback, because a callback is required in
	 * XMLLoad.js
	 */
	function bingme()
	{
	  // Ned?  Ned Ryerson?  Bing!
	}
	
	/**
	 * Callback functions to set up dingleton icons and shift map view
	 * to zoom level 6 with appropriate clusters
	 */
	function initPoints()
	{
		createPoints();
		clusterPoints6();
	}

	/**
	 * Create and XMLLoad-er to handle the repository
	 * as well as a pointer to the XML it holds
	 */
	function importRepository()
	{
    	xmlDocLoader = new XMLLoad("XML/eXpOutNewGISClusters.xml", clusterPoints6);
//    	xmlDocLoader = new XMLLoad("XML/eXpOutNewGISClusters.xml", initPoints);
    	xmlDoc = xmlDocLoader.getXML();
    }

	/**
	 * On main web page, clears out all data within the cluster Data form
	 */
	function clearCluster()
	{
		document.getElementById('imageFrame').innerHTML = " ";
/*
		document.clusterMetadata['clusterLatitude'].value=" ";
		document.clusterMetadata['clusterLongitude'].value=" ";
		document.clusterMetadata['clusterDate'].value=" ";
*/
  		
  		document.getElementById('clusterLatitude').innerHTML = "&nbsp;";
		document.getElementById('clusterLongitude').innerHTML = "&nbsp;";
		document.getElementById('clusterDate').innerHTML = "&nbsp;";
  		

		// .rightColumn.metadata
	}

	/**
	 * When a cluster is clicked, set the web page cluster index listing from XML data
	 * @param clusterIndex
	 * Index value of the cluster within the repository
	 */
 	function setCluster(clusterIndex)
	{
		var clusterList = currentXML.getElementsByTagName('x_m_l_cluster');
		imageList = xmlDoc.getElementsByTagName('image');
 		var cluster = clusterList.item(clusterIndex);
		children = cluster.getElementsByTagName('image_pointer');
		var htmlString = "";

		for(j=0;j<children.length;j++)
		{
			child = children.item(j);
			if (child != null) imageIndex = child.getAttribute('index');
			var imageFile = imageList.item(imageIndex-1).getAttribute('imageFile');
	   
			imageThumb = imageFile.substr(imageFile.indexOf("u"), imageFile.length);

			imageThumb = imageFile.substr(imageFile.indexOf("u"), imageFile.length);
			if(smallSize==true)
			{
			 htmlString += "<A border=0 onClick=\"init("+(imageIndex-1)+")\" HREF=\"#\"><IMG HEIGHT=89 WIDTH=148 STYLE=\"margin: 5px 5px 0px 0px;\" SRC=./thumbnails/"+imageThumb+"></A>"
			}
			else
			{
			 htmlString += "<A border=0 onClick=\"init("+(imageIndex-1)+")\" HREF=\"#\"><IMG HEIGHT=120 WIDTH=200 STYLE=\"margin: 5px 5px 0px 0px;\" SRC=./thumbnails/"+imageThumb+"></A>"
			}
		}

		document.getElementById('imageFrame').innerHTML = htmlString;
		
		/*
		document.clusterMetadata['clusterLatitude'].value=cluster.getAttribute('latitudeDegree');
		document.clusterMetadata['clusterLongitude'].value=cluster.getAttribute('longitudeDegree');
 		document.clusterMetadata['clusterDate'].value=cluster.getAttribute('time');
  		// document.clusterMetadata['clusterDescription'].value=" ";
  		*/
  		
  		document.getElementById('clusterLatitude').innerHTML = cluster.getAttribute('latitudeDegree');
		document.getElementById('clusterLongitude').innerHTML = cluster.getAttribute('longitudeDegree');

		var time = cluster.getAttribute('time');
		var parsedTime = new Date();
    
		parsedTime.setTime(time);
		document.getElementById('clusterDate').innerHTML = parsedTime.toLocaleString();		
  		
	}

 	function setClusterById(clusterIndex, zoomTo)
	{
//		alert("Staring set by ID #"+clusterIndex);
		currentXMLFile = zoomClusterXMLArray[zoomTo].getXML();
		var clusterListing = currentXMLFile.getElementsByTagName('x_m_l_cluster');
		imageLister = xmlDoc.getElementsByTagName('image');
		cluster = null;
//		alert('We have a cluster list '+clusterListing.length+' long.');
		for(j=0;j<clusterListing.length;j++)
		{
			
		    var id = clusterListing.item(j).getAttribute('id');
   		    var time = clusterListing.item(j).getAttribute('time');
//		    alert("Id["+j+"]: "+id+", at time: "+time);
			if(id == clusterIndex)
			{
 				cluster = clusterListing.item(j);
// 				alert('Ah snap!');
// 				break;
 			}
 		}

// 		alert("This is what we got "+cluster);
 		
 		
// 		showProps(cluster);
		childrenNodes = cluster.getElementsByTagName('image_pointer');
		var htmlString = "";

		for(j=0;j<childrenNodes.length;j++)
		{
			child = childrenNodes.item(j);
			if (child != null) imageIndex = child.getAttribute('index');
			var imageFile = imageLister.item(imageIndex-1).getAttribute('imageFile');
	   
			imageThumb = imageFile.substr(imageFile.indexOf("u"), imageFile.length);
			if(smallSize==true)
			{
			 htmlString += "<A border=0 onClick=\"init("+(imageIndex-1)+")\" HREF=\"#\"><IMG HEIGHT=89 WIDTH=148 STYLE=\"margin: 5px 5px 0px 0px;\" SRC=./thumbnails/"+imageThumb+"></A>"
			}
			else
			{
			 htmlString += "<A border=0 onClick=\"init("+(imageIndex-1)+")\" HREF=\"#\"><IMG HEIGHT=120 WIDTH=200 STYLE=\"margin: 5px 5px 0px 0px;\" SRC=./thumbnails/"+imageThumb+"></A>"
			}
		}

		document.getElementById('imageFrame').innerHTML = htmlString;

  		document.getElementById('clusterLatitude').innerHTML = cluster.getAttribute('latitudeDegree');
		document.getElementById('clusterLongitude').innerHTML = cluster.getAttribute('longitudeDegree');
		document.getElementById('clusterDate').innerHTML = cluster.getAttribute('time');
		
  		// document.clusterMetadata['clusterDescription'].value=" ";
//  		zoomPoint = new GLatLng(cluster.getAttribute('latitudeDegree'),cluster.getAttribute('longitudeDegree')); 
//  		alert("Hoo doggy!");
	}

     
	/** 
	 * Refresh cluster listing from zoom level xml
	 */
	function importClusters()
	{
		for(var j=0; j< (zoomClusterXMLArray.length - 1); j++)
		{ 
			zoomClusterXMLArray[j] = new XMLLoad("XML/savedClusterSet"+(j+1)+".xml",bingme);
		}
		j++;
		zoomClusterXMLArray[j] = new XMLLoad("XML/savedClusterSet"+(j+1)+".xml",importRepository);
	}


	/**
	 * Create a marker whose info window displays the given number.
	 * @param point
	 * @param imageList
	 * @param icon
	 * @param lati
	 * @param longi
	 */
	function createMarker(point, imageList, icon, lati, longi) 
	{

	  var highlight 	= new GMarker(point, thisIcon);
	  var marker 		= new GMarker(point, icon);

	  // Show this marker's index in the info window when it is clicked.
	  var thisItem 		= imageList.item(i);  //TODO Pass this variable!
	  var imageFile 	= thisItem.getAttribute('imageFile');
	  var time 			= thisItem.getAttribute('time');
	  var parsedTime 	= new Date();
	  parsedTime.setTime(time);
	  marker.imageIndex = i;
	  marker.location = new GLatLng(longi,lati);

	  /**
	   *  Click based event listener for cluster icons
	   * resets cluster form, fills image cluster window
	   * sets last selected zoom point
	   * Adds highlight marker
	   * removes last highlighted marker
	   */
	  GEvent.addListener(marker, 'click', function() 
	  {
		  clearCluster();
		  init(marker.imageIndex);
		  
		  zoomPoint = marker.location;

	  	  map.removeOverlay(lastMarker);
		  map.addOverlay(highlight);
		  lastMarker = highlight;
		  
		  currentlySelectedPoint = zoomPoint;
		  

		  // map.panTo(zoomPoint);
	  });

	  return marker;
	}

	/**
	 * Sneaky method for getting all valid methods within a javascript structure
	 * Shows propertis of an object in an alert window
	 *
	 */
	var haveShownProps = false;
	function showProps(o)
	{
		for (var x in o)
		alert(x+"\t"+o[x]);
	}

	/**
	 * Builds the cluster marker and event listeners for a cluster icon
	 * @param point
	 * @param cluster
	 * @param imageList
	 * @param icon
	 * @param clusterIcon
	 * @param lati
	 * @param longi
	 * @param time
	 */
	function createClusterMarker(point, cluster, imageList, icon, clusterIcon, lati, longi, time) 
	{

	  var children = cluster.getElementsByTagName('image_pointer');
	  var child = children.item(0);

		  if(children.length >= 15)
		  {
		    clusterIcon = clusterIcon4;
		    clusterHighlightIcon = clusterHighlightIcon4;
		  }else
		  if(children.length >= 10)
		  {
		    clusterIcon = clusterIcon3;
		    clusterHighlightIcon = clusterHighlightIcon3;
		  }else
		  if(children.length >= 5)
		  {
		    clusterIcon = clusterIcon2;
		    clusterHighlightIcon = clusterHighlightIcon2;
		  }else
		  {
		    clusterIcon = clusterIcon1;
		    clusterHighlightIcon = clusterHighlightIcon1;
		  }

	  var clusterHighlight = new GMarker(point, clusterHighlightIcon);
	  var clusterMarker = new GMarker(point, clusterIcon);
	  clusterMarker.clickMarker = clickMarker;
	  clusterMarker.location = new GLatLng(longi,lati);

	  var firstImageIndex = child.getAttribute('index');

	  if (firstImageIndex >= 253)
	  {
		  firstImageIndex = 252;
	  }

	  if (children.length > 1)
	  {		  
		  var imageFile = imageList.item(firstImageIndex).getAttribute('imageFile');
		  var parsedTime = new Date();
		  parsedTime.setTime(time);
	  	
		  var html = "<P><A onClick=\"setCluster("+k+");init("+firstImageIndex+");\" HREF=\"#\"><IMG HEIGHT=150 WIDTH=225 SRC=\""+imageFile+"\"></A>"+"<BR>"+"<FONT FACE=\"arial\">Latitude: "+lati+"<BR>"+"Longitude: "+longi+"<BR>"+"Time: "+parsedTime.toLocaleString()+"</FONT></P>";
		  clusterMarker.clusterIndex = k;

		  GEvent.addListener(clusterMarker, 'click', function() 
		  {

			  map.addOverlay(clusterHighlight);
		      clearCluster();
		      setCluster(clusterMarker.clusterIndex);
	      
 	  		  zoomPoint = clusterMarker.location;
			  haveSelectedBeforeZoom = true;

			  currentlySelectedImage = firstImageIndex;
			  map.removeOverlay(lastMarker);
			  lastMarker = clusterHighlight;
	  		  
	  		  //// map.setCenter(zoomPoint);
		  });
	 	}
		else
		{
			i = firstImageIndex-1;
			clusterMarker = createMarker(point, imageList, icon, lati, longi);
		}
		return clusterMarker;
	}


	/**
	 *  Special function for setting up map at zoom level 0, ignores all 
	 *  clusters and sets up individual images.
	 */
    function createPoints()
    {
	  var locationList = xmlDoc.getElementsByTagName('location');
      var imageList = xmlDoc.getElementsByTagName('image');
          
      for (i=0;i<locationList.length;i++)
	  {
	  	var location = locationList.item(i);
      	var longi = location.getAttribute('latitudeDegree');
      	var lati = location.getAttribute('longitudeDegree');

        locPoint = new GLatLng(longi, lati);
        locMarker = createMarker(locPoint, imageList, icon, lati, longi);
            
		map.addOverlay(locMarker);

       }
     }


	/**
	 * Initilization function for setting up map at zoom level 6  
	 */
	function clusterPoints6()
	{
	    clusterPoints(6);
	}


	 /**
	  * Set up map based on zoom level, despersing cluster markers 
	  * @param zoomTo
	  * Level of zoom map is moving to during a zoom event
	  */
     function clusterPoints(zoomTo)
	 {
	   currentXML = zoomClusterXMLArray[zoomTo].getXML();

		var locaPoint;

	   var clusterList = currentXML.getElementsByTagName('x_m_l_cluster');
	   imageList = xmlDoc.getElementsByTagName('image');

	   for (k=0; k<clusterList.length; k++)
	   {
			var cluster = clusterList.item(k);
			var longi = cluster.getAttribute('latitudeDegree');
			var lati = cluster.getAttribute('longitudeDegree');
			var time = cluster.getAttribute('time');
			var number = cluster.getAttribute('id');


            locaPoint = new GLatLng(longi, lati);

            locaMarker = createClusterMarker(locaPoint, cluster, imageList, icon, clusterIcon, lati, longi, time);
            
			map.addOverlay(locaMarker);

	   }

 
// 	   alert('In development...');
	   var image = imageList.item(currentlySelectedImage);
//	   alert("This is the image file I think we want: "+image.getAttribute('imageFile'));
	   var zoomClusters = image.getElementsByTagName('clusters').item(0);
	   // showProps(image);
	   // showProps(zoomClusters);
	   var clustersAtZoom = zoomClusters.getElementsByTagName('cluster_at_zoom');
	   // showProps(clustersAtZoom);
	   var thisImageForInit = currentlySelectedImage + 1;

//	   alert("Length of "+clustersAtZoom.length+" for image "+thisImageForInit);
	   
	   var zoom = 0;

		for (i=0;i<clustersAtZoom.length;i++)
		{
			currentImageZoom = clustersAtZoom.item(i);
			zoom = currentImageZoom.getAttribute('zoomLevel');
			
			if(zoom == (zoomTo + 1 )) // This plus one seems senseless but it seems to be one zoom level ahead for no reason... Go figure.
			{
//				alert('we have a match gentlemen!');
				indexForZoomMatch = currentImageZoom.getAttribute('index');
				
//				alert("I want this index: "+indexForZoomMatch+" out of "+k);
								
				// var latit = clusterList.item(indexForZoomMatch).getAttribute('latitudeDegree'); // cluster.getAttribute('latitudeDegree');
 				// var longit = clusterList.item(indexForZoomMatch).getAttribute('longitudeDegree'); // cluster.getAttribute('longitudeDegree');
 				var latit = clusterList.item(indexForZoomMatch).getAttribute('latitudeDegree'); // item(indexForZoomMatch).getAttribute('latitudeDegree'); // cluster.getAttribute('latitudeDegree');
 				var longit = clusterList.item(indexForZoomMatch).getAttribute('longitudeDegree'); // cluster.getAttribute('longitudeDegree'); 				
 				
// 				alert("Am I on? "+longit);
 				
// 				var latit = cluster.getAttribute('latitudeDegree');
// 				var longit = cluster.getAttribute('longitudeDegree');

            	locatPoint = new GLatLng(latit, longit);
            	
        		newClusterPoint = new GLatLng(latit, longit); 
        		
        		clusterCenterPoint = new GLatLng(latit, longit);

				map.setCenter(locatPoint);
				
				zoomPoint = locatPoint;
				
//				alert("Image we are matching: "+currentlySelectedImage);
//				alert("Index of match "+indexForZoomMatch+ " for zoom "+zoom);
//				alert("Location of Match: "+latit+", "+longit);
				setInitialCluster(locaPoint, lati, longi, indexForZoomMatch, zoom - 1);
// ####CHANGE###				init(currentlySelectedImage);
				// alert("After to match "+indexForZoomMatch);
				break;
			}
			if(zoom > zoomTo) break;
		}
/* */
	}
	
	function findNewMapCenter()
	{
	    //Get the center of the map as constants for future use in zooming algorithm
		var gLatLngCenter = map.getCenter(); // This center is no longer vald after the map moves unless you updateCenter(); This may seem redundant considering
										 // we just set the center, but I do this just in case we ever plan on changing that center in the furute.
		var gPointCenter = map.fromLatLngToDivPixel(gLatLngCenter); // This GPoint holds the center of the map in DIV pixels (which remains constant);
		var centerPointX = gPointCenter.x; // Center Point of the Map, X coordinate
		var centerPointY = gPointCenter.y; // Center point of the map, Y coordinate	
	
		var mapBounds = map.getBounds();
		var zoomFixed = mapBounds.contains(zoomPoint);
		
//		alert('The zoom point is '+zoomFixed);
		if(zoomFixed)
		{
//			alert('Zoom point fixed. Finding diff.');
			var currentZoomCoords = map.fromLatLngToDivPixel(zoomPoint);
//			alert('Current Zoom Coordinates: ('+currentZoomCoords.x+','+currentZoomCoords.y+').');
			diffSize = new GSize(currentZoomCoords.x - centerPointX, currentZoomCoords.y - centerPointY);
//			alert('Center point of map should be ('+centerPointX+', '+centerPointY+').');
//			alert('I have a new diff of ('+diffSize.width+', '+diffSize.height+').');
			panMapBy = diffSize;
		}
		markerInSight = zoomFixed;
	}
	
	function setInitialCluster(point, latitude, longitude, /*NEW*/ index, zoomTo)
	{
		clearCluster();
		
//		zoomPoint = new GLatLng(longitude,latitude);
//		alert('Setting cluster '+index+'...');
		setClusterById(index, zoomTo);
//	    alert('We set cluster '+index+'!');  


//		map.centerAndZoom(zoomPoint);
		
	}

	   /**
	    * Upper level call to build map with clusters based on zoom level
	  	* @param zoomTo
	  	* Level of zoom map is moving to during a zoom event
	    */
	   function buildMap(zoomTo)
	   {
		 switch(zoomTo)
		 {
			case 0: createPoints();
					
					break;
			case 1: case 2: case 3: 
			case 4: case 5: case 6:
			case 7: case 8: case 9: 
			case 10: case 11:
					clusterPoints(zoomTo); 
					break;
			default: clusterPoints(9); 
					 break;
		 }
	   }
        
    //]]>
        
