﻿/// <reference path="~/Resources/scripts/jquery-1.3.1-vsdoc.js" />
var map;
var trafficInfo = null;
var markers = new fMarkers();
var polylines = new fPolylines();
var polygons = new fPolygons();
var geodirections;
var miles;

var CURSOR_MOVE = "move";
var CURSOR_DRAW = "crosshair";

var MODE_PAN = "pan";
var MODE_DRAW = "draw";
var mapMode = MODE_DRAW;

var overViewCtrl = new GOverviewMapControl();

GPolyline.prototype.toDblArray = function()
{
	var line = this; // polylines.getLastValue();
	var pointcount = line.getVertexCount();
	var coords = new Array();
	var node = null;

	for (var index = pointcount - 1; index >= 0; index--)
	{
		node = line.getVertex(index);
		var p = new Array();
		p.push(node.lat());
		p.push(node.lng());
		coords.push(p);

	}

	return coords;
}

MyGMaps = {}
MyGMaps.FindMap = function()
{
	if (!map)
		loadMap();

	return { gMap: map, overViewCtrl: overViewCtrl };
}

function fMarkers()
{
	this.markers = new Array();
	this.getLength = function() { return this.markers.length; };
	this.pushValue = function(v) { this.markers.push(v); }
	this.getValue = function(i) { return this.markers[i]; }
	this.getLastValue = function() { return this.markers[this.markers.length - 1]; }
	this.getValueById = function(ID)
	{
		var i;
		for (i = 0; i < this.markers.length; i++)
		{
			if (this.markers[i].value == ID)
			{
				return this.markers[i];
			}
		}
		return null;
	}
	this.removeValueById = function(ID)
	{
		var i;
		for (i = 0; i < this.markers.length; i++)
		{
			if (this.markers[i].value == ID)
			{
				this.markers.splice(i, 1);
			}
		}
		return null;
	}
}

function fPolylines()
{
	this.polylines = new Array();
	this.polylinesID = new Array();
	this.getLength = function() { return this.polylines.length; };
	this.pushValue = function(v, ID) { this.polylines.push(v); this.polylinesID.push(ID); }
	this.getValue = function(i) { return this.polylines[i]; }
	this.getLastValue = function() { return this.polylines[this.polylines.length - 1]; }
	this.getValueById = function(ID)
	{
		var i;
		for (i = 0; i < this.polylinesID.length; i++)
		{
			if (this.polylinesID[i] == ID)
			{
				return this.polylines[i];
			}
		}
		return null;
	}
	this.removeValueById = function(ID)
	{
		var i;
		for (i = 0; i < this.polylinesID.length; i++)
		{
			if (this.polylinesID[i] == ID)
			{
				this.polylines.splice(i, 1);
				this.polylinesID.splice(i, 1);
			}
		}
		return null;
	}
}

function fPolygons()
{
	this.polygons = new Array();
	this.polygonsID = new Array();
	this.getLength = function() { return this.polygons.length; };
	this.pushValue = function(v, ID) { this.polygons.push(v); this.polygonsID.push(ID); }
	this.getValue = function(i) { return this.polygons[i]; }
	this.getLastValue = function() { return this.polygons[this.polygons.length - 1]; }
	this.getValueById = function(ID)
	{
		var i;
		for (i = 0; i < this.polygonsID.length; i++)
		{
			if (this.polygonsID[i] == ID)
			{
				return this.polygons[i];
			}
		}
		return null;
	}
	this.removeValueById = function(ID)
	{
		var i;
		for (i = 0; i < this.polygonsID.length; i++)
		{
			if (this.polygonsID[i] == ID)
			{
				this.polygons.splice(i, 1);
				this.polygonsID.splice(i, 1);
			}
		}
		return null;
	}
}

var elevationPoll = null;

