﻿/// <reference path="~/Resources/scripts/jquery-1.3.1-vsdoc.js" />
/// <reference path="LatLonHelper.js" />

MileStones = function (map, maxPixelDistance, polyLine)
{
	this.gMap = map;
	this.miles = new Array();
	this.pLine = polyLine;
	this.geoMagicNumber = 1 / 108; // distance [m] = 6378137.0 [m] * Pi * distance [degree] / 180.0

	if ((maxPixelDistance != null) && (typeof (maxPixelDistance) != "undefined"))
		this.maxPixel = maxPixelDistance;
	else
		this.maxPixel = 20;

	this.isVisible = true;
	this.calculateMileStones();
	this.redraw();
}

MileStones.prototype.setPolyline = function (pline)
{
	this.pLine = pline;
	this.redraw(true);
}

MileStones.prototype.drawFinished = false;

//meg kell pr=b'lni MyGMaps.MyGMapControl.prototype.AddGMarker -rel, mert igy kell egy hack a tooltip menjen a wpnek
MileStones.prototype.calculateMileStones = function ()
{
	if ((this.pLine == null) || (typeof (this.pLine) == "undefined"))
		return;

	this.miles = new Array();

	var vertexCount = this.pLine.getVertexCount();

	if (vertexCount < 1)
		return this.miles;

	//puts startpoint
	var icon = this.getIconType("start");
	var marker = new GMarker(this.pLine.getVertex(0), { icon: icon, zIndexProcess: MileStones.getZindex });

	this.miles.push(marker);
	this.gMap.addOverlay(marker);
	//this.addIfInViewPort(marker);

	var mp, innerstones, lastpoint, beforelastpoint;
	var remainder = 0;

	for (var i = 0; i < vertexCount - 1; i++)
	{
		lastpoint = this.pLine.getVertex(i + 1);
		beforelastpoint = this.pLine.getVertex(i);
		innerstones = this.interpolate(beforelastpoint, lastpoint, remainder);
		remainder = innerstones.remain;

		for (var ii = 0; ii < innerstones.points.length; ii++)
		{
			icon = this.getIconType("km", (this.miles.length).toString());
			marker = new GMarker(innerstones.points[ii], { icon: icon, zIndexProcess: MileStones.getZindex });

			this.miles.push(marker);
			this.gMap.addOverlay(marker);
		}
	}

	//puts endpoint
	icon = this.getIconType("end");
	marker = new GMarker(this.pLine.getVertex(vertexCount - 1), { icon: icon, clickable: false, zIndexProcess: MileStones.getZindex });

	this.miles.push(marker);
	this.gMap.addOverlay(marker);
	//this.addIfInViewPort(marker);
	this.drawFinished = true;

	return this.miles;
}

MileStones.prototype.interpolate = function (vertex1, vertex2, remainder)
{
	var start = new LatLon(vertex1.lat(), vertex1.lng());
	var end = new LatLon(vertex2.lat(), vertex2.lng());
	var sectionlength = start.distanceTo(end);
	var bearing = start.bearingTo(end);
	var interpolatedPoints = [];

	if (typeof remainder == 'undefined')
	{
		remainder = 0;
	}

	var len = parseFloat(sectionlength) + remainder;
	var roundedlen = Math.floor(len);


	if (roundedlen >= 1)
	{
		for (var i = 0; i < roundedlen; i++)
		{
			interpolatedPoints[i] = start.destinationPoint(bearing, i +1 - remainder).asGLatLng();
		}
	}

	return { points: interpolatedPoints, remain: len-roundedlen};
}

MileStones.getZindex = function ()
{
	return -9999999;
}

MileStones.prototype.addIfInViewPort = function (mileStone)
{
	var bounds = this.gMap.getBounds();
	if ((jQuery.inArray(mileStone, this.miles) == -1) && (bounds.containsLatLng(mileStone.getLatLng())))
		this.miles.push(mileStone);
}

MileStones.prototype.setVisibility = function (isVisible)
{
	this.isVisible = isVisible;
	this.redraw();
}

MileStones.prototype.redraw = function (recalc)
{
	this.hideMileStones();

	if ((recalc != null) && (recalc))
		this.calculateMileStones();

	if (this.isVisible)
		this.showMileStones();

}

