// GMAP API related items
var map = null;
var markerManager = null;
var geocoder = null;

// GMAP Addressing variables
var directions = null;
var directionsPanel = null;
var directionsStartInput = null;
var startAddr = null;
var endAddr = null;

// Arrays of markers from most to least-specific
var countryMarkers = [];
var metroareaMarkers = [];
var cityMarkers = [];
var restaurantMarkers = [];
var currentMarkers = [];

// Store Search Info
var savedSearchText = "";
var savedSearchSkip = 0;
// Default icons

var gIcon = "images/gmarker.png";

// Filter items
var type = 0; // [0 - multi, 1 - meat, 2 - dairy, 3 - pareve/veggie]
var cuisineFilterValue = 0; // [0 - none]

// currently displayed tooltip marker
var curTooltipMarker = null;
var deselectCurrent = function() {};

function Directions( restaurantAddress ) {

  if ( directions == null ) {
    directionsPanel = document.getElementById("route-info");
    directionsStartInput = document.getElementById("startaddress");  
    changeBodyClass( 'noroutebar', 'route-right');
    directions = new GDirections(map, directionsPanel);
  }
  
  var startAddress = directionsStartInput.value; 
  if ( startAddress.length == 0 ) {
    //alert ("Enter a starting address first");
    ;
  } else {
    computeDirections( startAddress, restaurantAddress );
  }
}

function computeDirections( from, to ) {
  var totalAddress = from + " to " + to;
  directions.load( totalAddress );
  startAddr = from;
  endAddr = to;
  //GLog.write( totalAddress );
}

function clearDirections() {
  if ( directions != null ) {
    directions.clear();
    startAddr = null;
    endAddr = null;
  }
}

function reverseDirections() {
  if ( directions != null ) {
    var newStart = endAddr;
    var newEnd = startAddr;
    clearDirections();
    computeDirections( newStart, newEnd );
  }
}

//create the ToolTip overlay object
function ToolTip(marker,html,width) {
  this.html_ = html;
  this.width_ = (width ? width + 'px' : 'auto');
  this.marker_ = marker;
}

ToolTip.prototype = new GOverlay();

ToolTip.prototype.initialize = function(map) {
  var div = document.createElement("div");
  div.style.display = 'none';
  map.getPane(G_MAP_FLOAT_PANE).appendChild(div);
    
  this.map_ = map;
  this.container_ = div;
}

ToolTip.prototype.remove = function() {
  this.container_.parentNode.removeChild(this.container_);
}

ToolTip.prototype.copy = function() {
  return new ToolTip(this.html_);
}

ToolTip.prototype.redraw = function(force) {
  if (!force) return;
    
  var pixelLocation = this.map_.fromLatLngToDivPixel(this.marker_.getPoint());
  
  this.container_.innerHTML = this.html_;
  this.container_.style.position = 'absolute';
  this.container_.style.left = pixelLocation.x + "px";
  this.container_.style.top = pixelLocation.y + "px";
  this.container_.style.width = this.width_;
  this.container_.style.font = 'bold 10px/10px verdana, arial, sans';
  this.container_.style.border = '1px solid black';
  this.container_.style.background = 'white';
  this.container_.style.padding = '4px';
  
  //one line to desired width
  this.container_.style.whiteSpace = 'nowrap';
  if(this.width_ != 'auto') this.container_.style.overflow = 'hidden';
  this.container_.style.display = 'block';
}

GMarker.prototype.ToolTipInstance = null;

GMarker.prototype.openToolTip = function(content) {
  //don't show the tool tip if there is acustom info window
  if(this.ToolTipInstance == null) {
    this.ToolTipInstance = new ToolTip(this,content)
      map.addOverlay(this.ToolTipInstance);
  }
}

GMarker.prototype.closeToolTip = function() {
  if (this.ToolTipInstance != null) {
    map.removeOverlay(this.ToolTipInstance);
    this.ToolTipInstance = null;
  }
}

