 
// Copyright 2006 OHO Corporation
// @author Titi Ala'ilima (tigre@oho.com)
// @creation-date 2006-03-07

var map;			// The main element, to be initialized on load
var searchTop;			// The bounds of our search markers
var searchBottom;
var searchLeft;
var searchRight;
// Associative arrays
var allMarkers = new Object();	// All the markers on the screen
var nearbyMarkers = new Object(); // Visible nearby markers
var hiddenMarkers = new Object(); // Invisible nearby markers
var searchMarkers = new Object(); // All the search markers
var tempMarkers;		// Holder
var idsByQuery = new Object();	// Store lists of ids retrieved by query

var categories = ["lodging", "restaurants", "shopping", "attractions", "wineries", "golf"];
var icon = new Array();
for (var i=0; i<categories.length; i++) {
  icon[categories[i]] = new GIcon(G_DEFAULT_ICON);
  icon[categories[i]].image = 'http://www.visitloudoun.org/global/images/lcva/mapmarker-'+categories[i]+'.png';
  icon[categories[i]].printImage = icon.image;
  icon[categories[i]].mozPrintImage = icon.image;
}

var mainIcon = new GIcon(G_DEFAULT_ICON);
mainIcon.image = 'http://www.visitloudoun.org/global/images/lcva/mapmainmarker.png';
mainIcon.printImage = mainIcon.image;
mainIcon.mozPrintImage = mainIcon.image;

function getInfoDiv(id, name, address, address2, city, state, zip) {
  var googleQuery = 'http://maps.google.com/?hl=en&f=d&q=';
  if (address.length)
    googleQuery += address.replace(/\s+/g, '+') + ',';
  if (city.length)
    googleQuery += city.replace(/\s+/g, '+') + ',' + state;

  var detailUrl;
  if (id.charAt(0) == "E")
    detailUrl = '/events/event-details?id=' + id.substring(1);
  else
    detailUrl = '/business/details?id=' + id;

  var infoDiv = document.createElement("div");
  infoDiv.className = 'map-info';

  infoDiv.innerHTML = '<h4><a target="_new" href="' + detailUrl + '">' +
    name +  '</a></h4>\n' + '<a target="_new" href="' + googleQuery +
    '">Get Directions</a>';

  return infoDiv;
}

function addMarker(id, div, latitude, longitude, nearby, category) {
  var marker;
  if (nearby)
    marker = new GMarker(new GPoint(longitude, latitude), icon[category]);
  else
    if (category != null)
      marker = new GMarker(new GPoint(longitude, latitude), icon[category]);
    else
      marker = new GMarker(new GPoint(longitude, latitude), mainIcon);
  marker.myId = id;
  marker.infoDiv = div;
  if (nearby)
    nearbyMarkers[id] = marker;
  else
    searchMarkers[id] = marker;
  allMarkers[id] = marker;
  return marker;
}

function comparePoint(latitude, longitude) {
  if (!searchTop || latitude > searchTop)
    searchTop = latitude;
  if (!searchBottom || latitude < searchBottom)
    searchBottom = latitude;
  if (!searchLeft || longitude < searchLeft)
    searchLeft = longitude;
  if (!searchRight || longitude > searchRight)
    searchRight = longitude;
}

function setupMap() {
  if (GBrowserIsCompatible()) {
    map = new GMap(document.getElementById("map"));
    map.addControl(new GSmallMapControl());
    map.centerAndZoom(new GPoint((searchLeft + searchRight) / 2,
				 (searchTop + searchBottom) / 2), 1);
    var latSpan = searchTop - searchBottom;
    var longSpan = searchRight - searchLeft;
    GEvent.addListener(map, 'click', function (overlay, point) {
      if (overlay) {
	showMarker(overlay);
	//      } else if (point) {
	//	map.recenterOrPanToLatLng(point);
      }
    });
    GEvent.addListener(map, 'moveend', refreshAllNearby);
    GEvent.addListener(map, 'zoom', refreshAllNearby);

    if (latSpan > 0.0 || longSpan > 0.0) {
      var level = map.getZoomLevel();
      var size;
      while ((size = map.getSpanLatLng()) && 
	     (size.width < longSpan || size.height < latSpan)) {
	map.zoomTo(++level);
      }
    }
    for (id in searchMarkers)
      if (id != 'prototype') {
	map.addOverlay(searchMarkers[id]);
      }
    refreshAllNearby();
  }
}

