var megalabMap;
var spotMarker;    // store marker
var currentMarker; // variable used in ajax.
var loadedMarkers = new Array(); // array of current marker objects
var loadedMarkersList = ''; // variable to avoid work when loading markers from ajax
var currentLevel = null; // different to zoom, this gives the current cluster level either 0 1 2 or 3
var markerToPopup = null; // lat and lng holder for marker to show info.
var loading = false; // check for ajax!
var lmTimeout = null; // timeout holder
var lamTimeout = null; // timeout holder

function gmapSetup() {
  if (GBrowserIsCompatible()) {
    // create map
    megalabMap = new GMap2($('map'));
    mapInit();
    createLoader();
    hideLoader();
  }
  self.focus();
}

function mapInit(){}

function toggleEvent() {
  if(this.clicked) {
    this.clicked = false;
    this.setImage(getVirtualDirURL() + '/images/pins/pin'+this.pinId+'.gif');
    removeEvent(this.pinId);
  } else {
    this.clicked = true;
    this.setImage(getVirtualDirURL() + '/images/pins/pin'+this.pinId+'selected.gif');
    addEvent(this.pinId);
  }
  checkDownload();
}

function addEvent(id) {
  var form = $('download_form');
  var input = document.createElement('input');
  input.setAttribute('type', 'hidden');
  input.setAttribute('id', 'event_'+id);
  input.setAttribute('name', 'event_'+id);
  input.setAttribute('value', id);
  form.appendChild(input);
}

function removeEvent(id) {
  var form = $('download_form');
  var input = $('event_'+id);
  form.removeChild(input);
}

function checkDownload() {
  var form = $('download_form');
  var button = $('download_submit');
  if(form.childNodes.length > 1) {
    button.removeAttribute('disabled');
  } else {
    button.setAttribute('disabled', 'disabled');
  }
}

function showLocationInfo() {
  currentMarker = this;
  showLoader();
  GDownloadUrl(getBaseURL(true) + '/showLocationInfo/eventId/'+this.pinId, addInfoWindow);
}

function showMapsLocationInfo() {
  currentMarker = this;
  showLoader();
  GDownloadUrl(getBaseURL() + '/maps/showLocationInfo/eventId/'+this.pinId, addInfoWindow);
}

function addInfoWindow(data, responseCode){
  var json = data.evalJSON();
  var tabs = createTabs(json);
  var opts = new Object();
  opts.maxWidth = 500;
  currentMarker.openInfoWindowTabs(tabs, opts);
  hideLoader();
}

function createTabs(data) {
  var tabs = new Array();
  data.each(function(t){
    var label = t.label;
    var content = document.createElement('div');
    t.content.each(function(c){
      content.appendChild(createHTML(c));
    });
    tabs.push(new GInfoWindowTab(label, content));
  });
  return tabs;
}

function createHTML(data) {
  var elem;
  if(data['tag']) {
    elem = document.createElement(data['tag']);
  } else {
    elem = document.createDocumentFragment();
  }

  if(elem.nodeType == 1 && data['attributes']) {
    for(var i in data['attributes']) {
      if(i == 'class') {
        elem.setAttribute(i+'Name', data['attributes'][i].gsub('\/', '/'));
      }
      elem.setAttribute(i, data['attributes'][i].gsub('\/', '/'));
    }
  }

  if(elem && data['content']) {
    data['content'].each(function(c){
      if(typeof c == 'object') {
        child = createHTML(c);
      } else {
        child = document.createTextNode(c);
      }
      elem.appendChild(child);
    });
  }
  return elem;
}

function openPopup(id) {
  var marker = findMarker(id);
  if(marker) {
    currentMarker = marker;
    showLoader();
    GDownloadUrl(getBaseURL(true) + '/showLocationInfo/eventId/'+marker.pinId, addInfoWindow);
  }
}

function findMarker(id) {
  for (var i = 0, len = loadedMarkers.length; i < len; ++i) {
    if(loadedMarkers[i].pinId == id) {
      return loadedMarkers[i];
    }
  }
  return null;
}

function updatePin() {
  var lat = $('latitude').value;
  var lng = $('longitude').value;
  if(lat != '' && lng != '') {
    if(spotMarker) {
    spotMarker.setPoint(new GLatLng(lat, lng));
    } else {
      var opts = new Object();
      opts.draggable = true;
      spotMarker = new GMarker(new GLatLng(lat, lng), opts);
      spotMarker.enableDragging();
      GEvent.addListener(spotMarker, 'dragend', endDragMarker);
      megalabMap.addOverlay(spotMarker);
    }
  }
}

function useLocation(marker, point) {
  var form = $('event_form');
  if(!marker) {
    if(spotMarker) {
      spotMarker.setPoint(point);
    } else {
      var opts = new Object();
      opts.draggable = true;
      spotMarker = new GMarker(point, opts);
      spotMarker.enableDragging();
      GEvent.addListener(spotMarker, 'dragend', endDragMarker);
      megalabMap.addOverlay(spotMarker);
      //form.habitat_id.selectedIndex = null;
      //form.location_id.value = null;
      //form.latitude.disabled = null;
      //form.longitude.disabled = null;
      //form.habitat_id.disabled = null;
    }
    addCoords(spotMarker);
  }
}

function endDragMarker() {
  addCoords(this);
}

function addCoords(marker) {
  var form = $('event_form');
  var lat = new Number(marker.getPoint().lat());
  var lng = new Number(marker.getPoint().lng());
  form.latitude.value = lat.toFixed(12);
  form.longitude.value = lng.toFixed(12);
  var zoom = $('zoom_level');
  zoom.value = megalabMap.getZoom();
  checkLocationForm();
}


