var fields = {map: null,
              search_query: null,
              category_button: null,
              category_label: null,
              category_arrow: null,
              category_list: null,
              category_tools: null,
              new_item_area: null,
              new_item_button: null,
              new_item_label: null,
              new_item_arrow: null,
              new_item_wizard: null,
              new_item_fields: null,
              new_item_instructions: null,
              new_item_preview: null,
              category: null,
              title: null,
              new_description: null,
              image_url: null,
              b3ok_url: null,
              other_url: null};

var map;
var keyVisible = false;
var clickListener = null;
var zoomListener = null;
var newMarker = null;
var clusterer = null;
var geocoder = new GClientGeocoder();
var searching = false;
var geocoded = false;
var infoWindowOptions = {maxWidth: 250};
var icons = [];

var newIcon = new GIcon(G_DEFAULT_ICON);
newIcon.shadow           = 'map/images/new_shadow.png';
newIcon.iconSize         = new GSize(12, 20);
newIcon.shadowSize       = new GSize(22, 26);
newIcon.iconAnchor       = new GPoint(6, 20);
newIcon.infoWindowAnchor = new GPoint(5, 1);
newIcon.maxHeight        = 1;
newIcon.dragCrossImage   = 'none';

var clusterIcon = new GIcon(G_DEFAULT_ICON);
clusterIcon.image       = 'map/images/20_cluster.png';
clusterIcon.shadow      = 'map/images/20_cluster_shadow.png';
clusterIcon.iconSize    = new GSize(20, 20);
clusterIcon.shadowSize  = new GSize(26, 26);
clusterIcon.iconAnchor  = new GPoint(10, 10);
clusterIcon.printImage  = mozPrintImage = 'map/images/20_cluster.gif';
clusterIcon.printShadow = 'map/images/20_cluster_shadow.gif';

addEventHandler(window, 'load', windowLoad);
addEventHandler(window, 'unload', GUnload);

function windowLoad()
{
  for (var id in fields)
    fields[id] = document.getElementById(id);
//debugger;

  if (!GBrowserIsCompatible())
    fields.map.innerHTML = 'Sorry, it appears that your browser isn\'t compatible with our maps.';
  else
  {
    map = new GMap2(fields.map, 
      {mapTypes: [G_NORMAL_MAP, G_PHYSICAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP]});
    
    map.setCenter(new GLatLng(20, 0), 2, G_NORMAL_MAP);
    
    map.addControl(new GMapTypeControl());
    map.addControl(new GLargeMapControl());
  	map.addControl(new GScaleControl());
  	map.addControl(new GOverviewMapControl());
  	
  	clusterer = new clusterClient(map);
  	clusterer.refreshMap();
  }

  var listContent = '';
  for (var n = 1; n < itemCategories.length; n++)
  {
    listContent = listContent + '\n' +
          '<div class="item_category" id="category_area_' + n + '">' +
            '<input type="checkbox" id="show_cat_' + n + '" onclick="filterItems()" />' +
            '<label for="show_cat_' + n + '">' +
              '<img width="10" height="17" src="' + itemCategories[n].icon_url + '" />' +
              itemCategories[n].name + 
            '</label>' +
          '</div>';

    fields.category.options[fields.category.length] = new Option(itemCategories[n].name, n, false, false);
  }

  fields.category_list.innerHTML = listContent;
};

function toggleKey()
{
  keyVisible = !keyVisible;
  refreshKey();
};

function searchItems()
{
  clusterer.urlParms.global = '';
  searching = true;
  geocoded  = false;
  refreshMap();
};

function clearSearch()
{
  if (clusterer.urlParms.search != '')
  {
    // Clearing an item search
    fields.search_query.value = '';
    clusterer.urlParms.global = '';
    fields.search_query.style.backgroundColor = '';
    refreshMap();
  }
  else
    // Clearing a placename search
    map.returnToSavedPosition();
};

function clearFilter()
{
  for (var n = 1; n < itemCategories.length; n++) 
    document.getElementById('show_cat_' + n).checked = false;

  filterItems();
};

function filterItems()
{
  refreshMap();
  refreshKey();
};

function refreshMap()
{
  var selectedCategories = [];
  for (var n = 1; n < itemCategories.length; n++) 
    if (document.getElementById('show_cat_' + n).checked)
      selectedCategories.push(n);
  clusterer.urlParms.category_id = selectedCategories.join(',');

  if (geocoded)
    clusterer.urlParms.search = '';
  else
    clusterer.urlParms.search = fields.search_query.value;

  clusterer.refreshMap();
};