function toggleNearby(id) {
  if (getByID(id + 'Check').checked)
    showCategory(id);
  else
    refreshAllNearby();
}

function hideNearby(id) {
  var marker = allMarkers[id];
  if (marker) {
    hiddenMarkers[id] = marker;
    delete nearbyMarkers[id];
    delete tempMarkers[id];
    // remove the marker
    map.removeOverlay(marker);
    // delete the tr
    var row;
    if (row = getByID('tr_' + id))
      row.parentNode.deleteRow(row.sectionRowIndex);
  }
  if (!getByID('nearbyTable').rows.length)
    hideNearbyDiv();
}

function displayNearby(id, category) {
  // If this id is already shown, return
  if (searchMarkers[id]) return;

  if (nearbyMarkers[id]) {
    // If the category of the marker changed, it must be updated
    if (nearbyMarkers[id].category != category) {
      hideNearby(id);
    } else {
      return;
    }
  }
  if (tempMarkers[id]) {
    nearbyMarkers[id] = tempMarkers[id];
    delete tempMarkers[id];
    // If the category of the marker changed, it must be updated
    if (nearbyMarkers[id].category != category) {
      hideNearby(id);
    } else {
      return;
    }
  }

  // If we don't have info, get it.
  if (allMarkers[id]) {
    nearbyMarkers[id] = allMarkers[id];
    delete hiddenMarkers[id];
    // If the category of the marker changed, it must be updated
    if (nearbyMarkers[id].category != category) {
      hideNearby(id);
      getAcctInfo(id, category);
    }
  } else {
    getAcctInfo(id, category);
  }

  // Display the info
  var marker = nearbyMarkers[id];
  map.addOverlay(marker);
  var table = getByID('nearbyTable');
  var index = findRowPos(table, marker.sortKey);
  var row = table.insertRow(index);
  row.id = "tr_" + marker.myId;
  row.sortKey = marker.sortKey;
  row.setAttribute("onclick", "showEntry('" + marker.myId + "');");
  if (row.attachEvent)
    row.attachEvent("onclick",
		    new Function ("showEntry('" + marker.myId + "');"));
  var cell = row.insertCell(0);
  cell.innerHTML = '<div class="map-icon" style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\'/global/images/lcva/mapmarker-'+category+'.png\',sizingMethod=\'scale\');"><img src="/global/images/lcva/mapmarker-'+category+'.png" width="22" height="37" border="0" style="filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" /></div>';
  cell = row.insertCell(1);
  var anchor = document.createElement('a');
  anchor.name = marker.myId;
  anchor.id = marker.myId;
  anchor.innerHTML = marker.entryHtml;
  cell.appendChild(anchor);
  showNearbyDiv();
}

function findRowPos(table, sortKey, min, max) {
  if (typeof(min) == "undefined") min = 0;
  if (typeof(max) == "undefined") max = table.rows.length;
  var i = Math.floor((min + max - 1) / 2);

  if (i < 0 || sortKey > table.rows[i].sortKey)
    if (i == table.rows.length - 1 || sortKey <= table.rows[i + 1].sortKey)
      return i + 1;
    else return findRowPos(table, sortKey, i + 1, max);
  else return findRowPos(table, sortKey, min, i);
}

function hideNearbyDiv() {
  getByID('map-nearby').style.visibility = 'hidden';
}

function showNearbyDiv() {
  getByID('map-nearby').style.visibility = 'visible';
}

function showCategory(category) {
  // Query for ids to show
  var ids = getNearbyIds(category).split(",");
  if (ids.length > 1 || ids[0].length)
    for (i = 0; i < ids.length; i++)
      displayNearby(ids[i].split('|')[0], category);
}