function createMarker(name, latlng, address,  iconImage, recnum, geocoded, link) {
	//document.getElementById("maparea").innerHTML = document.getElementById("maparea").innerHTML+"<br>"+address;
  if (iconImage!='') {
    var icon = new GIcon();
    icon.image = gIcon;
    icon.iconSize = new GSize(20, 34);
    icon.iconAnchor = new GPoint(14, 25);
    icon.infoWindowAnchor = new GPoint(14, 14);
	
	//alert(address);
	
   // var marker = new GMarker(latlng, { icon:icon, title:name });
	 var marker = new GMarker(latlng, { title:name });
  } else {
    var marker = new GMarker(latlng, { title:name });
  }
    
	//addClickevent(marker);
    map.addOverlay(marker);
  // Show InfoWindow when clicked
  if ( recnum != null ) {
    GEvent.addListener(marker, 'click', function() {
  	  showRestaurantDetails( recnum );
    });
  } else if ( geocoded == false ) {
    GEvent.addListener(marker, 'click', function() {
      showRestPage( marker, link );
      map.setCenter( marker.getPoint(), map.getZoom() );
    });  
  } else {
    // Zoom in when double-clicked
    GEvent.addListener(marker, 'dblclick', function() {
      map.setCenter( marker.getPoint(), map.getZoom() + 1 );
    });
  }

 
    
  // Hook in tooltip show/hide
  GEvent.addListener(marker,'mouseover',function() {
    var markerName = name;
   	marker.openToolTip(markerName);
    curTooltipMarker = marker;
  });
  
  GEvent.addListener(marker,'mouseout',function() {
    curTooltipMarker = null;
    marker.closeToolTip();
  });
  
  //map.addOverlay(marker);

  var myMarker = {};
  myMarker.marker = marker;
  myMarker.name = name;
  myMarker.recnum = recnum;
  myMarker.latlng = latlng;
  myMarker.geocoded = geocoded;
  myMarker.link = link;
  return myMarker;
}

function updateMarkers() {
		updateRestaurants( 10, 16);
}

function openPage( title, link ) {
  window.open( link, title, "directories=no,height=800,width=800,locations=no,menubar=no,status=no,toolbar=no,scrollbars=yes" );  
}

function URLEncode (clearString) {
  var output = '';
  var x = 0;
  clearString = clearString.toString();
  var regex = /(^[a-zA-Z0-9_.]*)/;
  while (x < clearString.length) {
    var match = regex.exec(clearString.substr(x));
    if (match != null && match.length > 1 && match[1] != '') {
    	output += match[1];
      x += match[1].length;
    } else {
      if (clearString[x] == ' ')
        output += '+';
      else {
        var charCode = clearString.charCodeAt(x);
        var hexVal = charCode.toString(16);
        output += '%' + ( hexVal.length < 2 ? '0' : '' ) + hexVal.toUpperCase();
      }
      x++;
    }
  }
  return output;
}

function URLDecode( encoded ) {
   // Replace + with ' '
   // Replace %xx with equivalent character
   // Put [ERROR] in output if %xx is invalid.
   var HEXCHARS = "0123456789ABCDEFabcdef"; 
   var plaintext = "";
   var i = 0;
   while (i < encoded.length) {
       var ch = encoded.charAt(i);
	   if (ch == "+") {
	       plaintext += " ";
		   i++;
	   } else if (ch == "%") {
			if (i < (encoded.length-2) 
					&& HEXCHARS.indexOf(encoded.charAt(i+1)) != -1 
					&& HEXCHARS.indexOf(encoded.charAt(i+2)) != -1 ) {
				plaintext += unescape( encoded.substr(i,3) );
				i += 3;
			} else {
				plaintext += "%[ERROR]";
				i++;
			}
		} else {
		   plaintext += ch;
		   i++;
		}
	} // while
   return plaintext;
}



