/**
 * Photomap - methods for displaying markers on the map when the viewport changes.
 */

var photomap = {
  
  // This method makes this object easier to identify in firebug.
 toString: function () {
    var string = 'Photomap()';
    return string;
  },

 // A layer containing the markers
 markerLayer: null,
 
 /** Sets up the Map to define the Photomap.
  * @param float longitude, latitude are the map centre, and the place where the marker initially appears if locationKnown
  * @param int zoom
  * @param int id Id of the initially selected feature.
  */
 initialize: function (csNS, gmlNS, longitude, latitude, zoom, id, featureTag, metaTag, lookup, selectCallback)
 {
   this.csNS  = csNS;
   this.gmlNS = gmlNS;
   
   this.selectedId = id;
   this.featureTag = featureTag;
   this.metaTag    = metaTag;
   this.selectCallback = selectCallback;

   var centre = CS.lonLatToMercator( new OpenLayers.LonLat(longitude, latitude));
   var map = CS.createMap('map', centre, zoom, true);
   this.setupMarkerLayer('Photomap', lookup);
   
   this.selectControl = new OpenLayers.Control.SelectFeature(this.markerLayer, {onSelect: photomap.onFeatureSelect});
   
   CS.map.addControl(this.selectControl);
   this.selectControl.activate();
   
   // This object is used to read the GML objects directly and translates to the map projection.
   this.formatGML =  new OpenLayers.Format.GML({internalProjection: CS.map.getProjectionObject(),
	 externalProjection: new OpenLayers.Projection("EPSG:4326")});
   
   CS.map.events.on({"moveend": this.getPhotos, "zoomend": this.getPhotos, scope: this});
   
   this.getPhotos();
 },

 getPhotos: function() {

    // Determine if the point needs to be brought into view.
    var bounds = CS.map.getExtent().transform(CS.map.getProjectionObject(), CS.map.displayProjection);

    var center = bounds.getCenterLonLat();

    var url = CS.baseUrl + '/api/photos.xml?useDom=1&latitude=' + CS.r7(center.lat) + '&longitude=' +  CS.r7(center.lon) + '&zoom=' + CS.map.getZoom() + '&w=' +  CS.r7(bounds.left) + '&s=' +  CS.r7(bounds.bottom) + '&e=' +  CS.r7(bounds.right) + '&n=' +  CS.r7(bounds.top) + '&feature=' + this.featureTag + '&meta=' + this.metaTag;
    CS.debugtagmsg("<a href=\"" + url + "\" target=\"_blank\">" + url + "</a>");
   
   // This bit dumps the features in the URL straight onto a new layer and is useful for debugging.
   if(false) {
     var gmlLayer = CS.map.addLayer(new OpenLayers.Layer.GML("GML", url, {
	 projection: new OpenLayers.Projection("EPSG:4326")}));
   }

   // Defined in openlayers/lib/OpenLayers/Ajax.js
   OpenLayers.loadURL(url, null, this, this.succeed);
 },

 succeed: function (request) 
 {
    var features = this.formatGML.read(request.responseText);

    var initiallySelectedFeature = false;

    for(var f = 0; f < features.length; f++) {
      features[f].feature = features[f].attributes.feature;
      //  features[f].type = 'amber';

      // Maintain selection.
      if(this.selectedId && features[f].attributes.id == this.selectedId) {
	initiallySelectedFeature = features[f];
      }
    }

    this.markerLayer.removeFeatures(this.markerLayer.features);
    this.markerLayer.addFeatures(features);

    // Initial selection
    if(initiallySelectedFeature) {
      this.selectControl.select(initiallySelectedFeature);
    }


	// Count of the displayed markers.
	var msgEl = document.getElementById('message');
	if(msgEl) {
	  msgEl.innerHTML = (features.length ? 'Showing ' + features.length + ' marker' + (features.length == 1 ? '' : 's') + '.' : 'No markers to display, try zooming out or panning to a different area.');
	}

 },

 /**
  * Setus up a style lookup table based on...
  * @link http://london.cyclestreets.ibsen/openlayers/examples/styles-unique.html
  */
 setupMarkerLayer: function (name, lookup)
 {
   
   // create a styleMap with a custom default symbolizer
   var styleMap = new OpenLayers.StyleMap({
       
	// Set the z-indexes of both graphics to make sure the background
    // graphics stay in the background (shadows on top of markers looks odd; let's not do that).
	graphicZIndex:           100,
	backgroundGraphicZIndex: 110,	 
	// If these are not supplied openlayers/.../Canvas.js works out some defaults based on pointRadius.
	graphicWidth:  36,
	graphicHeight: 30
	});
   
   // add rules from the above lookup table, with the keyes mapped to
   // the "type" property of the features, for the "default" intent
   styleMap.addUniqueValueRules("default", "feature", lookup);
   
   this.markerLayer = new OpenLayers.Layer.Vector(name, {styleMap: styleMap, rendererOptions: {yOrdering: false}});
   
   CS.map.addLayer(this.markerLayer);
   
 },

 onFeatureSelect: function(feature) { 
    selectPhoto(feature.attributes.id, feature.attributes.rating, feature.attributes.longitude, feature.attributes.latitude, feature.attributes.caption);

    // Preserve selection (can't use 'this' as we're outside that context).
    photomap.selectedId = feature.attributes.id;

    return;
  }
};
 
////Ends
