/**
 * Mapping.js
 * 
 * Google Maps implementation for the KBroker based Datastore presences
 * 
 * @version 0.3.0
 * 
 * VERSION HISTORY
 * 
 * Version Author         Description
 * 0.3     Lee Theobald   Updated to work with KB5. Use version 0.2.1 for KB4 presences.
 * 0.2.1   Lee Theobald   Fixed a small bug that allowed invalid lats & longs through
 * 0.2     Lee Theobald   Updated the code to allow links to records
 * 0.1     Lee Theobald   Initial Release
 */
var map;
var mgr;
var bounds;

// Returns the size of the object
function sizeOf(obj) {
  var size = 0, key;
  for (key in obj) {
    if (obj.hasOwnProperty(key))
      size++;
  }
  return size;
}

// MapDetails object for holding Map Details in an easy to use form
function MapDetails(json) {
  this.latitude = json.map_latitude;
  this.longitude = json.map_longitude;
  this.venueName = json.venueName;
  this.postcode = json.map_postcode;
  this.JSON = json;

  this.getLatitude = function() {
    return this.latitude;
  }

  this.getLongitude = function() {
    return this.longitude;
  }

  this.getVenueName = function() {
    return this.venueName;
  }

  this.getPostcode = function() {
    return this.postcode;
  }

  this.getJSON = function() {
    return this.JSON;
  }

  this.toString = function() {
    return "MapDetails [Lat = " + this.latitude + ", Long = " + this.longitude
        + ", Postcode = " + this.postcode + "]";
  }
}

function loadJSON(mapResults) {
  var result = new Array();
  var count = 0;
  for (postcodeKey in mapResults.postcodes) {
    result[count++] = new MapDetails(mapResults.postcodes[postcodeKey]);
  }
  return result;
}

// The Google maps related code
function loadGoogleMap(mapResults, elementId, options) {
  // The main function for loading a map
  if (mapResults) {
    // Read in the JSON
    var mapDetailsArray = loadJSON(mapResults);

    // Create a map
    var myOptions = {
      zoom : 13,
      center : new google.maps.LatLng(mapDetailsArray[0].getLatitude(),
          mapDetailsArray[0].getLongitude()),
      mapTypeId : google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById(elementId), myOptions);
    bounds = new google.maps.LatLngBounds();

    var listener = google.maps.event.addListener(map, 'bounds_changed',
        function() {
          setupLocationMarkers();
          google.maps.event.removeListener(listener);
        });
  }

  function getLocationMarkers() {
    var batch = [];
    for ( var i in mapDetailsArray) {
      if (mapDetailsArray[i] && mapDetailsArray[i].getLatitude()
          && mapDetailsArray[i].getLongitude()) {
        var latlng = new google.maps.LatLng(mapDetailsArray[i].getLatitude(),
            mapDetailsArray[i].getLongitude());
        var marker = new google.maps.Marker( {
          position : latlng,
          title : mapDetailsArray[i].getPostcode()
        });
        bounds.extend(latlng);
       
        createContentWindow(marker, createContentForWindow(mapDetailsArray[i].getJSON()));

        batch.push(marker);
      }
    }

    map.fitBounds(bounds);
    map.setCenter(bounds.getCenter());
    return batch;
  }
  
  function createContentForWindow(jsonObj) {
    var windowText = "";
    if ((typeof jsonObj.title) == 'string') {
      windowText = "<h5>"+ jsonObj.title +"</h5>";
    } else {
      windowText = "<ul>";
      var arrLength = jsonObj.title.length;
      for (var x=0; x<arrLength; x++) {
        windowText += "<li><h5>"+ jsonObj.title[x] +"</h5></li>";
      }
      windowText += "</ul>";
    }
    return windowText;
  }

  function createContentWindow(marker, content) {
    var infoWindow = new google.maps.InfoWindow( {
      content : content
    });

    google.maps.event.addListener(marker, 'click', function() {
      infoWindow.open(map, marker);
    });
  }

  function setupLocationMarkers() {
    mgr = new MarkerManager(map);

    google.maps.event.addListener(mgr, 'loaded', function() {
      mgr.addMarkers(getLocationMarkers(), 3);
      mgr.refresh();
    });
  }
}