// file: BrowseMap.js
// author: Matthew Lawhead
// purpose: object to encapsulate functionality related to 
//          browsing Conservation Registry project locations
// 	        using the Google Maps API
//
// namespace: TOF (The Other Firm)
// application: ConsRegistry (Conservation Registry)
//
// usage: var browseMap = new BrowseMap(mapDivId, portal, mapType);
// depends on: 
// 	 Google Maps API
//   MapInitDefaults.js
//   FormHelper.js
//   ReferencePointManager.js
//   RegistryInfoWindow.js
// 	 Clusterer2.js [optional]
// 	 progressbarcontrol.js [optional]
//

function BrowseMap(mapDiv, portal, mapType){
	this.portal = portal;
	this.portalMode = false;
  this.map = TOF.ConsRegistry.MapInitDefaults.init(mapDiv, portal, mapType, true);
	this.mapType = mapType; // 'search' or 'browse'
	this.icons = this.createIcons();
  this.iw; //custom info window overlay
  this.MIN_POINT_ZOOM = 7;// 10;
  this.site_points = [];
	this.clusterer = null;
  this.referencePointManager  = new ReferencePointManager(this.map);
}

// Clustering is not initialized by default
BrowseMap.prototype.initClusterer = function(){
	this.clusterer = new Clusterer(this.map);
	this.clusterer.SetIcon(this.icons.clusterIcon);
}

// Events are not initialized by default
BrowseMap.prototype.initEvents = function(portal_mode){
	if(portal_mode){this.portalMode = true;}
	this.createMapClickEvent();
  this.createMapPointAppearEvent();
}

BrowseMap.prototype.stopEvents = function(){
	this.removeMapClickEvent();
	this.removeMapPointAppearEvent();
	this.closeRegistryInfoWindow();
	this.clearExistingPoints();
}

BrowseMap.prototype.togglePortalMode = function(){
  this.portalMode = ! this.portalMode;
	this.closeRegistryInfoWindow();
	this.clearExistingPoints();
	this.findSitesInBounds();
}



BrowseMap.prototype.clearOverlays = function(){
  this.map.clearOverlays();	
}


BrowseMap.prototype.createIcons = function(){
  var blankIcon = new GIcon();
  blankIcon.image = "images/bg_transparent_white.png";
  blankIcon.iconSize = new GSize(7,7);
  blankIcon.iconAnchor = new GPoint(0,0);
  
  var defaultIcon = new GIcon();
      defaultIcon.image = "http://labs.google.com/ridefinder/images/mm_20_green.png";
      defaultIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
      defaultIcon.iconSize = new GSize(12, 20);
      defaultIcon.shadowSize = new GSize(22, 20);
      defaultIcon.iconAnchor = new GPoint(6, 20);
      defaultIcon.infoWindowAnchor = new GPoint(5, 1);

	var clusterIcon = new GIcon();
	clusterIcon.image = "/images/keys/cluster_blue.png";
	clusterIcon.iconSize = new GSize(18, 18);
	clusterIcon.iconAnchor = new GPoint(0, 0);
	clusterIcon.infoWindowAnchor = new GPoint(0,1);
  
  var refIcon = new GIcon(defaultIcon);
  refIcon.image = "http://labs.google.com/ridefinder/images/mm_20_purple.png";

  return {refIcon:refIcon, defaultIcon: defaultIcon, blankIcon:blankIcon, clusterIcon:clusterIcon};
}


BrowseMap.prototype.closeRegistryInfoWindow = function(){
  if(this.iw){
    this.map.removeOverlay(this.iw);
    delete this.iw;
  }
}


BrowseMap.prototype.projectClick = function(project_id){
  var contentClick = "";
  contentClick += "setMapExtentCookies();";
  return contentClick;
}

BrowseMap.prototype.projectLink = function(project_id){
  var linkTo = "/projects/" + project_id;
  return linkTo;
}