function loadMap()
{
	if (GBrowserIsCompatible())
	{
		map = new GMap2($("#GMapContainer")[0], { draggableCursor: CURSOR_DRAW, draggingCursor: CURSOR_MOVE });

		switchMode(MODE_DRAW);

		GEvent.addListener(map, "click", mapClick);

		GEvent.addListener(map, "moveend", addMiles);
		GEvent.addListener(map, "zoomend", onZoomEnd);
		GEvent.addListener(map, "dragend", addMiles);
		

		markers = new fMarkers();
		polylines = new fPolylines();
		polygons = new fPolygons();

		geodirections = new GDirections(null, $("#route")[0]);
		GEvent.addListener(geodirections, "load", gdLoad);
		miles = new MileStones(map);

		GService.GetGoogleObject(fGetGoogleObject);

		elevationPoll = setInterval("if(polylines.getLength() > 0)GService.GetPolylineElevation(0, OnSucceeded, OnFailed);", 3000);
	}
}

function onZoomEnd()
{
	addMiles();
	GService.RecenterMapComplete(map.getZoom());
}

function switchMode(mode)
{
	var editbuttons = $('.edtTbBtn');
	for (i in editbuttons)
	{
		if (editbuttons[i].classname == mode)
		{
			editbuttons[i].disabled = "disabled";
		}
		else
		{
			editbuttons[i].disabled = "";
		}
	}

	if (map != null)
	{
		if (mode == MODE_DRAW)
			map.getDragObject().setDraggableCursor(CURSOR_DRAW);
		else
			map.getDragObject().setDraggableCursor("default");

		mapMode = mode;
	}
}

//Handles the click event of the map
function mapClick(marker, clickedPoint)
{

	if (mapMode != MODE_DRAW)
		return;
	
	//clicking on the map
	if (!marker)
	{
		if (($('[id$=CbFollowRoutes]').is(':checked')) && (polylines.getLength() > 0) && (polylines.getLastValue().getVertexCount() > 0))
		{

			var startpoint = polylines.getLastValue().getVertex(polylines.getLastValue().getVertexCount() - 1);
			var opts;

			if ($("[id$=trafficrules]").is(':checked'))
				opts = { getPolyline: true, getSteps: true, preserveViewport: false };
			else
				opts = { getPolyline: true, getSteps: true, preserveViewport: false, travelMode: G_TRAVEL_MODE_WALKING };

			geodirections.load("from: " + startpoint.lat() + "," + startpoint.lng() + " to: " + clickedPoint.lat() + "," + clickedPoint.lng(), opts);
		}
		else
		{
			GService.AddPointToPolyLine("0", clickedPoint.lat(), clickedPoint.lng(), $("[id$=cbAutoPan]").is(':checked'), OnSucceeded, OnFailed);
		}

	}
	else //clicking on a marker or other mapelement
	{

	}
}

function trackBack()
{
	if (polylines.getLength() != 0)
	{
		var line = polylines.getLastValue();
		var pointcount = line.getVertexCount();

		if (pointcount > 2)
		{
			var coords = new Array();
			var node = null;

			for (var index = pointcount - 2; index >= 0; index--)
			{
				node = line.getVertex(index);
				var p = new Array();
				p.push(node.lat());
				p.push(node.lng());
				coords.push(p);
			}

			GService.AddCoordsToPolyLine("0", coords, OnSucceeded, OnFailed);

			if (node != null)
				map.setCenter(node);
		}
	}
}

function closeTrack(addPointCall)
{
	if (polylines.getLength() != 0)
	{
		var line = polylines.getLastValue();

		var pointcount = line.getVertexCount();

		if (pointcount > 1)
		{
			var node = line.getVertex(0);

			if (typeof (addPointCall) == "undefined")
				mapClick(null, node);
			else
				addPointCall(node);

			if (node != null)
				map.setCenter(node);
		}
	}

}

//Remove the point "pointID" from the 0th polyline
function removePoint(pointID)
{
	if (polylines.getLength() > 0)
		GService.RemovePointFromPolyLine("0", pointID, OnSucceeded);

}

