// This function doesnt have a constructor of its own, but objects that extend this class can put 
// this.start() in its own constructor to kick things off automatically.


Local = function() {}; 

Local.prototype.start = function()
{
	this.map = new GMap2(document.getElementById("map"));
	
	var that = this;
	
	// Register an AJAX reponder to show/hide the activity indicator 
	// when perform an ajax request.
	Ajax.Responders.register(
	{
		onCreate: function() 
		{
			if (Ajax.activeRequestCount > 0 && ($('ajax-activity') && $('ajax-activity').visible() === false))
			{
				$('ajax-activity').show();
			}
		},
		onComplete: function() 
		{
			if (Ajax.activeRequestCount === 0 && ($('ajax-activity') && $('ajax-activity').visible() === true))
			{
				$('ajax-activity').hide();
			}
		}
	});
	
	
	// Fire up the ajax and load the initial set of spots.
	ajax = new Ajax.Request('/ajax/get_user_lat_long/', 
	{
		method: 'get',
		onSuccess: function (transport, json) 
		{
			json = eval(transport.responseText);
			
			that.userLat = json.lat;
			that.userLong = json.long;
			that.localLevel = json.local_level;
			that.ISO2 = json.ISO2;
			that.setUpMap();
		}
	});	
}

//Local.prototype.MIN_ZOOM_LEVEL = 3;
	
Local.prototype.setUpMap = function()
{
	
	
	// NASTY VANS HACK.
	// If this is the vans local micro site wassit, we dont want to change where the map starts.
	if ($('vans-map-container'))
	{
		this.map.setCenter(new GLatLng(52.37805176,-3.43597293), 5);
	}
	else
	{
		this.map.setCenter(new GLatLng(this.userLat, this.userLong), this.getInitialZoomLevel());	
	}
	
	this.map.setUIToDefault();
	
	// Turn on scroll zooming.
	this.map.enableScrollWheelZoom(); 
	
	// Disable wheel scrolling if the user is over the map.
	// http://esa.ilmari.googlepages.com/scrollzoom.htm
	GEvent.addDomListener(this.map.getContainer(), "DOMMouseScroll", this.disableWheelEvent);
	this.map.getContainer().onmousewheel = this.disableWheelEvent; 
	
	var that = this;
	GEvent.addListener(this.map, "zoomend", function(oldZoom,newZoom) 
	{
		if (newZoom > oldZoom)
		{ 
			// When zooming with a window open, the map tends to pan it sels 
			// to the new window. To sort that, we'll just refocus on that open window
			// anwyay when zooming.
			if (that.map.getExtInfoWindow())
			{
				that.map.setCenter(that.map.getExtInfoWindow().marker_.getLatLng());
			}
		} 
		
		that.buildMapPoints();
	});

	GEvent.addListener(this.map, "moveend", function() 
	{
			that.buildMapPoints();
	});

	// Set default map type to terrain map
	this.map.setMapType(G_SATELLITE_MAP);
	
	
	// Bind our clicks
	//GEvent.addListener(this.map, "click", this.leftClick);
	
	// Remove the types we dont want.
	this.map.removeMapType(G_HYBRID_MAP);
	G_PHYSICAL_MAP.getMinimumResolution 	= function () { return 3 }; 
	G_NORMAL_MAP.getMinimumResolution 		= function () { return 3 }; 
	G_SATELLITE_MAP.getMinimumResolution 	= function () { return 3 }; 
	
	// And add the one we do.
	this.map.addMapType(G_SATELLITE_MAP);
	
	// Add the zoom/pan controls.
	//this.map.addControl(new GMapTypeControl());
	//this.map.addControl(new GLargeMapControl(), new GControlPosition(G_ANCHOR_TOP_LEFT,  new GSize(25,10)));
	//this.map.addControl(new GScaleControl());
	//this.map.addControl(new GOverviewMapControl())
	
	// Custom one, for suggesting a spot
	this.map.addControl(new SuggestSpotControl());
	
	
	
	// Resize the map for the first time.
	//this.resizeMap();
	
	// Kick off the zoom check
	var that = this;
	
	easeZoomOut = function()
	{
		var paragraphs = that.map.getContainer().getElementsByTagName('p').length;
		
		if(paragraphs > 6)
		{
			that.map.zoomOut();
		}
	}
	
	interval = setInterval(easeZoomOut,500);
	
	//MPORA.local.markerManager = new GMarkerManager(MPORA.local.map);
	
	//MPORA.local.addExistingPoint(MPORA.local.getLatLong(51.49121712928709, -0.1750946044921875), 'HALLO THAR!');
	//MPORA.local.addExistingPoint(MPORA.local.getLatLong(51.525585, -0.059202), 'HALLO THAR!');
	//MPORA.local.addExistingPoint(MPORA.local.getLatLong(-77.70720537443079, -48.7298583984375), '<b>So very cold!</b>', 10);
	
	this.constructIcons();
	
	this.buildMapPoints();
}