function refreshKey()
{
//debugger;
  if (keyVisible)
  {
    hideNew();

    fields.category_button.style.borderBottom = 'none';
    fields.category_button.style.paddingBottom = '6px';

    fields.category_label.style.border = 'none';
    fields.category_arrow.src = 'map/images/arrow_up.png';

    fields.category_tools.style.display = 'block';
    fields.category_list.style.display = 'block';
    for (var n = 1; n < itemCategories.length; n++) 
      document.getElementById('category_area_' + n).style.display = 'block';
  }
  else
  {
    fields.category_button.style.borderBottom = '1px solid black';
    fields.category_button.style.paddingBottom = '';

    fields.category_label.style.borderBottom = '1px solid silver';
    fields.category_label.style.borderRight = '1px solid silver';
    
    fields.category_tools.style.display = 'none';
    fields.category_arrow.src = 'map/images/arrow_down.png';

    var filtered = false;
    for (var n = 1; n < itemCategories.length; n++)
      if (document.getElementById('show_cat_' + n).checked)
      {
        filtered = true;
        document.getElementById('category_area_' + n).style.display = 'block';
      }
      else
        document.getElementById('category_area_' + n).style.display = 'none';

    if (!filtered)
      fields.category_list.style.display = 'none';
  }
};

function showNew()
{
  keyVisible = false;
  refreshKey();

  fields.new_item_button.style.borderBottom = 'none';
  fields.new_item_button.style.paddingBottom = '6px';
  fields.new_item_button.onclick = hideNew;

  fields.new_item_label.style.border = 'none';
  fields.new_item_arrow.src = 'map/images/arrow_up.png';

  fields.new_item_wizard.style.display = 'block';
  
  setNewItemPage(0);
};

function hideNew()
{
  fields.new_item_button.style.borderBottom = '1px solid black';
  fields.new_item_button.style.paddingBottom = '';
  fields.new_item_button.onclick = showNew;

  fields.new_item_label.style.borderBottom = '1px solid silver';
  fields.new_item_label.style.borderRight = '1px solid silver';
  fields.new_item_arrow.src = 'map/images/arrow_down.png';

  fields.new_item_wizard.style.display = 'none';
  
  if (newMarker)
  {
    map.closeInfoWindow();
    newMarker.hide();
  }
};

function setNewItemPage(page)
{
  map.closeInfoWindow();
  
  // Finalize the old page
  if ((page > 0) && (fields.new_item_fields.style.display == 'block'))
  {
    // Validate the Fields page
    if ((valueOfField(fields.category, fields.new_item_wizard) == '') ||
        (valueOfField(fields.title, fields.new_item_wizard) == '') ||
        (valueOfField(fields.new_description, fields.new_item_wizard) == ''))
    {
      alert('Category, title, and description are required.');
      return false;
    }
  }
  else if ((page != 1) && (fields.new_item_instructions.style.display == 'block'))
  {
    if (page > 1)
      // Validate the Marker page
      if (!newMarker || newMarker.isHidden())
      {
        alert('You need to click on the map to place your item.');
        return false;
      }

    // Take the map out of click mode
    clickMode(false);
  }
  
  // Show the new page
  if (page == 0)
  {
    fields.new_item_fields.style.display       = 'block';
    fields.new_item_instructions.style.display = 'none';
    fields.new_item_preview.style.display      = 'none';
  }
  else if (page == 1)
  {
    // Turn the page
    fields.new_item_fields.style.display       = 'none';
    fields.new_item_instructions.style.display = 'block';
    fields.new_item_preview.style.display      = 'none';
    
    // Put the map into click mode
    clickMode(true);
  }
  else
  {
    // Turn the page
    fields.new_item_fields.style.display       = 'none';
    fields.new_item_instructions.style.display = 'none';
    fields.new_item_preview.style.display      = 'block';
    
    // Show the preview
    var data = {name: itemCategories[valueOfField(fields.category, fields.new_item_wizard)].name,
                title: fields.title.value,
                description: fields.new_description.value,
                b3ok_url: fields.b3ok_url.value,
                other_url: fields.other_url.value};

    if (fields.image_url.value == '')
      data.image_url = '';
    else
    {
      data.image_url = 'map/constrain_image.php?image_url=' + 
                       encodeURIComponent(fields.image_url.value);
      data.image_width  = 0;
      data.image_height = 0;
    }

    newMarker.openInfoWindow(getDetails(data), infoWindowOptions);
  }
  
  return true;
};

function clickMode(on)
{
  if (on)
  {
    clickListener = GEvent.addListener(map, "click", placeMarker);
    zoomListener  = GEvent.addListener(map, "zoomend", function () {if (newMarker) map.panTo(newMarker.getLatLng())});
    map.getDragObject().setDraggableCursor('crosshair');

    if (newMarker)
      newMarker.enableDragging();
  }
  else
  {
    if (clickListener)
    {
      GEvent.removeListener(clickListener);
      clickListener = null;
    }

    if (zoomListener)
    {
      GEvent.removeListener(zoomListener);
      zoomListener = null;
    }

    map.getDragObject().setDraggableCursor('url(http://maps.google.com/intl/en_ALL/mapfiles/openhand.cur), default');

    if (newMarker)
      newMarker.disableDragging();
  }
};

function placeMarker(overlay, coords)
{
  if (coords)
  {
    if (newMarker)
    {
      newMarker.setImage = itemCategories[valueOfField(fields.category, fields.new_item_wizard)].icon_url;
      newMarker.setLatLng(coords);
      newMarker.show();
    }
    else
    {
      newIcon.image = 
        itemCategories[valueOfField(fields.category, fields.new_item_wizard)].icon_url;
      newMarker = new GMarker(coords, {icon: newIcon, draggable: true});
      map.addOverlay(newMarker);
    }
  }
  
};

