SIX.Tool.Area = function (parent, sImage, sToolTip, params)
{
	SIX.Tool.call(this, parent, SIX.eToolTypes.EXCLUSIVE, sImage, sToolTip, params);
	
	var toolData = {aPoints : null, 
						aPixelsX : null,
						aPixelsY : null,
						nSelectedIndex : -1,
						controlLayerName : SIX.Uid.getUid("AreaTool"),
						mapContainer : null,
						resultContainer : null, 
						elemArea : null, 
						init : function (map) {
							var control = document[map.uid];
							this.aPoints = new Array();
							this.aPixelsX = new Array();
							this.aPixelsY = new Array();
							
							if (this.elemArea)
								this.elemArea.innerHTML = "0 m2";					
															
							if (SIX.App.bDHTMLControl)
							{
								var canvas = map.getCanvas();
								var ctx = canvas.getContext("2d");
								ctx.clearRect(0, 0, canvas.width, canvas.height);
							}
							else
							{
								var nLayerIndex = control.GetLayerIndex(this.controlLayerName);
								if (nLayerIndex >= 0)
								{
									map.setLayerParameter(this.controlLayerName,"filledpolygon1=");
								}
								else 
								{
									nLayerIndex = map.addLayer("SIMPLEVECTOR", "", this.controlLayerName,"color=#ff0000;fillcolor=#0000ff;linewidth=1");
									if (nLayerIndex >= 0)
										control.SetLayerTransparency(this.controlLayerName, "#0000ff", 0.15);
								}
							}		
						},
						update : function (map, bRecalcPixels) {
							var dArea = this.aPoints.length > 2 ? SIX.Util.calculateArea(this.aPoints) : 0.0;

							if (SIX.App.bDHTMLControl)
							{	
								if (bRecalcPixels)
								{
									for (var i=0; i<this.aPoints.length; i++)
									{
										var point = this.aPoints[i];
										var aPixel = map.getPixelFromEN(point.x, point.y);
										this.aPixelsX[i] = aPixel[0];
										this.aPixelsY[i] = aPixel[1];	
									}
								}							
								if (this.aPixelsX.length && this.aPixelsY.length)
								{
									var canvas = map.getCanvas();
									var ctx = canvas.getContext("2d");
									ctx.clearRect(0, 0, canvas.width, canvas.height);
									
									ctx.beginPath();
									ctx.moveTo(this.aPixelsX[0], this.aPixelsY[0]);
									for (var i = 0; i < this.aPoints.length; i++)
										ctx.lineTo(this.aPixelsX[i], this.aPixelsY[i]);
									ctx.closePath();
									ctx.fillStyle = "rgba(0,0,255, 0.15)";
									ctx.fill();	
									
									ctx.beginPath();
									ctx.moveTo(this.aPixelsX[0], this.aPixelsY[0]);
									for (var i = 0; i < this.aPoints.length; i++)
										ctx.lineTo(this.aPixelsX[i], this.aPixelsY[i]);
									ctx.closePath();
									ctx.strokeStyle = "rgb(255,0,0)";
									ctx.stroke();								
								}
							}
							else
							{				
								if (this.aPoints.length == 1)
								{
									var params = "linewidth=10;filledpolygon1=;filledcircle1=" + this.aPoints[0].x + "," + this.aPoints[0].y + "|" +
																			(this.aPoints[0].x + 1) + "," + (this.aPoints[0].y + 1);
								}
								else if (this.aPoints.length > 1)
								{
									var params = "linewidth=1;filledcircle1=;filledpolygon1=";	
									for (var i=0; i<this.aPoints.length; i++)
										params += (i > 0 ? "|" : "") + this.aPoints[i].x + "," + this.aPoints[i].y;
								}
								else
								{
									var params = "filledcircle1=;filledpolygon1=";
								}
								map.setLayerParameter(this.controlLayerName, params);						
							}
							
							dArea = Math.round(dArea);
							var sUnits = "m2";
							if (dArea >= 10000)
							{
								dArea = dArea / 10000;
								if (dArea < 10) 
									dArea = dArea.toFixed(3);
								else if (dArea < 100) 
									dArea = dArea.toFixed(2);
								else if (dArea < 1000) 
									dArea = dArea.toFixed(1);					
								else
									dArea = Math.round(dArea);
								sUnits = "ha";
							}
							if (this.elemArea)
								this.elemArea.innerHTML = dArea + " " + sUnits;														
						}};				
						
	this.addCallback(SIX.eToolCallbacks.ONACTIVATE, 
				function (map, data) {
					map.setPointerMode(PM_POINTER);		
					
					var elemContainer = map.getContainer();
					if (elemContainer && data.mapContainer == elemContainer)	
					{				
						var elemResultContainer = data.resultContainer;
						elemResultContainer.style.display = "block";
					}
					else
					{
						var sDeleteTooltip = "Delete point (Ctrl+click or right mouse button over point to delete)";
						var sDeleteAllTooltip = "Delete all points (Shift+click)";
						
						if (data.mapContainer)
							data.mapContainer.removeChild(data.resultContainer);
						var elemResultContainer = document.createElement("div");
						elemResultContainer.setAttribute("class", "areaContainer");
						elemResultContainer.setAttribute("className", "areaContainer");
							
						var elemImageDelete = document.createElement("img");	
						elemImageDelete.setAttribute("class", "areaDeleteButton");
						elemImageDelete.setAttribute("className", "areaDeleteButton");
						elemImageDelete.setAttribute("alt", sDeleteTooltip);
						elemImageDelete.setAttribute("title", sDeleteTooltip);
						elemImageDelete.setAttribute("src", "images/deletePoint.gif");						
						
						elemImageDelete.onmouseover = function()
						{
							this.src = "images/deletePoint_on.gif";
						}
	
						elemImageDelete.onmouseout = function()
						{
							this.src = "images/deletePoint.gif";
						}	
							
						elemImageDelete.onclick = function()
						{
							with ({map : map, data : data})
							{
								map.setPointerMode(PM_POINTER);
								if (data.aPoints.length)
								{
									var nIndex = data.aPoints.length - 1;//Delete last point
									data.aPoints.splice(nIndex, 1);
									data.aPixelsX.splice(nIndex, 1);
									data.aPixelsY.splice(nIndex, 1);
									data.update(map);
								}									
							}
						}
						elemResultContainer.appendChild(elemImageDelete);	
						
						var elemImageDeleteAll = document.createElement("img");		
						elemImageDeleteAll.setAttribute("class", "areaDeleteAllButton");
						elemImageDeleteAll.setAttribute("className", "areaDeleteAllButton");	
						elemImageDeleteAll.setAttribute("alt", sDeleteAllTooltip);
						elemImageDeleteAll.setAttribute("title", sDeleteAllTooltip);
						elemImageDeleteAll.setAttribute("src", "images/deleteAllPoints.gif");						
	
						elemImageDeleteAll.onmouseover = function()
						{
							this.src = "images/deleteAllPoints_on.gif";
						}
	
						elemImageDeleteAll.onmouseout = function()
						{
							this.src = "images/deleteAllPoints.gif";
						}	
						
						elemImageDeleteAll.onclick = function()
						{
							with ({map : map, data : data})
							{
								map.setPointerMode(PM_POINTER);
								data.init(map);								
							}
						}
						elemResultContainer.appendChild(elemImageDeleteAll);						
										
						var elemResultLabel = document.createElement("span");
						elemResultLabel.setAttribute("class", "areaLabel");
						elemResultLabel.setAttribute("className", "areaLabel");
						elemResultLabel.appendChild(document.createTextNode("Area:"));
						elemResultContainer.appendChild(elemResultLabel);
	
						var elemResult = document.createElement("span");
						elemResult.setAttribute("class", "areaResult");
						elemResult.setAttribute("className", "areaResult");
						elemResult.appendChild(document.createTextNode(""));
						elemResultContainer.appendChild(elemResult);
						
						elemContainer.appendChild(elemResultContainer);
						
						data.mapContainer = elemContainer;
						data.resultContainer = elemResultContainer;
						data.elemArea = elemResult;
					}
					data.init(map);
				}, toolData);	

	this.addCallback(SIX.eToolCallbacks.ONDEACTIVATE, 
				function (map, data) {
					var control = document[map.uid];	
				
					if (SIX.App.bDHTMLControl)
					{
						var canvas = map.getCanvas();
						var ctx = canvas.getContext("2d");
						ctx.clearRect(0, 0, canvas.width, canvas.height);
					}
					else
					{
						var nLayerIndex = control.GetLayerIndex(data.controlLayerName);
						if (nLayerIndex >= 0)
							map.setLayerParameter(data.controlLayerName,"filledpolygon1=");					
					}
					
					var elemContainer = map.getContainer();
					if (elemContainer && data.mapContainer == elemContainer)	
					{				
						var elemResultContainer = data.resultContainer;
						elemResultContainer.style.display = "none";
					}

				}, toolData);	
				
	this.addCallback(SIX.eToolCallbacks.ONMAPMOUSEDOWN, 
				function (map, data) {
					var bDeleteAllPoints = (map.nMouseMask & MVK_SHIFT);
					if (bDeleteAllPoints)
					{
						data.init(map);
					}
					else
					{					
						var bDeletePoint = (map.nMouseMask & MVK_CONTROL) || (map.nMouseMask & MVK_RBUTTON);
						var nIndex = bDeletePoint ? data.aPoints.length - 1 : data.aPoints.length;
						var bMovePoint = false;			
						var dThreshold = 0.01 * Math.pow(Math.pow((map.brx - map.tlx),2) + Math.pow((map.tly - map.bry),2), 0.5);

						var nearestPoint = SIX.Util.getNearestPoint(map.dMouseWorldX, map.dMouseWorldY, data.aPoints);
						var nNearestPointIndex = nearestPoint ? nearestPoint[0] : -1;
						var dDistanceToNearestPoint = nearestPoint ? nearestPoint[1] : Number.MAX_VALUE;
						if (nNearestPointIndex >= 0 && nNearestPointIndex < data.aPoints.length && dDistanceToNearestPoint < dThreshold)
						{
							nIndex = nNearestPointIndex;
							bMovePoint = true;
						}
						else if (!bDeletePoint)
						{					
							var nearestLine = SIX.Util.getNearestLine(map.dMouseWorldX, map.dMouseWorldY, data.aPoints);
							var nNearestLineIndex = nearestLine ? nearestLine[0] : -1;
							var dDistanceToNearestLine = nearestLine ? nearestLine[1] : Number.MAX_VALUE;
							if (nNearestLineIndex >= 0 && nNearestLineIndex < data.aPoints.length - 1 && dDistanceToNearestLine < dThreshold)
								nIndex = nNearestLineIndex + 1;
						}
					
						if (bDeletePoint)
						{
							if (data.aPoints.length && nIndex < data.aPoints.length)
							{
								data.aPoints.splice(nIndex, 1);
								data.aPixelsX.splice(nIndex, 1);
								data.aPixelsY.splice(nIndex, 1);
							}								
						}
						else if (nIndex == data.aPoints.length)
						{
							data.aPoints[nIndex] = new SIX.Point(map.dMouseWorldX, map.dMouseWorldY);
							data.aPixelsX[nIndex] = map.dMouseScreenX;
							data.aPixelsY[nIndex] = map.dMouseScreenY;						
						}
						else
						{
							data.aPoints.splice(nIndex, (bMovePoint ? 1 : 0), new SIX.Point(map.dMouseWorldX, map.dMouseWorldY));
							data.aPixelsX.splice(nIndex, (bMovePoint ? 1 : 0), map.dMouseScreenX);
							data.aPixelsY.splice(nIndex, (bMovePoint ? 1 : 0), map.dMouseScreenY);						
						}
						
						data.nSelectedIndex = bDeletePoint ? -1 : nIndex;	
						data.update(map);
					}		
				}, toolData);		

	this.addCallback(SIX.eToolCallbacks.ONMAPMOUSEMOVE, 
				function (map, data) {
					if (data.nSelectedIndex >= 0 && data.nSelectedIndex < data.aPoints.length)
					{					
						var nIndex = data.nSelectedIndex;
					
						if (nIndex == data.aPoints.length)
						{
							data.aPoints[nIndex] = new SIX.Point(map.dMouseWorldX, map.dMouseWorldY);
							data.aPixelsX[nIndex] = map.dMouseScreenX;
							data.aPixelsY[nIndex] = map.dMouseScreenY;						
						}
						else
						{
							data.aPoints.splice(nIndex, 1, new SIX.Point(map.dMouseWorldX, map.dMouseWorldY));
							data.aPixelsX.splice(nIndex, 1, map.dMouseScreenX);
							data.aPixelsY.splice(nIndex, 1, map.dMouseScreenY);						
						}
						
						data.update(map);
					}	
				}, toolData);	

	if (SIX.App.bDHTMLControl)
	{				
		this.addCallback(SIX.eToolCallbacks.ONMAPEXTENTCHANGE, 
					function (map, data) {			
						data.update(map, true);
					}, toolData);
	}				
}
SIX.Util.extend(SIX.Tool.Area, SIX.Tool);