MileStones.prototype.showMileStones = function ()
{
	var bounds = this.gMap.getBounds();

	for (var i = 0; i < this.miles.length; i++)
	{
		var current;

		if (bounds.containsLatLng(this.miles[i].getLatLng()))
		{
			if ((i > 0) && (i < this.miles.length - 1))
			{ //avoid overlapping
				if ((current) && (this.pixelDistance(current.getLatLng(), this.miles[i].getLatLng()) <= this.maxPixel))
					continue;
			}

			current = this.miles[i];
			this.miles[i].show();
			//            this.gMap.addOverlay(current);
		}
	}
}

MileStones.prototype.hideMileStones = function ()
{
	for (var i = 0; i < this.miles.length; i++)
	{
		this.miles[i].hide();
		//this.gMap.removeOverlay(this.miles[i]);
	}
}

//Creates standard icontypes
MileStones.prototype.getIconType = function (type, label)
{
	if ((label == null) || (typeof label == "undefined"))
		label = "";

	var iconOptions = {};
	iconOptions.width = 24;
	iconOptions.height = 24;
	iconOptions.addStar = false;
	iconOptions.strokeColor = "#555555";
	iconOptions.shape = "circle";

	if (type == "start")
	{
		iconOptions.primaryColor = "#338AAC";
		iconOptions.cornerColor = "#DDDDDD";
		return MapIconMaker.createMarkerIcon(iconOptions);
	}
	else if (type == "end")
	{
		iconOptions.primaryColor = "#FF6A00";
		iconOptions.cornerColor = "#DDDDDD";
		return MapIconMaker.createMarkerIcon(iconOptions);
	}
	else if (type == "km")
	{
		iconOptions.width = 16;
		iconOptions.height = 16;
		iconOptions.labelSize = 10;
		iconOptions.label = label;

		iconOptions.primaryColor = "#81B33D";
		iconOptions.labelColor = "#555555";
		return MapIconMaker.createFlatIcon(iconOptions);
	}

}

MileStones.prototype.clustering = function (sourceArray, withAveraging)
{
	if ((sourceArray == null) || (typeof (sourceArray.length) == "undefined") || (sourceArray.length < 2))
		sourceArray = this.miles;

	if (withAveraging)
		var target = new Array();

	var distance;
	var index = sourceArray.length - 1;

	while (index >= 0)
	{


		var current = sourceArray[index];
		var isDroppable = false;

		if (withAveraging)
			var result = new Array();

		for (var i = 0; i < index; i++)
		{
			if (withAveraging)
				var temp = new Array();

			distance = this.pixelDistance(this.gMap, current, sourceArray[i]);

			if (distance <= this.maxPixel)
			{
				if (withAveraging)
				{
					if (temp.length == 0)
						temp.push(current);

					temp.push(sourceArray[i]);
				}
				else
				{
					isDroppable = true;
					break;
				}
			}
		}

		if (withAveraging)
		{
			var lats;
			var lons;

			for (point in temp)
			{
				xs += point.lat();
				ys += point.lng();
			}

			xs /= temp.length;
			ys /= temp.length;

			result.push(new GLatLng(xs, ys));
		}
		else
		{
			if (isDroppable)
				sourceArray.pop();
		}

		index--;
	}

	if (withAveraging)
		return result;
	else
		return sourceArray;
}

MileStones.getHighestZIndex = function ()
{
	return MileStones.getZindex() + 1;
}

MileStones.prototype.getHighestZIndex = function (marker, b)
{
	var i = 0;
	var t = 0;

	$.each(this.miles, function ()
	{
		t = GOverlay.getZIndex($(this).getPoint().lat());
		if (t > i)
			i = t;
	});

	return i + 100000;
}

MileStones.prototype.pixelDistance = function (p1, p2)
{
	var mapProj = (this.gMap.getCurrentMapType()).getProjection();
	var mapZoom = this.gMap.getZoom();
	var currentPixel = mapProj.fromLatLngToPixel(p1, mapZoom);
	var nextPixel = mapProj.fromLatLngToPixel(p2, mapZoom);

	return Math.sqrt(Math.pow((currentPixel.x - nextPixel.x), 2) + Math.pow((currentPixel.y - nextPixel.y), 2));
}
