﻿
MkMap = new (function ()
{
	var __this = this;

	////	// map center (Zagreb)
	////	var mLatitude = 45.805709;
	////	var mLongitude = 15.979443;

	// map center (Prijedor)
	var mLatitude = 44.9813889;
	var mLongitude = 16.7130556;

	var mMarkedLatLng = null;

	var mMap = null;
	var mCenter = null;
	var mZoom = null;
	var mMapBounds = null;
	var mPoligons = {};

	var mSelectedPolygon = null;

	__this.GetKvartMapInfo = function ()
	{
		if (mSelectedPolygon && mSelectedPolygon.GeoMapInfo && mSelectedPolygon.GeoMapInfo)
		{
			//  GeoMapInfo: KvartID, Naziv, Points; Points is array of objects with Latitude and Longitude
			var path = mSelectedPolygon.getPath();
			var arr = path.getArray();
			mSelectedPolygon.GeoMapInfo.Points = [];
			ForEach(arr, function (o, index)
			{
				mSelectedPolygon.GeoMapInfo.Points.push({
					Latitude: o.lat(),
					Longitude: o.lng()
				});
			});
			return mSelectedPolygon.GeoMapInfo;
		}
		return null;
	};

	__this.RunEdit = function (edit)
	{
		if (mSelectedPolygon && mSelectedPolygon.runEdit)
		{
			if (edit)
			{
				mSelectedPolygon.runEdit();
			}
			else
			{
				mSelectedPolygon.stopEdit();
			}
		}
	};

	function ForEach(enumerable, delegate)
	{
		if (enumerable && enumerable.charAt) // string
		{
			for (var nn = 0; nn < enumerable.length; nn++)
			{
				delegate(enumerable[nn], nn);
			}
		}
		else if (enumerable) // object or array
		{
			for (var pp in enumerable)
			{
				delegate(enumerable[pp], pp);
			}
		}
	}

	function BindContext(method, context)
	{
		var context = context || this; // if context is not defined
		return (function () { return method.apply(context, arguments); });
	}

	function GetColor(seed, borderColor)
	{
		var color;
		if (!borderColor)
		{
			var rint;
			do
			{
				rint = Math.round(0xffffff * Math.random(seed));
			}
			while ((rint / 0xffff > 0x50) || (rint / 0xff % 0xff > 0x50) || (rint % 0xff > 0x50));

			color = ('#0' + rint.toString(16)).replace(/^#0([0-9a-f]{6})$/i, '#$1');
		}
		else
		{
			color = borderColor.slice(0, 5);
			color += "99";
		}

		return color;
	}

	function SetVisibleKvartLabels(visible)
	{
		ForEach(mPoligons, function (o) { o.label.setVisible(visible); });
	}

	function SetVisiblePoligons(visible)
	{
		ForEach(mPoligons, function (o) { o.polygon.setVisible(visible); });
	}

	function RemovePoligons()
	{
		ForEach(mPoligons, function (o)
		{
			o.label.setMap(null);
			o.polygon.setMap(null);
		});
		mPoligons = null;
	}

	function DrawPoligons(result, circles, showOnMouseOverOnly, selectedKvartID, showAllPoligons)
	{
		mPoligons = [];
		if (!result || result.length == 0)
		{
			return; // nema kvartova
		}

		var mapBoundsAlreadyFound = false;

		var mapBounds = new google.maps.LatLngBounds();

		for (var n = 0; n < result.length; n++)
		{
			var kvart = result[n]; // KvartID, Naziv, Points; Points is array of objects with Latitude and Longitude
			var borderColor = "#f99f16"; //GetColor(kvart.KvartID || kvart.GradID);
			var polygonCoords = [];
			ForEach(kvart.Points, function (o) { polygonCoords.push(new google.maps.LatLng(o.Latitude, o.Longitude)) });

			if (polygonCoords.length < 1)
			{
				continue;
			}

			var polygon;

			if (circles)
			{
				polygon = new google.maps.Circle({
					center: polygonCoords[0],
					strokeColor: "#FF0000",
					radius: kvart.Radijus // meters
				});
			}
			else
			{
				polygon = new google.maps.Polygon({
					paths: polygonCoords,
					strokeColor: (showAllPoligons && selectedKvartID == kvart.KvartID) ? "#ff0000" : "#164376"
				});
			}

			polygon.setOptions({
				strokeOpacity: 0.8,
				fillColor: (showAllPoligons && selectedKvartID == kvart.KvartID) ? "#ff0000" : "#509edf",
				strokeWeight: 2,
				fillOpacity: 0.20
			});

			polygon.setMap(mMap);

			polygon.GeoMapInfo = kvart;

			var kvartBounds = new google.maps.LatLngBounds();
			ForEach(polygonCoords, function (o) { kvartBounds.extend(o); });
			var kvartCenter = kvartBounds.getCenter(); // polygon center

			if (!mapBoundsAlreadyFound)
			{
				if (result.length > 1)
				{
					mapBounds.extend(kvartCenter);
				}
				else
				{
					mapBounds = kvartBounds;
				}
			}

			var label = new google.maps.Label({
				map: mMap,
				position: kvartCenter,
				visible: false
			});


			label.set("text", kvart.Naziv);
			polygon.label = label;
			polygon.listeners = [];


			if (circles)
			{
				polygon.setVisible(true);
				label.setVisible(false);
			}
			else if (showAllPoligons || selectedKvartID == kvart.KvartID)
			{
				polygon.setVisible(true);
				label.setVisible(true);
				if (selectedKvartID == kvart.KvartID)
				{
					mSelectedPolygon = polygon;

					mapBounds = kvartBounds; // trenutni kvart postavi u centar mape
					mapBoundsAlreadyFound = true;

					if (showAllPoligons && polygon.runEdit)
					{
						////	polygon.runEdit();
					}
				}
			}
			else if (showOnMouseOverOnly)
			{
				polygon.setVisible(false);
				label.setVisible(false);

				polygon.listeners.push(google.maps.event.addListener(polygon, 'mouseover', BindContext(function () { this.label.setVisible(true); this.setVisible(true); }, polygon)));
				polygon.listeners.push(google.maps.event.addListener(polygon, 'mouseout', BindContext(function () { this.label.setVisible(false); this.setVisible(false); }, polygon)));
			}

			polygon.listeners.push(google.maps.event.addListener(polygon, 'click', BindContext(function ()
			{
				if (__this.HandlePoligonClick)
				{
					__this.HandlePoligonClick(this.GeoMapInfo.GradID, this.GeoMapInfo.KvartID);
				}
			}, polygon)));


			// cache the result
			mPoligons.push({
				polygon: polygon,
				center: kvartCenter,
				label: label
			});
		}

		mMapBounds = mapBounds;

		////if (!circles)
		{
			mMap.fitBounds(mMapBounds);
		}

		setTimeout(function ()
		{
			mCenter = mapBounds.getCenter(); // map center		
			if (circles)
			{
				var zoom = mMap.getZoom();
				mMap.setZoom(zoom + 1);
			}
		}, 500);

	}

	function Deserialize(jsonString)
	{
		var exp = jsonString.replace(new RegExp('(^|[^\\\\])\\"\\\\/Date\\((-?[0-9]+)\\)\\\\/\\"', 'g'), "$1new Date($2)"); // Unix time (miliseconds), MS Ajax compatibility
		return eval('(' + exp + ')');
	}

	function CreateKvartoviPoligons(currentGradID, currentKvartID, showAllPoligons)
	{
		if (mResultCache)
		{
			DrawPoligons(mResultCache, false, true, currentKvartID, showAllPoligons);
		}
		else
		{
			MojKvart.WebService.GMapInteraction.GetKvartoviMapInfos(currentGradID, function (result)
			{
				mResultCache = result;
				setTimeout(function () { DrawPoligons(result, false, true, currentKvartID, showAllPoligons); }, 1); // draw from new thread
			});
		}
	}

	function CreateGradoviPoligons()
	{
		if (mResultCache)
		{
			DrawPoligons(mResultCache, true, false);
		}
		else
		{
			MojKvart.WebService.GMapInteraction.GetGradoviMapInfos(function (result)
			{
				mResultCache = result;
				setTimeout(function () { DrawPoligons(result, true, false); }, 1); // draw from new thread
			});
		}
	}

	__this.CreateMap = function () // trenutni grad
	{
		var latLng = new google.maps.LatLng(mLatitude, mLongitude);

		mMap = new google.maps.Map(document.getElementById('map_canvas'), {
			zoom: 4,
			center: latLng,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		});

		google.maps.event.addListener(mMap, 'zoom_changed', function ()
		{
			var zoom = mMap.getZoom();
		});

		google.maps.event.addListener(mMap, 'click', function (e)
		{
			if (__this.HandleAdminInfoClick)
			{
				var latitude = e.latLng.lat();
				var longitude = e.latLng.lng();

				__this.HandleAdminInfoClick(latitude, longitude);

				var iw = infowindow && infowindow[0] && infowindow[0].content ? infowindow[0].content : null;

				__this.UnmarkLocation();

				__this.MarkLocation(null, latitude, longitude, iw);
			}
		});

	}

	var mResultCache = null;

	__this.LoadJson = function (json)
	{
		if (json && json.charAt) // is is string
		{
			mResultCache = Deserialize(json);
		}
		else // object itself
		{
			mResultCache = json;
		}
	};

	__this.ShowPoligons = function (gradID, kvartID, showAllPoligons)
	{
		if (gradID > 0)
		{
			CreateKvartoviPoligons(gradID, kvartID, showAllPoligons);
		}
		else
		{
			CreateGradoviPoligons(); // hrvatska
		}
	};

	__this.HandlePoligonClick = null;

	__this.HandleAdminInfoClick = null;

	__this.SavePosition = function ()
	{
		mCenter = mMap.getCenter();
		mZoom = mMap.getZoom();
	};

	__this.RestorePosition = function ()
	{
		mMap.fitBounds(mMapBounds);
		////mMap.panTo(mCenter);
	};

	var infowindow = [];
	var beachMarker = [];

	__this.MarkLocation = function (zoom, latitude, longitude, infoHtml)
	{
		if (__this.HandleAdminInfoClick)
		{
			__this.HandleAdminInfoClick(latitude, longitude);
		}

		mMarkedLatLng = new google.maps.LatLng(latitude, longitude);

		if (infoHtml && infoHtml.length > 0)
		{
			infowindow.push(new google.maps.InfoWindow({
				content: infoHtml,
				position: mMarkedLatLng,
				map: mMap
			}));
		}

		beachMarker.push(new google.maps.Marker({
			position: mMarkedLatLng,
			animation: google.maps.Animation.DROP,
			map: mMap
		}));

		if (zoom > 7 && zoom < 20)
		{
			mMap.setZoom(zoom);
		}

		mMap.panTo(mMarkedLatLng);


	};

	__this.MarkLocationByAddress = function (zoom, address, infoHtml, alternativeZoom, latitude, longitude)
	{
		var geocoder = new google.maps.Geocoder();

		geocoder.geocode({ 'address': address }, function (results, status)
		{
			if (status == google.maps.GeocoderStatus.OK)
			{
				latitude = results[0].geometry.location.lat();
				longitude = results[0].geometry.location.lng();

				__this.MarkLocation(zoom, latitude, longitude, infoHtml);
			}
			else if (latitude > 0 && longitude > 0)
			{
				__this.MarkLocation(alternativeZoom, latitude, longitude, infoHtml);
			}
			else
			{
				alert("Geocode was not successful for the following reason: " + status);
			}

	
		});
	};

	__this.UnmarkLocation = function ()
	{
		var o;
		while (o = infowindow.shift())
		{
			o.setMap(null);
		}

		while (o = beachMarker.shift())
		{
			o.setMap(null);
		}
	};

	__this.CreateRoute = function (travelMode, origin)
	{
		var directionsService = new google.maps.DirectionsService();

		var directionsDisplay = new google.maps.DirectionsRenderer();
		directionsDisplay.setMap(mMap);

		var request = {
			origin: origin,
			destination: mMarkedLatLng,
			travelMode: eval("google.maps.TravelMode." + travelMode)
		};

		directionsService.route(request, function (response, status)
		{
			if (status == google.maps.DirectionsStatus.OK)
			{
				directionsDisplay.setDirections(response);
			}
			else
			{
				alert("Google routing error!");
			}
		});
	};


})();