function showRestaurantDetails( recnum ) {

  myMarker = restaurantMarkers[recnum];
  
  if(myMarker.latlng)
  {
  	map.setCenter( myMarker.latlng, 15 );
  }
  
  if ( myMarker.html != null ) {
    myMarker.marker.openInfoWindowHtml(myMarker.html);
  } else {
    var request = GXmlHttp.create();
    var getVars =  "?eventid=" + recnum;
      
    //tell the request where to retrieve data from.
    request.open('GET', 'gmapeventdetails.php' + getVars, true);
    request.onreadystatechange = function() {
      if (request.readyState == 4) {
        
   	    //GLog.write( 'Length of response ' + request.responseText.length );
    	  var xmlResp = request.responseText;
        //GLog.write (xmlResp);	
        if ( xmlResp ) {
          myMarker.marker.openInfoWindowHtml(xmlResp);
          myMarker.html = xmlResp;      
        }  	    
    	} 
    } //request.onreadystategchange function
    
    //tell the request what to do when the state changes.
    request.send(null);
  }
}


function requestRestaurants( minZoom, maxZoom, curZoom, minlon, maxlon, minlat, maxlat ) {

 var request = GXmlHttp.create();
  var getVars =  "?tab=0&lngMax=" + maxlon + "&lngMin=" + minlon + "&latMax=" + maxlat + "&latMin=" + minlat + "&zoomlevel=" + curZoom;

  request.open('GET', 'mapevents.php', true);
  request.onreadystatechange = function() {
    if (request.readyState == 4) {
      
 	    //GLog.write( 'Length of response ' + request.responseText.length );
  	  var xmlResp = request.responseText;	
  	  var xmlDoc = request.responseXML;
 	  
  	    
  	  if ( xmlDoc && xmlDoc.documentElement ) {

  	    // Process Markers
  	    var markers = xmlDoc.documentElement.getElementsByTagName("marker");
  	    
  	    // Empty "current" restaurants array 
        currentMarkers.length = 0;
        
 	      //GLog.write( "# Markers = " + markers.length );
  	    for (var i = 0; i < markers.length; i++) {
      		var lng = markers[i].getAttribute("lng");
      		var lat = markers[i].getAttribute("lat");
      		var name = markers[i].getAttribute("name");
      		var address = markers[i].getAttribute("address");
            var recno = markers[i].getAttribute("recno");
      		var recnum = parseInt(recno,10);
      		
           currentMarkers[currentMarkers.length] = recnum;
          
       
          
          // If we have do not have this restaurant already, create it 
    		  if ( restaurantMarkers[recnum] == null ) {
        		//check for lng and lat so MSIE does not error
        		//on parseFloat of a null value
        		if(lng && lat) 
				{
        		  var latlng = new GLatLng(parseFloat(lat),parseFloat(lng));
				  var marker = createMarker(name, latlng, address, gIcon, recnum, true, null);
				  restaurantMarkers[recnum] = marker;
        		}
				else
				{	
					geocoder = new GClientGeocoder();
					geocoder.getLatLng(
						  address,
						  function(point) {
							  var latlng = point; //new GLatLng(parseFloat(lat),parseFloat(lng));
							  var marker = createMarker(name, latlng, address, gIcon, recnum, true, null);
							  restaurantMarkers[recnum] = marker;
						  }
						);
				}
				
          }
    	  } //for
        

     	} else {
     	  //alert( "xmlDoc or documentElement is null ");
      } //if

		
  	} 
  } //request.onreadystategchange function
  
  //tell the request what to do when the state changes.
  request.send(null);
}



function updateRestaurants( minZoom, maxZoom ) {

  // Set loading state to Loading
  //changeBodyClass( 'standby', 'loading' );

  // Get the current lat/lon extents for the map
  var bounds = map.getBounds();
  var lat1 = bounds.getSouthWest().lat().toFixed(6);
  var lat2 = bounds.getNorthEast().lat().toFixed(6);
  var lon1 = bounds.getSouthWest().lng().toFixed(6);
  var lon2 = bounds.getNorthEast().lng().toFixed(6);
    
  var minlat = Math.min( lat1, lat2 );
  var maxlat = Math.max( lat1, lat2 );
  var minlon = Math.min( lon1, lon2 );
  var maxlon = Math.max( lon2, lon1 );
  
  requestRestaurants( minZoom, maxZoom, map.getZoom(), minlon, maxlon, minlat, maxlat );
  
}