BrowseMap.prototype.ncedSingleSiteContent = function(site){
  var separator = space(3) + pipe() + space(3);

  var linkTo = this.projectLink(site.project_id);
  var contentClick = this.projectClick(site.project_id);
  
  var header = h3(a( site.project_name, linkTo, {onclick : contentClick}));
  var content = p(strong("Site: ") + site.site_name + "<br />" + strong("Location: ") + site.location + "<br />" + strong("Easement Holder: ") + site.easement_holder  + "<br />" + strong("Landowner Type: ") + site.landowner_type + "<br />" + strong("Public Access: ") + site.public_access, {id: "info_item_details"});
  content += p((site.description || "No description"), {id : "info_item_description"});
  content += p( a_img_w_text("View Detail Page", 
                        "/images/bu-detail_page.png", 
                         linkTo,
                        {'class':"png", width:"16", height:"16", alt:"View project detail page", border:"0"},
                        {onclick : contentClick}),
                {id:"info_view_detail_page"});
                
  return { content: content, header: header};
}
  
BrowseMap.prototype.singleSiteContent = function(site){
  var separator = space(3) + pipe() + space(3);

  var linkTo = this.projectLink(site.project_id);
  var contentClick = this.projectClick(site.project_id);
  
  var header = h3(a( site.project_name, linkTo, {onclick : contentClick}));
  var content = p(strong("Site: ") + site.site_name + "<br />" + strong("Location: ") + site.location + "<br />" + strong("Organization: ") + site.organization  + "<br />" + strong("Contact: ") + site.primary_contact, {id: "info_item_details"});
  content += p((site.description || "No description"), {id : "info_item_description"});
  content += p( a_img_w_text("View Detail Page", 
                        "/images/bu-detail_page.png", 
                         linkTo,
                        {'class':"png", width:"16", height:"16", alt:"View project detail page", border:"0"},
                        {onclick : contentClick}),
                {id:"info_view_detail_page"});
                
  return { content: content, header: header};
}

BrowseMap.prototype.multipleSitesContent = function(sites){
  var header = h3(a("Shared Location", "#"));
  var content = "<ul>";
	var self = this;
  sites.each(function(site){
    var linkTo = self.projectLink(site.project_id);
    var contentClick = self.projectClick(site.project_id);
    content += "<li>" + a( site.project_name, linkTo, {onclick : contentClick}) + "</li>";
  });
  content += "</ul>";
  return {content: content, header: header} ;
}


BrowseMap.prototype.openRegistryInfoWindow = function(pt, sites){
  var obj;
  if(sites.length > 1){
    obj = this.multipleSitesContent(sites);
  }
  else{
		if(sites[0].custom_info_window){ obj = this.ncedSingleSiteContent(sites[0]); } 
		else{ obj = this.singleSiteContent(sites[0]); }
  }

  this.closeRegistryInfoWindow();
  this.iw = new RegistryInfoWindow(pt, obj.content, obj.header);
  this.map.addOverlay(this.iw);
}


BrowseMap.prototype.findSitesFromPoint = function(pt){
	var self = this;
  new Ajax.Request("/browse/map/find_sites_from_coords", { 
    method: 'post',
    parameters: {lat : pt.lat(), lng : pt.lng(), zoom : self.map.getZoom()},
    onSuccess: function(req){
      var arr = eval('(' + req.responseText + ')');
      
      if(arr.length >= 1){ self.openRegistryInfoWindow(pt, arr);}
    },
    asynchronous:true, evalScripts:true
  });
}


BrowseMap.prototype.createMapClickEvent = function(){
		var self = this;
    this.mapClickEvent = GEvent.addListener(self.map, 'click', function(overlay,pt){
      if(overlay == null){ self.findSitesFromPoint(pt); }
    });
};

BrowseMap.prototype.removeMapClickEvent = function(){
	var self = this;
	GEvent.removeListener(self.mapClickEvent);
}