Local.prototype.constructIcons = function()
{
	this.baseUserIcon = new GIcon();
	this.baseUserIcon.shadow = MPORA.globalVars.static+"resources/images/site/user_pin_shaddow.png";
	this.baseUserIcon.iconSize = new GSize(42,32);
	this.baseUserIcon.shadowSize = new GSize(42, 32);
	this.baseUserIcon.iconAnchor = new GPoint(9, 32);
	this.baseUserIcon.infoWindowAnchor = new GPoint(51,0);
	this.baseUserIcon.infoShadowAnchor = new GPoint(13, 28);	
	
	
	this.baseSpotIcon = new GIcon();
	this.baseSpotIcon.shadow = MPORA.globalVars.static+"resources/images/site/spot_shaddow.png";
	this.baseSpotIcon.iconSize = new GSize(56,35);
	this.baseSpotIcon.shadowSize = new GSize(56,35);
	this.baseSpotIcon.iconAnchor = new GPoint(17,35);
	this.baseSpotIcon.infoWindowAnchor = new GPoint(50,0);
}
	
Local.prototype.getInitialZoomLevel = function()
{
	var zoomLevel = this.MIN_ZOOM_LEVEL;
	
	if (this.localLevel == 'country')
	{
		zoomLevel = 5;
		
		// Because the US, China, Australia and Canada are so big, we need to make an exception and zoom further out to take it in.
		if (this.ISO2 == 'US' || this.ISO2 == 'CN' || this.ISO2 == 'CA' || this.ISO2 == 'AU')
		{
			zoomLevel = 4;	
		}
		
		// Well russial is just extra huge. Zoom even further out.
		if (this.ISO2 == 'RU')
		{
			zoomLevel = 3;	
		}
		
	}
	else if (this.localLevel == 'local')
	{
		zoomLevel = 9;	
	}
	
	return zoomLevel;	
}

	
// Take input data from various sources (ajax, inline etc) and use it to add markers, and HTML windows to the map.
// point = lat/long object.
// htmlSrc = html plaintext source for the overlay window
// maxZoomLevel/minZoomLevel set the max/min zoom levels that this marker will appear at. 
Local.prototype.addExistingPoint = function(opts, id)
{
	//console.log(opts.spot_type);
	minZoomLevel = opts.minZoomLevel || this.MIN_ZOOM_LEVEL;
	
	if (opts.spot_type == 'my_spot' || opts.spot_type == 'friend_spot')
	{
		// Some sort of user pin.
		var spotIcon = new GIcon(this.baseUserIcon);
		
		if (opts.spot_type == 'my_spot')
		{
			spotIcon.image = MPORA.globalVars.static_base_url+"resources/images/site/user_blue_pin.png";	
		}
		else
		{
			spotIcon.image = MPORA.globalVars.static_base_url+"resources/images/site/user_red_pin.png";
		}
	}
	else
	{
		// Some sort of spot pin.
		var spotIcon = new GIcon(this.baseSpotIcon);
		
		spotIcon.image = MPORA.globalVars.static_base_url+'resources/images/site/'+opts.spot_type+'_spot.png';
	}

	
	var marker = new GMarker(opts.point, {icon:spotIcon});
	var that = this;

	if ($('vans-map-container'))
	{	  
		Event.observe($('vans-map-'+id), 'click', function()
		{ 				
			that.map.closeExtInfoWindow();
			
			var elm = $('vans-map-'+id);
			
			var latlng = elm.rel.split(',');
			
			that.map.setCenter(new GLatLng(latlng[0],latlng[1]), 15); 

			marker.openExtInfoWindow
			(
				that.map,
				"spot-local-infowindow",
				opts.htmlSrc,
				{beakOffset: 2}
			); 
			
			Event.stop(event);
		});
	}
	
	GEvent.addListener(marker, 'click', function()
	{ 
		marker.openExtInfoWindow
		(
			that.map,
			((opts.spot_type == 'my_spot' || opts.spot_type == 'friend_spot') ? opts.spot_type : 'spot' ) + "-local-infowindow",
			opts.htmlSrc,
			{beakOffset: 2}
		); 
	});
	
	this.clusterPoints.push(marker);
	
	return marker;
}
	