function saveNew()
{
  var coords = newMarker.getLatLng();
  var url = 'map/new_item.php';
  var post = 'category=' + valueOfField(fields.category, fields.new_item_wizard) +
              '&title=' + encodeURIComponent(valueOfField(fields.title, fields.new_item_wizard)) +
              '&description=' + encodeURIComponent(valueOfField(fields.new_description, fields.new_item_wizard)) +
              '&image_url=' + encodeURIComponent(valueOfField(fields.image_url, fields.new_item_wizard)) +
              '&b3ok_url=' + encodeURIComponent(valueOfField(fields.b3ok_url, fields.new_item_wizard)) +
              '&other_url=' + encodeURIComponent(valueOfField(fields.other_url, fields.new_item_wizard)) +
              '&latitude=' + coords.lat() +
              '&longitude=' + coords.lng();

  GDownloadUrl(url, afterSave, post);
};

function afterSave(response)
{
  alert(response);
  if (response.indexOf('added') > -1)
  {
    clusterer.refreshMap();
    hideNew();
    fields.new_item_wizard.reset();
  }
};

function plotLocation(response) 
{
  if (response && 
      (response.Status.code == 200))
  {
    geocoded = true;
    map.savePosition();

    var place = response.Placemark[0];
    var coords = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);

    fields.search_query.style.backgroundColor = '';
    clusterer.urlParms.search = '';
    map.setCenter(coords, 5 + place.AddressDetails.Accuracy);
  }
  else
  {
    fields.search_query.style.backgroundColor = 'yellow';
    alert('Can\'t find anything for "' + fields.search_query.value + '"');
  }
};

function getDetails(data)
{
  var result = '<div id="infowindow">' + 
                 '<h3>' + data.title.htmlEntities() + '</h3>' + 
                 '<p><em>' + data.name + '</em></p>' + 
                 '<p>' + data.description.htmlEntities() + '</p>';

  if (data.image_url != '')
  {
    result = result + '<div';
    if (data.image_height == 0)
      result = result + ' style="width: 250px; height: 250px"';
    result = result + '><p><a target="_blank" href="' + data.image_url + '"><img src="' + data.image_url.htmlEntities() + '"';
    if (data.image_width > 0)
      result = result + ' width="' + data.image_width + '"';
    if (data.image_height > 0)
      result = result + ' height="' + data.image_height + '"';
    result = result + ' /></a></p></div>';
  }
  
  if (data.b3ok_url != '')
    result = result + '<p>B3OK link: <a href="' + data.b3ok_url + '">Click Here</a></p>';
  if (data.other_url != '')
    result = result + '<p>Web link: <a href="' + data.other_url + '">Click Here</a></p>';
  
  result = result + '</div>';

  return result;
};

// Overrides of SSC class methods

clusterClient.prototype.afterRefresh = function ()
{
  if (searching &&
      (clusterer.urlParms.search != ''))
  {
    var bounds = new GLatLngBounds;
    for (var p in this.points)
      bounds.extend(this.points[p].coords);
    
    if (bounds.isEmpty())
    {
      // No item results found
      if (clusterer.urlParms.global == '')
      {
        // Try a global search
        clusterer.urlParms.global = '1';
        refreshMap();
      }
      else 
      {
        // Try for a placename instead
        geocoder.getLocations(fields.search_query.value, plotLocation);

        // Clear other item-search-related stuff
        clusterer.urlParms.global = '';
//        clusterer.urlParms.search = '';
        searching = false;
      }
    }
    else
    {
      // Item results found
      if (clusterer.urlParms.global == '1')
        // Zoom to the item results
        this.quietMove(bounds.getCenter(), Math.min(10, map.getBoundsZoomLevel(bounds)));

      searching = false;
      fields.search_query.style.backgroundColor = 'yellow';
    }
  }
};

clusterClient.singleton.prototype.getIcon = function ()
{
  if (!icons[this.data.category_id])
  {
    icons[this.data.category_id] = new GIcon(G_DEFAULT_ICON);
    with (icons[this.data.category_id])
    {
      image            = this.data.icon_url;
      shadow           = 'map/images/32_shadow.png';
      iconSize         = new GSize(19, 32);
      shadowSize       = new GSize(35, 32);
      iconAnchor       = new GPoint(10, 31);
      infoWindowAnchor = new GPoint(10, 1);
      printImage       = mozPrintImage = this.data.icon_url.replace('png', 'gif');
      printShadow      = 'map/images/32_shadow.gif';
    }
  }

  return icons[this.data.category_id];
};

clusterClient.singleton.prototype.getTitle = function ()
{
  return this.title;
};

clusterClient.singleton.prototype.getInfoWindowContent = function ()
{
  this.infoWindowOptions = infoWindowOptions;
  return getDetails(this.data);
}

clusterClient.cluster.prototype.getIcon = function ()
{
  return clusterIcon;
};


