
// Global variables
  var markers = Array();
  var prefiltered_markers = Array();
  var circle, icon, radius_marker, map, visitors_center;
  var busy = false;
      
// Bind Events once DOM is loaded
  Event.observe(window, 'load', mapsListeners);

// Event bindings
  function mapsListeners(){
    if($('maps_wrapper')) {
      $$('#maps_tabs li a').each(function(el){
        el.observe('click', switchTab);
      });

      $$('dt a').each(function(el){
        el.observe('click', changeCategory);
      });

      $$('dd li input').each(function(el){
        el.observe('click', displayCategory);
      });

      $$('dd p.maps_controls a.show').each(function(el){
        el.observe('click', showAll);
      });

      $$('dd p.maps_controls a.hide').each(function(el){
        el.observe('click', hideAll);
      });

      $('maps_set_radius').observe('click', drawRadius);
      $('maps_radius').observe('change', changeRadius);

      $('maps_neighborhood_form').observe("submit",neighborhoodRecenter);
      $('maps_visitors_recenter').observe("click",visitorsRecenter);
      $('maps_address_form').observe("submit",addressSearch);
      $("maps_prefiltered").observe("change",loadPrefilteredMap);
      $('maps_search_form').observe("submit",mapSearch);
      $("maps_query").observe("keyup",mapSearchEmpty);
      maps_init();
    }
  }

// Tabs
  function switchTab(ev) {
    Event.stop(ev);
    var active = $$('#maps_tabs li.active')[0];
    active.removeClassName('active');
    $(active.down().readAttribute('rel')).hide();
    $(this.readAttribute('rel')).show();
    this.up().addClassName('active');
    Event.stop(ev);
  }

// Google Maps
  function maps_init() {
    if (GBrowserIsCompatible()) {
      // initialize map
      map = new GMap2(document.getElementById('map'));
      visitors_center = new GLatLng('39.284187', '-76.613025'); // 401 Light St, Baltimore, MD 21202
      map.setCenter(visitors_center, 13);
      var mt = map.getMapTypes();
      // Overwrite the getMinimumResolution() and getMaximumResolution() methods
      for (var i=0; i<mt.length; i++) {
        mt[i].getMinimumResolution = function() {return 9;}
        mt[i].getMaximumResolution = function() {return 17;}
      }
      map.addControl(new GLargeMapControl());


      
      // show visitor's center
      var visitors_icon = new GIcon(G_DEFAULT_ICON);
      visitors_icon.image = 'http://www.baltimore.org/images/fastspot/marker_visitors.png';
      visitors_icon.iconSize = new GSize(35, 35);
      visitors_icon.iconAnchor = new GPoint(17, 18);
      visitors_icon.shadow = null;
      visitors_icon.imageMap = Array(0,0, 35,0, 35,35, 0,35);
      visitors_icon.infoWindowAnchor = new GPoint(17, 20);
      var visitors_marker = new GMarker(visitors_center, visitors_icon);
      map.addOverlay(visitors_marker);
      GEvent.addListener(visitors_marker,'click', function(){
        html = '<div class="infowindow"><h2><a href="/visitor-center">Baltimore Visitor Center</a></h2><p>401 Light Street<br />Baltimore, MD 21202<br /><br />West Shore of Baltimore\'s Inner Harbor</p></div>';  
        this.openInfoWindowHtml(html);
      });
      //GEvent.trigger(visitors_marker, 'click');
      
      // Setup other variables/icons/markers
      icon = new GIcon(G_DEFAULT_ICON);
      icon.image = 'http://www.baltimore.org/images/fastspot/marker_attractions.png';
      icon.iconSize = new GSize(42, 53);
      icon.shadow = null;
      icon.infoWindowAnchor = new GPoint(17, 2);
      icon.imageMap = Array(0, 0, 34, 0, 34, 34, 0, 34);

      var radius_icon = new GIcon(G_DEFAULT_ICON);
      radius_icon.image = 'http://www.baltimore.org/images/fastspot/radius_marker.png';
      radius_icon.iconSize = new GSize(29, 46);
      radius_icon.iconAnchor = new GPoint(0, 46);
      radius_icon.shadow = null;

      radius_marker = new GMarker(map.getCenter(), {icon: radius_icon, draggable: true, clickable: false});
      map.addOverlay(radius_marker);
      radius_marker.hide();
      
      if (typeof(poi) != 'undefined') {
        icon.image = poi.icon;
        map.addOverlay(createMarker(new GLatLng(poi.latitude, poi.longitude), icon, poi));
        map.setCenter(new GLatLng(poi.latitude, poi.longitude));
      }

      // Bind event listeners for dragging walking radius marker
      GEvent.addListener(radius_marker, 'dragstart', startDrag);
      GEvent.addListener(radius_marker, 'dragend', endDrag);
    }
  }
  
