var MapAPI = {

  theMap: null,
  icons: {},
  markers: {},
  eventsEnabled: true,
  logEnabled: false,
  directions: null,
  refreshDisabled: false,
  
  log: function(s)
    {
	if (this.logEnabled)
		google.maps.Log.write(s);
    },

  getClientLocation: function()
    {
	  if (google.loader.ClientLocation) 
  
	    return [google.loader.ClientLocation.latitude, google.loader.ClientLocation.longitude];
		
	  return null;	
	},	

  setClientLocationAsCenter: function(zoom)
    {
	  if (google.loader.ClientLocation) 
	    {
		this.setCenter(google.loader.ClientLocation.latitude,
					   google.loader.ClientLocation.longitude,
					   zoom);

		return true;
		}

	  return false;			
	},	

  init: function(element, smallControls)
    {
      var n1 = "overflow";
      var n2 = "hidden";

	  if (!google.maps.BrowserIsCompatible())
	    {
		  alert("Din webbläsare kan tyvärr ej visa Googles kartor");
		  return;
		}

	  var map = new google.maps.Map2($(element));

	  map.addMapType(G_PHYSICAL_MAP);

	  if (smallControls)
	  	  map.addControl(new google.maps.SmallMapControl());
	  else	  
	  	  map.addControl(new google.maps.LargeMapControl());

	  if (typeof google.maps.HierarchicalMapTypeControl == "undefined")
 	  	map.addControl(new google.maps.MapTypeControl(smallControls));
	  else
	  	map.addControl(new google.maps.HierarchicalMapTypeControl(smallControls));

	  map.enableDoubleClickZoom();
	  map.enableContinuousZoom();

	  google.maps.Event.addListener(map, "moveend", function()
	  	{
		  if (MapAPI.eventsEnabled == true)
		    onMapChange("moveend");	
		});

	  map.getContainer().style[n1]=n2;

	  this.theMap = map;
	},

  showOverviewMap: function()
    {
	  this.theMap.addControl(new google.maps.OverviewMapControl());
    },

  savePosition: function()
    {
      this.theMap.savePosition();
    },

  returnToSavedPosition: function()
    {
      this.theMap.returnToSavedPosition();
    },

  refresh: function()
    {
    this.theMap.checkResize();
    this.theMap.returnToSavedPosition();
    },	

  enableEvents: function()
	{
    this.log("enabling events");
	this.eventsEnabled = true;
	},

  disableEvents: function()
	{
    this.log("disabling events");
	this.eventsEnabled = false;
	},

  disableMarkerRefresh: function()
  {
    this.refreshDisabled = true;
  },
  
  enableMarkerRefresh: function()
  {
    this.refreshDisabled = false;
  },
  
  unload: function()
    {
	  google.maps.Unload(); 
	},

  getBounds: function()
    {
	  var bounds = this.theMap.getBounds();	  
	  var northEast = bounds.getNorthEast();
	  var southWest = bounds.getSouthWest();

	  return [northEast.lat(), southWest.lng(),
			  southWest.lat(), northEast.lng()];
	},

  getType: function()
    {
	  var type = this.theMap.getCurrentMapType();
      var stype = "";
	  
	  if (type == G_SATELLITE_MAP)
        stype = "satellite";
	  else if (type == G_HYBRID_MAP)
        stype = "hybrid";
	  else if (type == G_PHYSICAL_MAP)
        stype = "physical";
      else
	    stype = "normal";

	  return stype;	
    },

  setType: function(type)
    {
	  if (type == "satellite")
	    this.theMap.setMapType(G_SATELLITE_MAP);
	  else if (type == "hybrid")	
	    this.theMap.setMapType(G_HYBRID_MAP);
	  else if (type == "physical")	
	    this.theMap.setMapType(G_PHYSICAL_MAP);
	  else	
	    this.theMap.setMapType(G_NORMAL_MAP);
    },

  getCenter: function()
    {
	  var center = this.theMap.getCenter();
	  return [center.lat(), center.lng()];
	},
  
  setCenter: function(lat, lng, zoom)
    {
	  this.theMap.setCenter(new google.maps.LatLng(lat, lng), zoom);

	  if (this.theMap.getZoom() != zoom)
	  	this.theMap.setZoom(zoom);
	},

  panTo: function(lat, lng)
    {
	  this.theMap.panTo(new google.maps.LatLng(lat, lng));
	},

  panToMarker: function(markerID, open)
    {
	var marker = this.markers[markerID];
	var p = marker.getPoint();
	this.panTo(p.lat(), p.lng());

	if (open)
	  marker.openInfoWindowHtml(marker._geopos_info);
	},

  getZoom: function()
    {
	  return this.theMap.getZoom();
	},

  setZoom: function(i)
    {
	  this.theMap.setZoom(i);
	},

  zoomIn: function()
    {
	  this.theMap.zoomIn();
	},

  zoomOut: function()
    {
	  this.theMap.zoomOut();
	},

  replaceGeoPositionMarkers: function(positions, callbacks)
    {
	  var newMarkers = {};

	  for (var i = 0; i < positions.length; i++)
	  {
		var ID = positions[i].ID;

		if (this.markers[ID] )
		  {
			newMarkers[ID] = this.updateMarkerForGeoPosition(this.markers[ID], positions[i], callbacks, i+1);
		  }
		else
		  {
			newMarkers[ID] = this.createMarkerForGeoPosition(positions[i], callbacks, i+1);
		  }
	  }

	  for (var old in this.markers)
	  {
		if (!newMarkers[ old ] )
		{
		  this.removeMarker(this.markers[old]);
		}
	  }

	  this.markers = newMarkers;
	},

  highlightMarkerForGeoPosition: function(ID)
    {
      this.highlightMarker(this.markers[ID]);
    },

  unhighlightMarkerForGeoPosition: function(ID)
    {
      this.unhighlightMarker(this.markers[ID]);
    },

  highlightMarker: function(marker)
    {
	  var def = marker.getIcon().image;
	  marker.orgImage = def;

	  marker.setImage(this.getHighlightIconURL());
    },

  unhighlightMarker: function(marker)
    {
	  marker.setImage(marker.orgImage);
    },

  moveMarker: function(marker, lat, lng)
    {
	  var pos = new google.maps.LatLng(parseFloat(lat), parseFloat(lng));
	  marker.setPoint(pos);
    },

  closeInfoWindows: function()
    {
      this.theMap.closeInfoWindow();
    },

  createDraggableMarker: function(lat, lng, html, title)
	{
	  var xicon = this.getMapIcon("marker_target");
	  var pos = new google.maps.LatLng(parseFloat(lat), parseFloat(lng));

	  var marker = new google.maps.Marker(pos, { title: title, icon: xicon, draggable: true, bouncy: true });

	  if (html)
		 {
		 google.maps.Event.addListener(marker, "click", function()
		 	{
			  marker.openInfoWindowHtml(html);
			});
		 }

	  google.maps.Event.addListener(marker, "dragstart", function()
		  {
			MapAPI.theMap.closeInfoWindow();
		  });

	  google.maps.Event.addListener(marker, "dragend", function()
		  {
			var p = marker.getPoint();
			onMarkerMove(p.lat(), p.lng());
		  });

	  this.theMap.addOverlay(marker);

	  return marker;
	},

  createMarkerForGeoPosition: function(o, callbacks, idx)
    {
	  var pos = new google.maps.LatLng(parseFloat(o.latitude), parseFloat(o.longitude));
	  var xicon = this.getIconForGeoPosition(o, idx);

	  var tooltip;

	  if (o.title)
		 tooltip = o.title;

	  var marker = new google.maps.Marker(pos, { title: tooltip, icon: xicon });

	  marker._geopos_ID = o.ID;
	  marker._geopos_refclass = o.refclass;
	  marker._geopos_symbol = o.symbol;
	  marker._geopos_viewURL = o.viewURL;
	  marker._geopos_info = o.info;

	  if (callbacks && callbacks.click)
	    {
		  google.maps.Event.addListener(marker, "click", callbacks.click);
		}
	  else
	    {
		  google.maps.Event.addListener(marker, "click", function()
	  	    {
		    marker.openInfoWindowHtml(marker._geopos_info);
		    });
        }

	  if (callbacks && callbacks.mouseover)
	  	  google.maps.Event.addListener(marker, "mouseover", callbacks.mouseover);

	  if (callbacks && callbacks.mouseout)
	  	  google.maps.Event.addListener(marker, "mouseout", callbacks.mouseout);

    google.maps.Event.addListener(marker, "click", function()
    {
      MapAPI.disableMarkerRefresh();
    });
        
	  MapAPI.markers[ marker._geopos_ID ] = marker;

	  this.theMap.addOverlay(marker);

	  return marker;
	},

  updateMarkerForGeoPosition: function(marker, o, callbacks, idx)
    {
	  var xicon = this.getIconForGeoPosition(o, idx);

	  marker.setImage(xicon.image);

	  return marker;
	},

  removeMarker: function(m)
    {
	  this.theMap.removeOverlay(m);

	  if (m._geopos_ID)
	  	MapAPI.markers[ m._geopos_ID ] = null;
	},

  
  getIconForGeoPosition: function(pos, idx)
    {
      var name; 
	  var iconColor;

	  if (this.iconFinder)
         {
         name = this.iconFinder(pos);

	     return this.getMapIcon(name, idx);
         }
      else
         {
		 var className = pos.refclass;	
		 var symbol = pos.symbol;

		 if (className == "Photo")
		   	iconColor = "red";
		 else if (className == "Member")
	     	iconColor = "blue";
	     else if (className == "GeoFeature")
	  	    iconColor = "orange";
	     else if (className == "ClassifiedAd")
            iconColor = "green";
	     else
            iconColor = "red";

   	     if ((typeof(iconColor)=="undefined") || (iconColor==null))
	  	    iconColor = "red"; 

	     return this.getMapIcon("marker_" + iconColor, idx);
         }
	},

  getMapIcon: function(name, idx)
    {
	  if (!this.icons["default"])
	  {	
		// Create a base icon instance, cloned later 
		//
		this.icons["default"] = new google.maps.Icon(); 
		this.icons["default"].image = "/maps/images/marker_default.png"; 
		this.icons["default"].shadow="http://www.google.com/mapfiles/shadow50.png"; 
		this.icons["default"].iconSize=new google.maps.Size(20, 34); 
		this.icons["default"].shadowSize=new google.maps.Size(37, 34); 
		this.icons["default"].iconAnchor=new google.maps.Point(9,34); 
		this.icons["default"].infoWindowAnchor=new google.maps.Point(9,2); 
		this.icons["default"].infoShadowAnchor=new google.maps.Point(18,25); 
		this.icons["default"].printImage="http://www.google.com/mapfiles/markerie.gif"; 
		this.icons["default"].mozPrintImage="http://www.google.com/mapfiles/markerff.gif"; 
		this.icons["default"].printShadow="http://www.google.com/mapfiles/dithshadow.gif"; 
		this.icons["default"].transparent="http://www.google.com/mapfiles/markerTransparent.png";
		this.icons["default"].imageMap=[9,0,6,1,4,2,2,4,0,8,0,12,1,14,2,16,5,19,7,
										23,8,26,9,30,9,34,11,34,11,30,12,26,13,24,14,21,16,18,18,16,
										20,12,20,8,18,4,16,2,15,1,13,0]; 
	  }

      if (idx)
	    name += ("_" + idx);

	  if (!this.icons[name])
	    {
		this.icons[name] = new google.maps.Icon(this.icons["default"]);
		this.icons[name].image = "/maps/images/" + name + ".png";
	    } 
	
	  return this.icons[name];
	},

  getHighlightIconURL: function()
    {
		return "/maps/images/marker_highlight.png";
    },

  addTrackLog: function(n, doZoom)
    {
		var cb = function(data) { 
			if (data.kmlfile)
				{
				MapAPI.addKMLFile(data.kmlfile, doZoom);
				}
			else	
				{
				var def = {
					color: "#0000ff",
					weight: 4,
					points: data.encodedPoints,
					levels: data.levels,
					zoomFactor: data.zoomFactor,
					numLevels: data.numLevels
					};

				var pl = new google.maps.Polyline.fromEncoded(def);
				MapAPI.theMap.addOverlay(pl);

				if (doZoom && doZoom == true)
					{
					var bounds = pl.getBounds();
					var center = bounds.getCenter();
					var level = MapAPI.theMap.getBoundsZoomLevel(bounds);
					MapAPI.theMap.setCenter(center, level);
					}	

				}
			};

		asyncRpcCall("maps.getTrackLog", n, cb);
    },

  addKMLFile: function(file, doZoom)
    {
    try
	  {
	  var cb = function() {
	      if (gx.loadedCorrectly() && doZoom && doZoom == true)
		    gx.gotoDefaultViewport(MapAPI.theMap);
			};

	  var gx = new google.maps.GeoXml(file, cb);
	  if (gx)
	  	  MapAPI.theMap.addOverlay(gx);
	  }
	catch(err)
	  {
      alert("Google Maps kunde tyvärr ej ladda denna KML-fil " + err); 
      }
    },

  enableDirections: function(el) 
  {
    this.directions = new GDirections(this.theMap, el);
  },
  
  loadDirections: function(query)
  {
    this.directions.load(query);
  },
  
  dummy: null
}