function clearMap()
{
	GService.ClearMap();
	map.clearOverlays();
	$("#TbRouteLen").val("0");
	$("#TbElevation").val("0");
	polylines = new fPolylines();
	polygons = new fPolygons();
	//	startPoint = null;
	miles = new MileStones(map);

	lastMile = 0;
}

function saveGoogleObject()
{
	if (polylines.getLength() != 0)
	{
		GService.IsUpdateFinished(function(res)
		{
			if (!res)
			{
				if (confirm("Kis türelmet, a magasságok számítása folyik. Megpróbáljuk újra?"))
					saveGoogleObject();
				return false;
			}
		});

		GService.SaveGoogleObject(OnSucceeded, OnFailed);

		clearInterval(elevationPoll);

		return true;
	}
	else
		return false;
}

function loadGoogleObject(objectid)
{
	map.clearOverlays();

	if (objectid)
		GService.LoadGoogleObject(objectid, OnSucceeded, OnFailed);
}

function GetElevation(lat, lon)
{
	GService.GetElevation(lat, lon, OnSucceeded, OnFailed);
}

// Callback function invoked on successful 
// completion of the page method or webservice.
function OnSucceeded(result, userContext, methodName)
{
	if (methodName == "SaveGoogleObject")
		document.URL = document.location.toString().replace(/step1/, "step2") + "?ID=" + result; //relocate to viewer page
	else if (methodName == "GetPolylineElevation")
	{//processing of the elevation data
		$("#TbElevation").val(result);
	}
	else if ((methodName == "AddPointToPolyLine") || (methodName == "AddCoordsToPolyLine"))
	{
		if ((methodName == "AddPointToPolyLine") && (result == null))
			return;

		GService.GetOptimizedGoogleObject(fGetGoogleObjectOptimized);
		//GService.GetPolylineElevation(0, OnSucceeded, OnFailed); //Only one polyline with ID 0
	}
	else if (methodName == "UpdateLineNode")
	{
		GService.GetPolylineElevation(0, OnSucceeded, OnFailed); //Only one polyline with ID 0
	}
	else if (methodName == "RemovePointFromPolyLine")
	{

		//Remove the last point and recalculate the elevation
		if (result > 0)
		{
			GService.GetOptimizedGoogleObject(fGetGoogleObjectOptimized);
			GService.GetPolylineElevation(0, OnSucceeded, OnFailed);
		}
		else
			clearMap();
	}
	else
		GService.GetOptimizedGoogleObject(fGetGoogleObjectOptimized);

}

// Callback function invoked on failure 
// of the page method.
function OnFailed(error, userContext, methodName)
{
	if (error !== null)
	{
		TrackHelpers.Alert("An error occurred: " +
            error.get_message());
	}
}

function updateNode(result, userContext)
{
	fGetGoogleObjectOptimized(result, userContext);
	//sets up the altitude of node
	var pointcount = polylines.getLastValue().getVertexCount();
	if (pointcount > 0)
	{
		var node = polylines.getLastValue().getVertex(pointcount - 1);
		GService.UpdateLineNode("0", pointcount - 1, node.lat(), node.lng(), OnSucceeded);
	}
}

function CreateMarker(point, icon1, InfoHTML, bDraggable, sTitle)
{
	var marker;
	marker = new GMarker(point, { icon: icon1, draggable: bDraggable, title: sTitle });

	if (InfoHTML != '')
	{
		GEvent.addListener(marker, "click", function() { map.openInfoWindowHtml(point, InfoHTML); });
		GEvent.addListener(marker, "dragend", function() { GService.SetLatLon(this.value, this.getLatLng().y, this.getLatLng().x); RaiseEvent('PushpinMoved', this.value); });
	}
	return marker;
}

function CreatePolyline(points, color, width, isgeodesic, lengthcontrol)
{
	var polyline;

	if (!isgeodesic)
	{
		polyline = new GPolyline(points, color, width);
	}
	else
	{
		var polyOptions = { geodesic: true };
		polyline = new GPolyline(points, color, width, 1, polyOptions);
	}

	if (typeof (lengthcontrol) != "undefined")
	{
		var len = parseInt(polyline.getLength()) / 1000;
		lengthcontrol.value = len;
	}

	addMiles(polyline);

	return polyline;
}

