function MapLoader()
{
}
MapLoader.url = "locations/"; // CitySummaryResource/APILocationListJSONView
MapLoader.map = null;
MapLoader.center = null;
MapLoader.manager = null;
MapLoader.markers = new Hash(); // global hash (for all types of Locations) to check they are on the map already (based on ID)
MapLoader.PADDING_LAT = 0.2;
MapLoader.PADDING_LNG = 0.6;
MapLoader.ZOOM_COUNTRY = 7;
MapLoader.ZOOM_CITY = 12;
MapLoader.ZOOM_STREET = 14;
MapLoader.BLUE_ICON = new GIcon(G_DEFAULT_ICON);
MapLoader.BLUE_ICON.image = "http://www.whatsup.lt/static/images/blue-marker.png";
MapLoader.YELLOW_ICON = new GIcon(G_DEFAULT_ICON);
MapLoader.YELLOW_ICON.image = "http://www.whatsup.lt/static/images/yellow-marker.png";

MapLoader.init = function(control, host, lat, lng, zoomLevel)
{
	MapLoader.url = host + MapLoader.url;

	if (GBrowserIsCompatible())
	{
		MapLoader.map = new GMap2(control);

		MapLoader.center = new GLatLng(lat, lng);
		MapLoader.map.setCenter(MapLoader.center, zoomLevel);

		MapLoader.manager = new MarkerManager(MapLoader.map, { borderPadding: 0 } );

		MapLoader.map.addControl(new GSmallMapControl());
		MapLoader.map.addControl(new GMapTypeControl());
		GEvent.addListener(MapLoader.map, "moveend", MapLoader.update);
		GEvent.addListener(MapLoader.map, "zoomend", MapLoader.update);

		MapLoader.update();
	}
}

MapLoader.update = function()
{
	var bounds = MapLoader.map.getBounds();
	var centerLat = (bounds.getSouthWest().lat() + bounds.getNorthEast().lat()) / 2;
	var centerLng = (bounds.getSouthWest().lng() + bounds.getNorthEast().lng()) / 2;
	var width = bounds.getNorthEast().lng() - bounds.getSouthWest().lng() + MapLoader.PADDING_LNG * 2;
	var height = bounds.getNorthEast().lat() - bounds.getSouthWest().lat() + MapLoader.PADDING_LAT * 2;

	MapLoader.load(MapLoader.map, centerLat, centerLng, width, height);
}

MapLoader.load = function(map, centerLat, centerLng, width, height)
{
	var url = MapLoader.url + "?center=" + encodeURIComponent(centerLat) + "," + encodeURIComponent(centerLng) + "&span=" + encodeURIComponent(width) + "," + encodeURIComponent(height) + "&view=json";
	//alert(url);
	$.getJSON(url, function(result) { MapLoader.process(result.Array); });
}

MapLoader.process = function(locations)
{
	if (locations != null)
	{
		MapLoader.clean();

		var markers = new Array(); // markers by type; not to be confused with the global MapLoader.markers hash
		markers.City = new Array();
		markers.Street = new Array();
		markers.Building = new Array();

		if ("City" in locations) markers.City = MapLoader.locations2markers(locations.City);
		if ("Street" in locations) markers.Street = MapLoader.locations2markers(locations.Street);
		if ("Building" in locations) markers.Building = MapLoader.locations2markers(locations.Building);

		MapLoader.fill(MapLoader.map, markers);
	}
}

MapLoader.locations2markers = function(locations)
{
	var markers = null;
	if (locations != null)
	{
		markers = new Array();

		for (var i in locations)
		{
			var location = locations[i];
			var key = "index" + location.id;
			if (!MapLoader.markers.containsKey(key)) // if does not exist yet
			{
				var latLng = new GLatLng(location.lat, location.lng);
				var icon = null;
				if (latLng.equals(MapLoader.center)) icon = MapLoader.YELLOW_ICON;
				else icon = MapLoader.BLUE_ICON;
				var marker = new GMarker(latLng, { title: location.FullName, icon: icon });
				marker.location = location;
				GEvent.addListener(marker, "click", function() { window.location = "http://" + window.location.host + "/" + this.location.resource; }); 
				
				markers.push(marker);
				MapLoader.markers.put(key, marker);
			}
		}
	}
	return markers;
}

MapLoader.clean = function() // remove markers which are out of map bounds
{
	var bounds = MapLoader.map.getBounds(); 
	var temp = new Hash();

	for (var i in MapLoader.markers.values())
	{
		var marker = MapLoader.markers.get(i);

		if (!(marker.getLatLng().lat() > bounds.getSouthWest().lat() - MapLoader.PADDING_LAT && marker.getLatLng().lat() < bounds.getNorthEast().lat() + MapLoader.PADDING_LAT && marker.getLatLng().lng() > bounds.getSouthWest().lng() - MapLoader.PADDING_LNG && marker.getLatLng().lng() < bounds.getNorthEast().lng() + MapLoader.PADDING_LNG)) MapLoader.manager.removeMarker(marker);
		else temp.put("index" + marker.location.id, marker);
	}

	MapLoader.markers = temp;
}

MapLoader.fill = function(map, markers)
{
	if (markers != null)
	{
		for (var i in markers.City)
			MapLoader.manager.addMarker(markers.City[i], MapLoader.ZOOM_COUNTRY, MapLoader.ZOOM_CITY - 1);
		for (var i in markers.Street)
			MapLoader.manager.addMarker(markers.Street[i], MapLoader.ZOOM_CITY, MapLoader.ZOOM_STREET - 1);
		for (var i in markers.Building)
			MapLoader.manager.addMarker(markers.Building[i], MapLoader.ZOOM_STREET);
		
		/*
		MapLoader.manager.addMarkers(markers.City, MapLoader.ZOOM_COUNTRY, MapLoader.ZOOM_CITY - 1);
		MapLoader.manager.addMarkers(markers.Street, MapLoader.ZOOM_CITY - 1);
		MapLoader.manager.addMarkers(markers.Building, MapLoader.ZOOM_STREET);
		MapLoader.manager.refresh();
		*/
	}
}

function Hash()
{
	this.array = new Array();
}
//Hash.prototype.array;

Hash.prototype.get = function(key)
{
    if (this.containsKey(key)) return this.array[key];
	else return null;
}

Hash.prototype.put = function(key, value)
{
    this.array[key] = value;
}

Hash.prototype.values = function()
{
    return this.array;
}

Hash.prototype.containsKey = function(key)
{
    return typeof(this.array[key]) != "undefined";
}

/*
$.ajaxSetup({"error":function(XMLHttpRequest,textStatus, errorThrown)
{
  alert(textStatus);
  alert(errorThrown);
  alert(XMLHttpRequest.responseText);
}
});
*/