// Returns the latlong object required by google, given the lat/long as floats.
Local.prototype.getLatLong = function(lat, long)
{
	return new GLatLng(lat, long);
} 

// This function stops the default browser mouse wheel scroll action
// http://esa.ilmari.googlepages.com/scrollzoom.htm
Local.prototype.disableWheelEvent = function(e)
{
	if (!e)
	{
		e = window.event;
	}
	
	if (e.preventDefault)
	{
		e.preventDefault()
	}
	
	e.returnValue = false;
}


// SUGGEST SPOT
// Custom control to sit on top of a google map.
function SuggestSpotControl() {}

SuggestSpotControl.prototype = new GControl();

// Create the html for this control.
SuggestSpotControl.prototype.initialize = function(map)
{
	var suggestSpotDivContainer = document.createElement("div");
	suggestSpotDivContainer.style.width = '198px';
	suggestSpotDivContainer.style.backgroundColor = 'white';
	suggestSpotDivContainer.style.cursor = 'pointer';
	suggestSpotDivContainer.style.border = '1px solid black';
	suggestSpotDivContainer.style.textAlign = 'center';
	
	var suggestSpotDiv = document.createElement("div");
	suggestSpotDivContainer.appendChild(suggestSpotDiv);
	suggestSpotDiv.appendChild(document.createTextNode("Suggest a Spot"));
	
	suggestSpotDiv.style.borderTop 		= '1px solid white';
	suggestSpotDiv.style.borderLeft 	= '1px solid white';
	suggestSpotDiv.style.borderRight 	= '1px solid #B0B0B0';
	suggestSpotDiv.style.borderBottom 	= '1px solid #B0B0B0';
	suggestSpotDiv.style.fontSize 		= '12px';
	suggestSpotDiv.style.fontWeight 	= 'bold';
	
	GEvent.addDomListener(suggestSpotDivContainer, "click", function() 
	{
		window.location.href = '/suggest/';
	});
	
	map.getContainer().appendChild(suggestSpotDivContainer);
	
	return suggestSpotDivContainer;
}

// By default, the control will appear in the top left corner of the
// map with 7 pixels of padding.
SuggestSpotControl.prototype.getDefaultPosition = function() 
{
  return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(7,35));
}


/* Extended from Local, a map for adding points to a database */

AddMap = function()
{
	this.start();
}

AddMap.prototype = new Local();