function addMiles(polyline)
{
	if ((polyline != null) && (typeof (polyline) == "object"))
	{
		miles.setPolyline(polyline);
	}
	miles.setVisibility($("[id$=chbMilestones]").is(":checked"));

}

function CreatePolygon(points, strokecolor, strokeweight, strokeopacity, fillcolor, fillopacity)
{
	var polygon = new GPolygon(points, strokecolor, strokeweight, strokeopacity, fillcolor, fillopacity);
	return polygon;
}

function updateLine()
{
	GService.UpdateLine(0, polylines.getLastValue().toDblArray(), fGetGoogleObjectOptimized);
}

function fGetGoogleObject(result, userContext)
{
	var zoomLevel;
	var center = new GLatLng(result.CenterPoint.Latitude, result.CenterPoint.Longitude);
	map.setCenter(center);

	if (result.ShowMapTypesControl)
	{

		if (result.IsMapControlHierachical)
			map.addControl(new GHierarchicalMapTypeControl());
		else
			map.addControl(new GMapTypeControl());
	}

	if (result.ShowZoomControl)
		map.addControl(new GLargeMapControl3D());

	if (result.ShowOverviewMap)
		map.addControl(overViewCtrl);

	if (result.IsScrollWheelZoomEnabled)
		map.enableScrollWheelZoom();

	var currentmaptypes = map.getMapTypes();

	var i;
	for (i = currentmaptypes.length - 1; i > 0; i--)
		map.removeMapType(currentmaptypes[i]);

	for (i = 0; i < result.MapTypeControls.length; i++)
		map.addMapType(eval(result.MapTypeControls[i]));

	map.addControl(new GScaleControl());


	if (markers != null)
	{
		for (i = 0; i < markers.getLength(); i++)
		{
			var cmark = markers.getValue(i);
			if (cmark != null)
			{
				map.removeOverlay(cmark);
			}
		}
	}

	markers = new fMarkers();


	for (i = 0; i < result.Points.length; i++)
	{
		var myIcon_google;

		var myPoint = new GLatLng(result.Points[i].Latitude, result.Points[i].Longitude);

		myIcon_google = null;
		if (result.Points[i].IconImage != '')
		{
			myIcon_google = new GIcon(G_DEFAULT_ICON);
			markerOptions = { icon: myIcon_google };

			myIcon_google.iconSize = new GSize(result.Points[i].IconImageWidth, result.Points[i].IconImageHeight);
			myIcon_google.image = result.Points[i].IconImage;
		}

		var marker = CreateMarker(myPoint, myIcon_google, result.Points[i].InfoHTML, result.Points[i].Draggable, result.Points[i].ToolTip);
		marker.value = result.Points[i].ID;
		markers.pushValue(marker);
		map.addOverlay(markers.getLastValue());
	}
	//Add polylines
	var polypoints;
	var polyline;

	polylines = new fPolylines();
	for (i = 0; i < result.Polylines.length; i++)
	{
		polypoints = new Array();
		var j;

		for (j = 0; j < result.Polylines[i].Points.length; j++)
		{
			polypoints.push(new GLatLng(result.Polylines[i].Points[j].Latitude, result.Polylines[i].Points[j].Longitude));
		}
		polyline = CreatePolyline(polypoints, result.Polylines[i].ColorCode, result.Polylines[i].Width, result.Polylines[i].Geodesic, $("#TbRouteLen")[0]);
		polylines.pushValue(polyline, result.Polylines[i].ID);

		map.addOverlay(polyline);
	}

	//TODO: Refactor for more general.
	if (polylines.getLength() == 1)
	{
		var l = polylines.getLastValue();
		// polyline editing - later	
//		l.enableEditing();
//		GEvent.addListener(l, "lineupdated", updateLine);
		var b = l.getBounds();
		zoomLevel = map.getBoundsZoomLevel(b) - 1;
		center = b.getCenter();
		map.setCenter(center);
	}
	else
		zoomLevel = result.ZoomLevel;  //Store the zoomlevel for client use.

	

	map.getCurrentMapType().getMaxZoomAtLatLng(center, function(response)
	{
		if (response && response['status'] == G_GEO_SUCCESS)
		{
			zoomLevel = Math.min(response['zoom'], zoomLevel);
		}
	});
	
	map.setZoom(zoomLevel);
	GService.RecenterMapComplete(zoomLevel);

	polygons = new fPolygons();
	for (i = 0; i < result.Polygons.length; i++)
	{
		addPolyLineOverLay(result, i);
	}


	if (result.ShowTraffic)
	{
		trafficInfo = new GTrafficOverlay();
		map.addOverlay(trafficInfo);
	}
}