function getNearbyIds(categories) {
  var bounds = map.getBoundsLatLng();
  var req = GXmlHttp.create();
  var query = "top=" + bounds.maxY + "&bottom=" + bounds.minY + "&left=" +
	    bounds.minX + "&right=" + bounds.maxX + "&category=" + categories;
  if (idsByQuery[query])
    return idsByQuery[query];
  req.open("GET", "http://www.visitloudoun.org/info/maps/get-ids?" + query, false);
  req.send("");
  idsByQuery[query] = req.responseText;
  return req.responseText;
}

function getAcctInfo(id, category) {
  var req = GXmlHttp.create();
  req.open("GET","http://www.visitloudoun.org/info/maps/get-info?id=" + id, false);
  req.send("");
  var resp = req.responseXML;

  var accountname = GXml.value(resp.getElementsByTagName('accountname')[0]);
  var address = GXml.value(resp.getElementsByTagName('address')[0]);
  var address2 = GXml.value(resp.getElementsByTagName('address2')[0]);
  var city = GXml.value(resp.getElementsByTagName('city')[0]);
  var state = GXml.value(resp.getElementsByTagName('state')[0]);
  var zip = GXml.value(resp.getElementsByTagName('zip')[0]);
  var phone = GXml.value(resp.getElementsByTagName('phone')[0]);

  var brTag = '<br />\n';
  var entryHtml = accountname + brTag;
  if (address.length)
    entryHtml += address + brTag;
  if (address2.length)
    entryHtml += address2 + brTag;
  if (city.length)
    entryHtml += city + ', ' + state + brTag;
  entryHtml += phone + brTag;
  entryHtml += '<a href="#" onclick="add_quick_item(\''+id+'\',\''+accountname+'\',\''+city+'\');return false;"><img src="/global/images/lcvanew/icon-add-to-trip-builder-transparent.gif" border="0" /> Add to Trip Planner</a>';

  var marker = addMarker(id,
			 getInfoDiv(id, accountname, address, address2,
				     city, state, zip),
			 GXml.value(resp.getElementsByTagName('latitude')[0]),
			 GXml.value(resp.getElementsByTagName('longitude')[0]),
			 true, category);

  marker.entryHtml = entryHtml;
  marker.sortKey = accountname; 
  marker.category = category;
}

var nearbyList = ["lodging", "restaurants", "shopping", "attractions",
		  "wineries", "golf"];

function refreshAllNearby() {
  // Find categories
  var categories = new Array();
  for (var i = 0; i < nearbyList.length; i++) {
    if (getByID(nearbyList[i] + "Check").checked)
      categories[categories.length] = nearbyList[i];
  }

  // Query for all nearby ids
  if (categories.length)
    var ids = getNearbyIds(categories.join("&category=")).split(",");
  else
    var ids = [""];

  tempMarkers = nearbyMarkers;
  nearbyMarkers = new Object();

  if (ids.length > 1 || ids[0].length) {
    // Show current list items
    for (i = 0; i < ids.length; i++) {
      var nearBy = ids[i].split('|');
      displayNearby(nearBy[0], nearBy[1]);
    }
  }

  // Hide all entries that are not in the current list
  for (id in tempMarkers)
    if (id != 'prototype')
      hideNearby(id);
}

function showEntry(id) {
  // Highlight the marker
  highlightMarker(allMarkers[id]);
  // Highlight the row
  highlightEntry(id);
}

function highlightEntry(id) {
  changeColor('tr_' + id, 'pink');
}

function showMarker(marker) {
  highlightMarker(marker);
  highlightEntry(marker.myId);
  var location_obj = findPosY(getByID(marker.myId));
  var location_div = findPosY(getByID('map-entries'));
  getByID('map-entries').scrollTop = (location_obj - location_div) -
			(navigator.userAgent.indexOf("MSIE") >= 0 ? 4 : 23);
}

function highlightMarker(marker) {
  marker.openInfoWindow(marker.infoDiv);
  GEvent.addListener(marker, 'infowindowclose', function () {
    changeColor('tr_'+this.myId, 'white');
  });
}
