var map;
var customLabels = new Array();
var markersArray = new Array();
var markerCluster = null;
var mcOptions = {gridSize: 50, maxZoom: 15};

Object.size = function(obj) {
  var size=0, key;
  for (key in obj) {
    if (obj.hasOwnProperty(key)) size++;
  }
  return size;
}

function CustomLabel(id, html) {
  var centre_id = id;
  var label_html = html;
  addLabel(this);
  
  this.getHTML = function() {
    return(label_html);
  }
  
  this.getCentre = function() {
    return(centre_id);
  }
  
  this.setHTML = function(html) {
    try {
      label_html = html;
      var success=true;
    } catch(e) {
      throw("Invalid html provided");
      var success=false;
    }
    return(success);
  }
}

function addLabel(cLabel) {
  customLabels.push(cLabel);
}

function getLabel(id) {
  for (var i=0; i<customLabels.length; i++) {
    if (customLabels[i].getCentre() == id) {
      return(customLabels[i]);
    }
  }
  return(false);
}

function labelCount() {
  return(customLabels.length);
}

function hasCustomLabel(needle) {
  for (var i = 0; i < customLabels.length; i++) {
    if (customLabels[i].getCentre == needle) {
      return(true);
    }
  }
  return(false);
}

// This is our function to be called with JSONP data
function addMarkers(markers) {
  
  var markersBounds = new google.maps.LatLngBounds();
  var infoWindow = new google.maps.InfoWindow;
  
  var autocentre = markers[0].autocentre;

  if (markers.length == 1) { //implies no results -- just 'autocentre' returned
    alert("Unable to find any centres with the given criteria");
    return;
  }
  
  for (var i = 1; i < markers.length; i++) {
    var centreid = markers[i].centre_id;
    var name = markers[i].centre;
    var lat = markers[i].lat;
    var lng = markers[i].lng;

    var point = new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
    var marker = new google.maps.Marker({
      map: map,
      position: point,
      title: name,
      icon: 'http://labs.google.com/ridefinder/images/mm_20_blue.png',
      shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
    });
    markersBounds.extend(point);
    markersArray.push(marker);
    
    var infoLabel = getLabel(1000);
    var html = infoLabel.getHTML();
    var thisLabel = getLabel(centreid);
    if (thisLabel) {
      html = thisLabel.getHTML();
    }

    var parsedHTML = html;
    for (var key in markers[i]) {
      var regex = '%' + key + '%';
      if (key == 'website') {
        markers[i].website = 'http://' + markers[i].website;
      } else if (key == 'the') {
        if (markers[i].the > 0) markers[i].the = 'The'; else markers[i].the = '';
      }
      if (parsedHTML.match(regex)) {
        var replacer = new RegExp(regex, "g");
        parsedHTML = parsedHTML.replace(replacer, markers[i][key]);
      }
    }
    bindInfoWindow(marker, map, infoWindow, parsedHTML);
  }
  
  if (autocentre) {
    map.setCenter(markersBounds.getCenter());
    map.fitBounds(markersBounds);
  }
}