function updateZoom(oldLevel, newLevel) {
  var zoom = $('zoom_level');
  zoom.value = newLevel;
}

function loadMarkers(oldLevel, newLevel) {
  if(lmTimeout) {
    window.clearTimeout(lmTimeout);
  }
  var level = getLevel();
  if(currentLevel == null) {
    currentLevel = level;
  } else if (currentLevel != level) {
    currentLevel = level;
    megalabMap.clearOverlays();
    loadedMarkers = new Array();
    loadedMarkersList = '';
  }
  var sw = megalabMap.getBounds().getSouthWest();
  var ne = megalabMap.getBounds().getNorthEast();
  lmTimeout = window.setTimeout(function(){loading = true;GDownloadUrl(getBaseURL(true) + '/retrievePinInfo?level='+level+'&south='+sw.lat()+'&west='+sw.lng()+'&north='+ne.lat()+'&east='+ne.lng()+'&excluded='+loadedMarkersList, populateMap);}, 1000);
}

function loadAdditionalMarkers() {
  if(lamTimeout) {
    window.clearTimeout(lamTimeout);
  }
  if(!loading) {
    var level = getLevel();
    var sw = megalabMap.getBounds().getSouthWest();
    var ne = megalabMap.getBounds().getNorthEast();
    lamTimeout = window.setTimeout(function(){loading = true;GDownloadUrl(getBaseURL(true) + '/retrievePinInfo?level='+level+'&south='+sw.lat()+'&west='+sw.lng()+'&north='+ne.lat()+'&east='+ne.lng()+'&excluded='+loadedMarkersList, populateMap);}, 1000);
  }
}

function populateMap(data, responseCode) {
  var json = data.evalJSON();
  for(var i = 0; i < json.pins.length; i++)
  {
    if(json.level != getLevel()) break;
    createMarker(json.pins[i]);
  }
  loading = false;
  if(markerToPopup) {
    var id = markerToPopup;
    markerToPopup = null;
    openPopup(id);
  }
}

function createMarker(obj) {
  var opts = new Object();
  opts.title = obj.title;
  iconPath = obj.iconPath;
  var icon = new GIcon(G_DEFAULT_ICON, iconPath);
  icon.iconSize = new GSize(obj.iconWidth, obj.iconHeight);
  if(currentLevel != getUnclusteredLevel()) {
    opts.clickable = false;
    icon.shadow = null;
    icon.iconAnchor = new GPoint(18, 18);
    icon.imageMap = new Array(13,1,23,1,27,3,33,8,35,13,35,23,33,28,28,33,23,35,13,35,8,33,3,28,1,23,1,13,3,8,7,4,10,2);
  }
  //showImageMap(icon);
  opts.icon = icon;
  var mkr = new GMarker(new GLatLng(obj.lat, obj.lng), opts);
  if(currentLevel == getUnclusteredLevel()) {
    GEvent.addListener(mkr, 'click', showLocationInfo);
  } else {
    //GEvent.addListener(mkr, 'click', showClusterInfo);
  }
  mkr.pinId = obj.id;
  megalabMap.addOverlay(mkr);
  loadedMarkers.push(mkr);
  var comma = '';
  if(loadedMarkersList != '') {
    comma = ',';
  }
  loadedMarkersList += comma + obj.id;
}

function showImageMap(icon) {
  var output = '[\n';
  for(var i = 0; i < icon.imageMap.length; i++) {
    output += icon.imageMap[i];
    if(i != icon.imageMap.length-1) {
      output += ', ';
    }
    if(i%2 != 0) {
      output += '\n';
    }
  }
  output += ']';
}

function getLevel() {
  switch(megalabMap.getZoom()) {
    case 0: case 1: case 2:
      return 0;
    case 3: case 4: case 5:
      return 1;
    case 6: case 7:
      return 2;
    case 8: case 9:
      return 3;
    case 10: case 11:
      return 4;
    default:
      return 5;
  }
}

function getUnclusteredLevel() {
  return 5;
}

function drawGrid(level) {
  var grids = new Array(14.4, 3.6, 0.72, 0.144, 0.072);
  var grid = grids[level];
  for(var lat = 43.2; lat <= 72; lat += grid) {
    var points = new Array(new GLatLng(lat, -90), new GLatLng(lat, 90));
    megalabMap.addOverlay(new GPolyline(points, '#c90000', 1, 1));
  }
  for(var lng = -28.8; lng <= 14.4; lng += grid) {
    var points = new Array(new GLatLng(-90, lng), new GLatLng(90, lng));
    megalabMap.addOverlay(new GPolyline(points, '#c90000', 1, 1));
  }
}

function showClusterInfo() {
  var zoom = megalabMap.getZoom();
  currentMarker = this;
  GDownloadUrl(getBaseURL(true) + '/showClusterInfo/clusterId/'+this.pinId, addInfoWindow);
}

function createLoader() {
  var loader = document.createElement('div');
  loader.setAttribute('id', 'overlay');
  var img = document.createElement('img');
  img.setAttribute('id', 'loaderImage');
  img.setAttribute('src', getVirtualDirURL() + '/images/ajax-loader.gif');
  loader.appendChild(img);
  var MLmap = $('map');
  Position.clone(MLmap, loader, {setLeft:false, setTop:false});
  MLmap.appendChild(loader);
  var loaderImage = $('loaderImage');
  var loaderSize = Element.getDimensions(loader);
  var imgSize = Element.getDimensions(loaderImage);
  var left = loaderSize.width/2 - imgSize.width/2+'px';
  var top = loaderSize.height/2 - imgSize.height/2+'px';
  Element.setStyle(loaderImage, {'left': left, 'top': top});
}

function showLoader() {
  $('overlay').show();
}

function hideLoader() {
  $('overlay').hide();
}