function fGetGoogleObjectOptimized(result, userContext)
{
	if (result.ShowTraffic)
	{
		trafficInfo = new GTrafficOverlay();
		map.addOverlay(trafficInfo);
	}
	else
	{
		if (trafficInfo != null)
		{
			map.removeOverlay(trafficInfo);
			trafficInfo = null;
		}
	}

	var i;
	for (i = 0; i < result.Points.length; i++)
	{
		//Create icon
		var myIcon_google;

		var myPoint = new GLatLng(result.Points[i].Latitude, result.Points[i].Longitude);

		myIcon_google = null;
		if (result.Points[i].IconImage != '')
		{
			myIcon_google = new GIcon(G_DEFAULT_ICON);
			markerOptions = { icon: myIcon_google };

			myIcon_google.iconSize = new GSize(result.Points[i].IconImageWidth, result.Points[i].IconImageHeight);
			myIcon_google.image = result.Points[i].IconImage;
		}

		var marker;

		//Existing marker, but changed.
		if (result.Points[i].PointStatus == 'C')
		{
			marker = markers.getValueById(result.Points[i].ID);
			if (marker != null)
			{
				markers.removeValueById(result.Points[i].ID);
				map.removeOverlay(marker);
			}
			marker = CreateMarker(myPoint, myIcon_google, result.Points[i].InfoHTML, result.Points[i].Draggable, result.Points[i].ToolTip);
			marker.value = result.Points[i].ID;
			markers.pushValue(marker);
			map.addOverlay(markers.getLastValue());
		}
		else if (result.Points[i].PointStatus == 'N')//New Marker
		{
			marker = CreateMarker(myPoint, myIcon_google, result.Points[i].InfoHTML, result.Points[i].Draggable, result.Points[i].ToolTip);
			marker.value = result.Points[i].ID;
			markers.pushValue(marker);
			map.addOverlay(markers.getLastValue());
		}
		else if (result.Points[i].PointStatus == 'D')//Existing marker, but deleted.
		{
			marker = markers.getValueById(result.Points[i].ID);
			if (marker != null)
			{
				markers.removeValueById(result.Points[i].ID);
				map.removeOverlay(marker);
			}
		}
	}

	var polyline;
	//Get Polylines
	for (i = 0; i < result.Polylines.length; i++)
	{
		
		var j;

		if (result.Polylines[i].LineStatus == 'C')//Existing polyline, but changed.
		{
			polyline = polylines.getValueById(result.Polylines[i].ID);
			if (polyline != null)
			{
				polylines.removeValueById(result.Polylines[i].ID);
				map.removeOverlay(polyline);
			}

			polyline = addPolyLineOverLay(result, i);
		}
		else if (result.Polylines[i].LineStatus == 'N')		//New polyline
		{
			polyline = addPolyLineOverLay(result, i);
		}
		else if (result.Polylines[i].LineStatus == 'D') //Existing polyline, but deleted.
		{
			polyline = polylines.getValueById(result.Polylines[i].ID);
			if (polyline != null)
			{
				polylines.removeValueById(result.Polylines[i].ID);
				map.removeOverlay(polyline);
			}
		}
	}


	if (result.RecenterMap)
	{
		map.setCenter(new GLatLng(result.CenterPoint.Latitude, result.CenterPoint.Longitude), result.ZoomLevel);
		GService.RecenterMapComplete(result.ZoomLevel);
	}
//polyline editing - later
//	if (polylines.getLength() == 1)
//	{
//		var l = polylines.getLastValue();
//		l.enableEditing();
//		GEvent.addListener(l, "lineupdated",updateLine);
//	}


	//Get Polygons
	for (i = 0; i < result.Polygons.length; i++)
	{
		if (result.Polygons[i].Status == 'C')//Existing Polygon, but changed.
		{

			var polygon = polygons.getValueById(result.Polygons[i].ID);
			if (polygon != null)
			{
				polygons.removeValueById(result.Polygons[i].ID);
				map.removeOverlay(polygon);
			}

			addPolyLineOverLay(result, i);
		}
		else if (result.Polygons[i].Status == 'N')//New Polygon
		{
			polypoints = new Array();

			for (j = 0; j < result.Polygons[i].Points.length; j++)
			{
				polypoints.push(new GLatLng(result.Polygons[i].Points[j].Latitude, result.Polygons[i].Points[j].Longitude));
			}
			polygon = CreatePolygon(polypoints, result.Polygons[i].StrokeColor, result.Polygons[i].StrokeWeight, result.Polygons[i].StrokeOpacity, result.Polygons[i].FillColor, result.Polygons[i].FillOpacity);
			polygons.pushValue(polygon, result.Polygons[i].ID);
			map.addOverlay(polygons.getLastValue());
		}
		else if (result.Polygons[i].Status == 'D')//Existing Polygon, but deleted.
		{
			polygon = polygons.getValueById(result.Polygons[i].ID);
			if (polygon != null)
			{
				polygons.removeValueById(result.Polygons[i].ID);
				map.removeOverlay(polygon);
			}
		}
	}
}