function loadMarkers(mapName, filterOptions, defaultLabelHTML, mapOptions, noToggle) {
  var latlng = new google.maps.LatLng(54.5, -3.3);
  
  var myOptions = {
    zoom: 6,
    center: latlng,
    mapTypeId: google.maps.MapTypeId.TERRAIN,
    mapTypeControl: 0,
    streetViewControl: 0,
    navigationControl: true,
    navigationControlOptions: {
      style: google.maps.NavigationControlStyle.SMALL
    }
  };
  
  if (mapOptions != undefined)
  {
    for (v in mapOptions)
    {
      var toCall = "myOptions." + v + " = mapOptions." + v + ";";
      eval (toCall);
    }
  }
  
  map = new google.maps.Map(document.getElementById(mapName),
                            myOptions);
                            
  //Set up control to toggle clustering
  if (noToggle == undefined) noToggle = false;
  if (!noToggle)
  { 
    var toggleDiv = document.createElement('DIV');
    toggleControl = new ToggleControl(toggleDiv);
    
    toggleDiv.index = 1;
    map.controls[google.maps.ControlPosition.TOP_LEFT].push(toggleDiv);
  }
                            
  var logo = document.createElement('DIV');
  showLogo = new ShowLogo(logo);
  
  logo.index = 2;
  map.controls[google.maps.ControlPosition.TOP_RIGHT].push(logo);
  
  if (defaultLabelHTML == undefined) {
    defaultLabelHTML = '<b>%centre%</b><br /><a href="%website%">Visit their website</a>';
  }

  var defaultLabel = new CustomLabel(1000, defaultLabelHTML);
  
  var queryURL = "http://sciencecentres.org.uk/mapapi/mapjsonp.js.php?jsonp=addMarkers";

  if (filterOptions.filter == 1) {
    queryURL = queryURL + '&filter';
    if (filterOptions.region != undefined) {
      var autocentre = true;
      queryURL = queryURL + '&region=' + filterOptions.region;
    }
    if (filterOptions.postcode != undefined) {
      var autocentre = true;
      queryURL = queryURL + '&lat=' + filterOptions.lat + '&lng=' + filterOptions.lng + '&radius=' + filterOptions.radius;
    }
    if (filterOptions.centres != undefined) {
      queryURL = queryURL + '&centres=';
      for (var i = 0; i < filterOptions.centres.length; i++) {
        queryURL += filterOptions.centres[i] + ',';
      }
      queryURL = queryURL.substring(0, queryURL.length - 1);
    }
    if (filterOptions.searchtext != undefined) {
      var autocentre = true;
      queryURL = queryURL + "&searchtext=" + filterOptions.searchtext;
    }
  }
  
  queryURL = autocentre ?  queryURL + "&autocentre" : queryURL;

  // this is dynamic script insertion
  var script = document.createElement('script');
  script.setAttribute('src', queryURL);

  // load the script (which will call 'addMarkers' defined above and in the queryURL
  // '?jsonp=addMarkers'
  document.getElementsByTagName('head')[0].appendChild(script); 

}

function bindInfoWindow(marker, map, infoWindow, html) {
  google.maps.event.addListener(marker, 'click', function() {
    infoWindow.setContent(html);
    infoWindow.open(map, marker);
  });
}

function ToggleControl(controlDiv) {
  controlDiv.style.backgroundColor = '#ECECEC';
  controlDiv.style.borderStyle = 'solid';
  controlDiv.style.borderWidth = '1px';
  controlDiv.style.borderColor = 'black';
  controlDiv.style.margin = '5px';
  controlDiv.style.padding = '5px';
  controlDiv.style.paddingTop = '3px';
  controlDiv.innerHTML = 'Group nearby centres: ';
  
  var controlCheckBox = document.createElement('INPUT');
  controlCheckBox.type = "checkbox";
  controlCheckBox.checked = "";
  controlCheckBox.name = "clustering";

  controlDiv.appendChild(controlCheckBox);

  google.maps.event.addDomListener(controlCheckBox, 'click', function() {
    //www.geocodezip.com/v3_GoogleEx_markerclusterer_unclusterB.html
    switch (controlCheckBox.checked) {
    case true: //turn it on
      for (var i = 0; i < markersArray.length; i++) { 
        markersArray[i].setOptions({ map:null, visible: false});
      }
      markerCluster = new MarkerClusterer(map, markersArray, mcOptions);
      break;
      
    case false: //turn it off
      markerCluster.clearMarkers();
      for (var i = 0; i < markersArray.length; i++) { 
        markersArray[i].setOptions({map: map, visible:true});
      }
      break;
    }
  });
}

function ShowLogo(logoDiv) {
  var logolink = document.createElement('A');
  logolink.href = "http://sciencecentres.org.uk";
  
  var logoimg = document.createElement('IMG');
  logoimg.src = "http://sciencecentres.org.uk/mapapi/asdclogo.png";
  logoimg.border = 0;
  
  logolink.appendChild(logoimg);
  logoDiv.appendChild(logolink);
}