AddMap.prototype.setUpMap = function()
{
	var that = this;
	var initialZoom = this.getInitialZoomLevel();
	
	var lat = this.userLat;
	var long = this.userLong;
	
	
	
	if ($('spot_lat') && $F('spot_lat') && $F('spot_long'))
	{
		lat 		= $F('spot_lat');
		long 		= $F('spot_long');
		initialZoom = 15;
		this.map.setCenter(new GLatLng(lat, long), initialZoom);
		this.addPoint(false, new GLatLng(lat, long), this);
	}
	else
	{	
		this.map.setCenter(new GLatLng(lat, long), initialZoom);	
	}
	
	
	
	// Turn on scroll zooming.
	this.map.enableScrollWheelZoom(); 
	
	// Disable wheel scrolling if the user is over the map.
	// http://esa.ilmari.googlepages.com/scrollzoom.htm
	GEvent.addDomListener(this.map.getContainer(), "DOMMouseScroll", this.disableWheelEvent);
	this.map.getContainer().onmousewheel = this.disableWheelEvent; 
	
	// Bind our clicks
	GEvent.addListener(this.map, "click", function (src, cords) { that.addPoint(src, cords, that); });
	//zoomend
	GEvent.addListener(this.map, "zoomend", function (oldZoom, newZoom) 
	{
		that.zoomLevelWarning(newZoom);
	});
	
	
	// Remove the types we dont want.
	this.map.removeMapType(G_HYBRID_MAP);
	
	G_PHYSICAL_MAP.getMinimumResolution 	= function () { return 3 }; 
	G_NORMAL_MAP.getMinimumResolution 		= function () { return 3 }; 
	G_SATELLITE_MAP.getMinimumResolution 	= function () { return 3 }; 
	
	// And add the one we do.
	this.map.addMapType(G_PHYSICAL_MAP);
	
	// Add the zoom/pan controls.
	this.map.addControl(new GMapTypeControl());
	this.map.addControl(new GLargeMapControl());
	this.map.addControl(new GScaleControl());
	
	// Kick off the zoom check
	var that = this;
	
	easeZoomOut = function()
	{
		var paragraphs = that.map.getContainer().getElementsByTagName('p').length;
		
		if(paragraphs > 6)
		{
			that.map.zoomOut();
		}
	}
	
	interval = setInterval(easeZoomOut,500);
}

AddMap.prototype.addPoint = function(src, cords, that)
{
	if (!src)
	{

		that.map.clearOverlays();

		var marker = new GMarker(cords, {draggable: true});

		GEvent.addListener(marker, "dragend", 	function () { that.pointUpdate(marker); });

		that.map.addOverlay(marker);

		that.pointUpdate(marker);

		that.mapHasMarker_ = true;
		
		that.zoomLevelWarning();
	}
	else
	{
		this.map.setCenter(src.getLatLng(), 14);	
	}	
}

AddMap.prototype.zoomLevelWarning = function(zoomLevel)
{
	zoomLevel = zoomLevel || this.map.getZoom();
	
	if (this.mapHasMarker_)
	{
		if (zoomLevel >= 14)
		{
			if ($('local-zoom-warning'))
			{
				new Effect.Fade($('local-zoom-warning'), {duration:1});
				if ($('local-edit-submit'))
				{
					$('local-edit-submit').enable();
				}
			}
			
		}
		else
		{
			if ($('local-zoom-warning'))
			{
				new Effect.Appear($('local-zoom-warning'), {duration:1});
				
				if ($('local-edit-submit'))
				{
					$('local-edit-submit').disable();
				}
			}
		}
	}
}

// If the point has been updated, update the form fields that (should!) be on the page.
AddMap.prototype.pointUpdate = function (marker)
{
		if ($('spot_lat_readonly'))
		{
			var latlng = marker.getLatLng();
			
			$('spot_lat_readonly').value = latlng.lat();
			$('spot_long_readonly').value = latlng.lng();
			$('spot_lat').value = latlng.lat();
			$('spot_long').value = latlng.lng();
		}
}		