function addPolyLineOverLay(result, i)
{
	var polypoints = new Array();

	for (j = 0; j < result.Polylines[i].Points.length; j++)
	{
		polypoints.push(new GLatLng(result.Polylines[i].Points[j].Latitude, result.Polylines[i].Points[j].Longitude));
	}

	gdcolor = result.Polylines[i].ColorCode;

	var polyline = CreatePolyline(polypoints, result.Polylines[i].ColorCode, result.Polylines[i].Width, result.Polylines[i].Geodesic, $("#TbRouteLen")[0]);
	polylines.pushValue(polyline, result.Polylines[i].ID);

	map.addOverlay(polyline);

	return polyline;
}

var gdcolor;
//function for the load event of gdirection
function gdLoad()
{

	var gdpolyline = geodirections.getPolyline();
	gdpolyline.color = gdcolor;

	var coords = new Array();

	for (var i = 0; i < gdpolyline.getVertexCount(); i++)
	{

		var p = new Array();
		var node = gdpolyline.getVertex(i);
		p.push(node.lat());
		p.push(node.lng());
		coords.push(p);
	}

	GService.AddCoordsToPolyLine("0", coords, OnSucceeded, OnFailed);

	return gdpolyline;
}

//function pageLoad()
//{
//	if (!map)
//		loadMap();

//	if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack())
//		Sys.WebForms.PageRequestManager.getInstance().add_endRequest(OnSucceeded);
//}

function createIcon(img, shadow, iconsize, shadowshize, iconanchor, infoanchor)
{
	var icon = new GIcon();
	icon.image = img ? img : "http://www.google.com/intl/en_us/mapfiles/ms/micons/red-dot.png";
	icon.shadow = shadow ? shadow : "http://www.google.com/mapfiles/shadow50.png";
	icon.iconSize = iconsize ? iconsize : new GSize(24, 38);
	icon.shadowSize = shadowshize ? shadowshize : new GSize(44, 38);
	icon.iconAnchor = iconanchor ? iconanchor : new GPoint(12, 38);
	icon.infoWindowAnchor = infoanchor ? infoanchor : new GPoint(5, 1);

	return icon;
}