// Walking radius functions
  function drawRadius() {
    if (!$('maps_set_radius').checked) {
      map.removeOverlay(circle);
      radius_marker.hide();
      $('maps_radius').disable();
    }
    else {
      $('maps_radius').enable();
      if (radius_marker.isHidden()) {
        radius_marker.show();
      }
      drawCircle(map.getCenter(), calcRadius());
    }
  }

  function calcRadius() {
    var hypot = 918.72; // length of hypotenuse of map
    var meters_per_mile = 1609.344; // constant of meters in a mile
    var miles = $('maps_radius').getValue(); // get number of miles in radius
  
    var corner = map.getBounds().getSouthWest();
    var distance = corner.distanceFrom(map.getBounds().getNorthEast());
    var meters_per_pixel = distance / hypot;

    return (meters_per_mile / meters_per_pixel) * miles; // pixels
  }

  function drawCircle(center, radius) {
    var points = Array();
    var projection = G_NORMAL_MAP.getProjection();
    var zoom = map.getZoom();
    var circle_center = projection.fromLatLngToPixel(center, zoom);
    var sides = 50;
    var length = 360 / sides;
  
    for (var i = 0; i < (sides + 1); i++) {
      var aRad = length * i * (Math.PI / 180);
      var pixelX = circle_center.x + radius * Math.cos(aRad);
      var pixelY = circle_center.y + radius * Math.sin(aRad);
      var pixel = new GPoint(pixelX, pixelY);
      var point = projection.fromPixelToLatLng(pixel, zoom);
      points.push(point);
    }
    circle = new GPolygon(points, '#EF6423', 2, 1, '#EF6423', 0.2);
    if (center != radius_marker.getLatLng()) {
      radius_marker.setLatLng(center);
    }
    map.addOverlay(circle);
  }
  function changeRadius() {
    map.removeOverlay(circle);
    drawCircle(radius_marker.getLatLng(), calcRadius());
  }
  function endDrag() {
    drawCircle(radius_marker.getLatLng(), calcRadius());
  }
  function startDrag() {
    map.removeOverlay(circle);
  }

  // Category display functions
  function changeCategory(ev) {
    Event.stop(ev);
  	if (busy == true)
  		return;
    var clicked = this.up().next('dd');
    if (this.up().hasClassName("maps_noexpand")) {
    	if (this.hasClassName("active")) {
    		removePOIs(this.up().id);
    		this.removeClassName("active");
    	} 
    	else {
    		this.addClassName('active');
			  displayPOIs(this.up().id);
		  }
    } 
    else {
      this.addClassName('active');
		  $$('#maps_categories dd').each(function(el){
			  if (el.visible() && clicked != el){
		    	busy = true;
				  el.previous().select('a')[0].removeClassName('active');
   	     	new Effect.Parallel([Effect.BlindUp(el, {sync: true}), Effect.BlindDown(clicked, {sync: true})], { afterFinish: function() { busy = false; }});
   	   	}
   	 	});
   	}
  }

  function displayCategory(ev) {
    var cat = this.readAttribute('name');
    if (cat == "events") {
    	hideCategory("Events-Today");
    	hideCategory("Events-Week");
    	hideCategory("Events-Month");
    	cat = this.readAttribute("value");
    }
    if (!this.checked) {
      hideCategory(cat);
    }
    else if (cat) {
      icon.image = 'http://www.baltimore.org/images/fastspot/marker_' + this.up(2).className + '.png';
      showCategory(cat);
    }
  }
  
  // Hide all categories in a section
  function hideAll(ev){
    this.up().next().select('li input').each(function(el){
      hideCategory(el.readAttribute('name'));
      el.checked = false;
    });
    Event.stop(ev);
  }

  // Show all categories in a section
  function showAll(ev){
    icon.image = 'http://www.baltimore.org/images/fastspot/marker_' + this.up(1).className + '.png';
    var categories = new Array();
    this.up().next().select('li input').each(function(el){
      var category = el.readAttribute('name');
      if (markers[category]) {
        showCategory(category);
      }
      else {
        categories.push(category);
      }
      el.checked = true;
    });
    
    if (categories.length != 0) {
      fetchCategories(categories);
    }

    Event.stop(ev);
  }

  // closure so infoWindow has access to data
  function createMarker(point, icon, data){
    var marker = new GMarker(point, icon);
    GEvent.addListener(marker,'click', function(){
      	if (data.poi_type == "event")
      		html = '<div class="infowindow" style="font-size: 12px; height: auto; width: 260px;"><h2><a href="/events/id/' + data.id + '/">' + data.name + '</a></h2>';
		else if (data.poi_type == "member")
      		html = '<div class="infowindow" style="font-size: 12px; height: auto; width: 260px;"><h2><a href="/attractions/' + data.id + '/">' + data.name + '</a></h2>';
		else
	      	html = '<div class="infowindow" style="font-size: 12px; height: auto; width: 260px;"><h2>' + data.name + '</h2>';

    	if (data.image) {
    		html += '<img src="' + data.image + '" alt="" width="65" height="65" />';
    	}
    	if (data.address) {
    	  html += '<p>' + data.address + '<br />' + data.city + ', ' + data.state + ' ' + data.zip + '</p>';
    	}
    	if (data.url) {
    	  html += '<a href="http://' + data.url.replace('http://','') + '" target="_blank">Website</a>';
    	}
  		if (data.description) {
  		  html += '<br class="clear" /><div class="description">' + truncate(data.description, 300, data.id) + '</div>';
  		}	
  		
  		if (data.suitcased > 0)
	  		html += '<ul><li><a href="#" class="suitcaseit_link" name="' + data.poi_type + '-' + data.id + '"><img src="http://www.baltimore.org/images/fastspot/add_icon.png" alt="" />Remove from Suitcase</a></li>';
	  	else
	  		html += '<ul><li><a href="#" class="suitcaseit_link" name="' + data.poi_type + '-' + data.id + '"><img src="http://www.baltimore.org/images/fastspot/add_icon.png" alt="" />Add to Suitcase</a></li>';
	  	
  		html += '<li><a href="#" class="emailit_link" name="' + data.poi_type + '-' + data.id + '"><img src="http://www.baltimore.org/images/fastspot/email_icon.png" alt="" />Email It</a></li>';
  		html += '<li><a href="javascript:map.setCenter(new GLatLng(' + data.latitude + ',' + data.longitude + '));"><img src="http://www.baltimore.org/images/fastspot/center_icon.png" alt="" />Center</a></li></ul>';	
	    html += '</div>';	
	    this.openInfoWindowHtml(html, {maxWidth: 250});
	    $$('.emailit_link').each(function(el) {
     	el.observe("click",emailIt);
     	});
     	$$('.suitcaseit_link').each(function(el) {
     	el.observe("click",suitcaseIt);
     	});
    });
    return marker;
  }

  // fetch all items in category
  function fetchCategory(category) {
    // check if markers already cached, if not, create array and fetch JSON data via AJAX
    if (!markers[category]){
      $('maps_loading').show();
      markers[category] = new Array();
      var ajax = new Ajax.Request('/fastspot/ajax/map.php?category=' + category, {
        method: 'get',
        onSuccess: function(response) {
          data = eval(response.responseText);
          for (var i = 0; i < data.length; i++) {
            // create markers and add to map
            markers[category][i] = createMarker(new GLatLng(data[i].latitude,data[i].longitude), icon, data[i]);
            map.addOverlay(markers[category][i]);
          }
          $('maps_loading').hide();
        }
      });
    }
  }

  // fetch items from multiple categories in one request
  function fetchCategories(categories) {
    if (categories.length != 0) {
      $("maps_loading").show();
      cats = categories.join('&categories[]=');
      new Ajax.Request('/fastspot/ajax/map.php?categories[]=' + cats, {
        method: 'get',
        onSuccess: function(response) {
          data = eval('(' + response.responseText + ')');
          for (var category in data) {
            markers[category] = new Array();
            for (var j=0; j < data[category].length; j++) {
              // create markers and add to map
              markers[category][j] = createMarker(new GLatLng(data[category][j].latitude,data[category][j].longitude), icon, data[category][j]);
              map.addOverlay(markers[category][j]); 
            }
          }
          $('maps_loading').hide();
        }
      }); 
    }
  }

  function showCategory(category){
    // check if category has already been fetched and cached
    if (markers[category]) {
      for (var i=0; i < markers[category].length; i++) {
        markers[category][i].show();
      }
    }
    else {
      fetchCategory(category);
    }
  }

  function hideCategory(category){
    if (markers[category]) {
      for (var i=0; i < markers[category].length; i++) {
        markers[category][i].hide();
      }
    }
  }
  
  // Recenter-ers
  function neighborhoodRecenter(event) {
  	Event.stop(event);
  	$("maps_loading").show();
  	new Ajax.Request("/fastspot/ajax/map_action.php?action=neighborhood&id=" + $("maps_neighborhood_select").value, {onComplete: function(){ $("maps_loading").hide(); } });
  }
  
  function visitorsRecenter(event) {
    Event.stop(event);
  	map.setCenter(visitors_center);
  }
  
  // Searches
  
  function addressSearch(event) {
  	Event.stop(event);
  	$("maps_loading").show();
  	new Ajax.Request("/fastspot/ajax/map_action.php?action=address_search&query=" + escape($("maps_address_query").value), {
  	  onComplete: function() {
  	    $("maps_loading").hide();
  	  }
  	});
  }
  
  function mapSearch(event) {
  	Event.stop(event);
  	$('maps_loading').show();
  	new Ajax.Updater("maps_search_results","/fastspot/ajax/map_search.php?query=" + escape($("maps_query").value), { evalScripts: true, onComplete: function() { 
  	  $('maps_loading').hide();
  	  $("maps_search_results").style.display = "block"; 
  	  } 
  	});
  }
  
  function moreMapSearch(page) {
  	new Ajax.Updater("maps_search_results","/fastspot/ajax/map_search.php?query=" + escape($("maps_query").value) + "&page=" + page, { evalScripts: true });
  }
  
  function mapSearchEmpty() {
  	if ($("maps_query").value == "")
  		$("maps_search_results").style.display = "none";
  }
  
  function mapPoint(id,type) {
  	new Ajax.Request("/fastspot/ajax/map_action.php?action=point&id=" + id + "&type=" + type, {onSuccess: function(response){ eval(response);}});
  }
  
  function closeMapSearch() {
  	$("maps_search_results").style.display = "none";
  }
  
  // Admin POIs Displaying
  
  function displayPOIs(category) {
  	category = category.replace("maps_","");
  	icon.image = 'http://www.baltimore.org/images/fastspot/marker_' + category + '.png';
  	showCategory(category);
  }
  
  function removePOIs(category) {
  	category = category.replace("maps_","");
  	hideCategory(category);
  }
  
  // Prefiltered Maps Loading
  
  function loadPrefilteredMap() {
  	id = $("maps_prefiltered").value;
  	hideEverything();
  	$("maps_loading").show();
  	new Ajax.Request('/fastspot/ajax/map.php?prefiltered=' + id, {
        method: 'get',
        onSuccess: function(response) {
          data = eval(response.responseText);
          for (var i = 0; i < data.length; i++) {
            // create markers and add to map
            icon.image = 'http://www.baltimore.org/images/fastspot/marker_' + data[i].category + '.png';
            prefiltered_markers[i] = createMarker(new GLatLng(data[i].latitude,data[i].longitude), icon, data[i]);
            map.addOverlay(prefiltered_markers[i]);
          }
          map.setCenter(visitors_center, 13);
          $("maps_loading").hide();
        }
     });
  }
  
  function hideEverything(){
    $$('#maps_categories li input').each(function(el){
      hideCategory(el.readAttribute('name'));
      el.checked = false;
    });
    hideCategory("parking");
    $("maps_parking").down().removeClassName("active");
    hideCategory("landmarks");
    $("maps_landmarks").down().removeClassName("active");
    for (var i=0; i < prefiltered_markers.length; i++) {
    	prefiltered_markers[i].hide();
    }
  }
  
  // truncate string
  function truncate(str, length, id) {
    if (str.length <= length) {
      return str;
    }
    else {
      return str.substring(0, length - 3) + '...' + '<a href="/events/id/' + id + '">more</a>';
    }
  }
  
  function emailIt(ev) {
	Event.stop(ev);
	var el = Event.element(ev);
	offset = el.cumulativeOffset();
	
	new Ajax.Request("/fastspot/ajax/email_it.php?left=" + offset[0] + "&top=" + offset[1] + "&id=" + el.name, { evalScripts: true });
  }
  
  function suitcaseIt(ev) {
		Event.stop(ev);
		var el = Event.element(ev);
		offset = el.cumulativeOffset();
				new Ajax.Request("/fastspot/ajax/login.php?left=" + offset[0] + "&top=" + offset[1], { evalScripts: true });
			}