// This routine returns the height of the inner window for different browsers
function windowHeight() {
  // Standard browsers (Mozilla, Safari, etc.)
  if ( document.all ) {
    if (document.body.offsetHeight) {
    	return document.body.offsetHeight;
    }
  } else {
    if (self.innerHeight) {
    	return self.innerHeight;
    }
  }
  
  // IE 6
  if (document.documentElement && document.documentElement.clientHeight)
	  return document.documentElement.clientHeight;
    
  // IE 5
  if (document.body)
  	return document.body.clientHeight;
    
  // Just in case.
  return 0;
}

// This routine is called when the window is resized to move all the components around
function handleResize() {
  var height = windowHeight() - document.getElementById('toolbar').offsetHeight - 30;
  document.getElementById('map').style.height = (height-16) + 'px';
  document.getElementById('sidebar').style.height = (height-14) + 'px';
  document.getElementById('route').style.height = (height-16) + 'px';
  document.getElementById('results').style.height = (height -  document.getElementById('searchPane').offsetHeight - 1 - 15) + 'px';
  if ( map != null ) {
    map.checkResize();
  }
}

// This routine handles changing the state from loading to standby
function changeBodyClass(from, to) {
  document.body.className = document.body.className.replace(from, to);
  return false;
}


function zoomLevel( placemark ) {
  var accuracy = placemark.AddressDetails.Accuracy;

  /*
  0 	 Unknown location. (Since 2.59)
  1 	Country level accuracy. (Since 2.59)
  2 	Region (state, province, prefecture, etc.) level accuracy. (Since 2.59)
  3 	Sub-region (county, municipality, etc.) level accuracy. (Since 2.59)
  4 	Town (city, village) level accuracy. (Since 2.59)
  5 	Post code (zip code) level accuracy. (Since 2.59)
  6 	Street level accuracy. (Since 2.59)
  7 	Intersection level accuracy. (Since 2.59)
  8 	Address level accuracy. (Since 2.59)
  */
  switch ( accuracy ) {
    case 0: //   0 	 Unknown location. (Since 2.59)
    default:
      newZoomLevel = 4;
      break;
    case 1: //   1 	Country level accuracy. (Since 2.59)
      newZoomLevel = 6;
      break;
    case 2: //   2 	Region (state, province, prefecture, etc.) level accuracy. (Since 2.59)
      newZoomLevel = 8;
      break;
    case 3: //   3 	Sub-region (county, municipality, etc.) level accuracy. (Since 2.59)
      newZoomLevel = 9;
      break;
    case 4: //   4 	Town (city, village) level accuracy. (Since 2.59)
      newZoomLevel = 10;
      break;
    case 5: //   5 	Post code (zip code) level accuracy. (Since 2.59)
      newZoomLevel = 13;
      break;
    case 6: //   6 	Street level accuracy. (Since 2.59)

      newZoomLevel = 15;
      break;
    case 7: //   7 	Intersection level accuracy. (Since 2.59)
    case 8: //   8 	Address level accuracy. (Since 2.59)
      newZoomLevel = 16;
      break;
  }
  return newZoomLevel;
}


function gotoLL( lat, lng ) {
      	var	latlng = new GLatLng(parseFloat(lat),parseFloat(lng));
        map.setCenter( latlng, 16 );
}

// The routine is called only once when the URL is first called
function init() {
  document.getElementById("maparea").innerHTML = "Updating Events";
  // Create the main map and add all controls
  map = new GMap2(document.getElementById("map"));
  map.addControl(new GLargeMapControl());
  map.addControl(new GMapTypeControl());
  //map.setCenter(new GLatLng(startLat, startLon), startZoom);
  map.enableDoubleClickZoom();
  map.enableContinuousZoom();
  map.setCenter(new GLatLng(51.4612, -2.59141), 12);
  // Create Marker Manager to manage all the markers
  markerManager = new GMarkerManager(map);
    
  // This causes restaurants to be added to the map when the map moves
  //GEvent.addListener(map, "moveend", function() { updateMarkers() });
  //map.setCenter( latlng, 10 );
    
  updateMarkers();
  document.getElementById("maparea").innerHTML = "";
}

// Equivalent of "main" code below
//window.onresize = handleResize;
window.onload = init;
window.onunload = GUnload;