BrowseMap.prototype.findSitesInBounds = function(bounds){
	var self = this;
	var zoom = this.map.getZoom();
	var show_all = false;
	if(zoom == this.map.getCurrentMapType().getMaximumResolution()){ 
		show_all = true;
	}
	
  if(zoom >= self.MIN_POINT_ZOOM){
    var bnds = bounds || self.map.getBounds();
    var sw = bnds.getSouthWest();
    var ne = bnds.getNorthEast();
		var params = { sw_lat : sw.lat(), sw_lng : sw.lng(), 
	                 ne_lat : ne.lat(), ne_lng : ne.lng(),
								   show_all: show_all};
								
		if(this.portalMode){ params["portal"] = this.portal;}
				
    new Ajax.Request("/browse/map/find_sites_in_bounds",
        { method: 'post',
          parameters: params, 
          onSuccess: function(req){
            self.drawSitePoints(eval('(' + req.responseText + ')'));
          },
          asynchronous:true, evalScripts:true
        });
  }
  else{
    self.clearExistingPoints();
  }
}

// pointObjects => array of [lat, lng] pairs
BrowseMap.prototype.drawSitePoints = function(pointObjects, useProgressBar){
	var self = this;
	// var progressBar;
	// if(useProgressBar){
	// 	progressBar = new ProgressbarControl(self.map, {width:150}); 
	// 	progressBar.start(pointObjects.length);
	// };

  this.clearExistingPoints();	
  pointObjects.each(function(ptObj){
    var point = new GLatLng(ptObj[0], ptObj[1]);
    var marker = new GMarker(point, {icon: self.icons.defaultIcon});

    GEvent.addListener(marker, 'click', function(pt){
      self.findSitesFromPoint(pt);
    });
    
    self.site_points.push(marker);
		if(self.clusterer){ self.clusterer.AddMarker(marker, "");}
		else{ self.map.addOverlay(marker);}

		//if(useProgressBar){progressBar.updateLoader(1);}
  });

	// if(useProgressBar){progressBar.remove();}
}

BrowseMap.prototype.clearExistingPoints = function(){
  for(var i=0, j=this.site_points.length; i<j; i++){
    this.map.removeOverlay(this.site_points.pop());
  }
}

BrowseMap.prototype.zoomToPoints = function(){
	var self = this;
	var ptslen = this.site_points.length;

	if(ptslen > 0){
		var startpt = this.site_points[0].getLatLng();
		var maxlat = startpt.lat();
		var maxlng = startpt.lng();
		var minlat = startpt.lat();
		var minlng = startpt.lng();
		
		for(var i=1; i < ptslen; i++){
			var pt = this.site_points[i].getLatLng();
			if(maxlat < pt.lat()){maxlat = pt.lat();}
			if(maxlng < pt.lng()){maxlng = pt.lng();}
			if(minlat > pt.lat()){minlat = pt.lat();}
			if(minlng > pt.lng()){minlng = pt.lng();}
		}
	
		var bounds = new GLatLngBounds(new GLatLng(minlat, minlng), new GLatLng(maxlat, maxlng));
		self.map.setCenter(bounds.getCenter(), self.map.getBoundsZoomLevel(bounds));
			
		if(self.map.getZoom() < 3){
			self.map.setZoom(3);
		}
	}
}


BrowseMap.prototype.createMapPointAppearEvent = function(){
	var self = this;
  this.zoomendEvent = GEvent.addListener(self.map, 'zoomend', function(){
    self.findSitesInBounds();
  });
  this.moveendEvent = GEvent.addListener(self.map, 'moveend', function(){
    self.findSitesInBounds();
  });   
}

BrowseMap.prototype.removeMapPointAppearEvent = function(){
	var self = this;
	GEvent.removeListener(self.zoomendEvent);
	GEvent.removeListener(self.moveendEvent);
}





