function MeasureOption(image, div, vectorMode, ieCursor, otherCursor)
{
	this.image = $get(image);
	this.div = $get(div);
	this.vectorMode = vectorMode;
	this.ieCursor = ieCursor;
	this.otherCursor = otherCursor;
	this.mapTool;
};

MeasureTool = function(map, floatingPanelId, mapUnits)
{
    this.enableRealTimeUpdate = true;
    this.map = map;
    if (this.map == null) alert("measure...map is null");
	this.floatingPanelId = floatingPanelId;
	this.floatingPanel = $find(floatingPanelId);
	this.floatingPanel.add_close(Function.createDelegate(this, this._onClosePanel));
	this.mapUnits = mapUnits;
	this.linearUnits = "feet";
	this.areaUnits = "acres";
    //this.vectorFormatting = new vectorFormatArgs("blue", 2, 0.5, "blue", 0.1);
	this.tools = new Array();
	
	this.tools["line"] = new MeasureOption("measurePolylineImage", "measureLineOutput", "line", "hand", "pointer");
	this.tools["line"].mapTool = $create(MapsDirect.WebControls.Tools.Line, {map: this.map}, null, null, null);
	this.tools["line"].mapTool.parent = this;
	// override the tool onMouseMove function
	this.tools["line"].mapTool.onMouseMove = Function.createDelegate(this, this._onMouseMove);
	
	this.tools["poly"] = new MeasureOption("measurePolygonImage", "measurePolyOutput", "poly", "crosshair", "pointer");
	this.tools["poly"].mapTool = $create(MapsDirect.WebControls.Tools.Polygon, {map: this.map}, null, null, null);
	this.tools["poly"].mapTool.parent = this;
	// override the tool onMouseMove function
	this.tools["poly"].mapTool.onMouseMove = Function.createDelegate(this, this._onMouseMove);
	
	this.defaultTool = "line";
	this.activeTool = this.tools[this.defaultTool];
	this.segments = null;
	
	this._clickDelegate = Function.createDelegate(this, this._addLineSegment);
	this._dblClickDelegate = Function.createDelegate(this, this._calculate);
	
	//help
	this.polyHelpString = "This tool measures the perimeter and area of a user-defined shape.<br /><br />Click on the map to add points to your shape.<br /><br />Press the 'DELETE' key to undo your last click.<br /><br />Double-click to complete the shape.<br /><br />Points in an completed shape can be moved by dragging the associated vertex to the desired location.<br /><br />Points can be removed from a completed shape by mousing over the vertex and pressing the 'DELETE' key.";
    this.lineHelpString = "This tool measures the distance along a user-defined path.<br /><br />Click on the map to add points to your path.<br /><br />Press the 'DELETE' key to undo your last click.<br /><br />Double-click to complete the path.<br /><br />Points in an completed shape can be moved by dragging the associated vertex to the desired location.<br /><br />Points can be removed from a completed path by mousing over the vertex and pressing the 'DELETE' key.";   
}

MeasureTool.prototype = 
{	
    set_enableRealTimeUpdate: function(value)
    {
        this.enableRealTimeUpdate = value;
    },
    
	set_areaUnits: function(unit)
	{
		this.areaUnits = unit;
		this._calculate(this.activeTool.mapTool);
	},
		
	set_linearUnits: function(unit)
	{
		this.linearUnits = unit;
		this._calculate(this.activeTool.mapTool);
	},
	
	set_tool: function(tool)
	{
		var l1 = $get("ddlMeasureLinearUnits1");
		var l2 = $get("ddlMeasureLinearUnits2");
		for(var i = 0; i < l1.options.length; i++){
			if(l1.options[i].value == this.linearUnits){
				l1.selectedIndex = i;
				l2.selectedIndex = i;
				break;
			}
		}
		
		for(var key in this.tools){
			this.tools[key].image.style.border = "1px solid #FFFFFF";			
			this.tools[key].div.style.display = "none";		
	        //this.tools[key].mapTool.geometry().showVertices = false;
		}
		
		this.activeTool = this.tools[tool];
		this.activeTool.image.style.border = "1px solid #919B9C";
		this.activeTool.div.style.display = "block";
		this.map.set_tool(this.activeTool.mapTool);	
		if(this.activeTool.vectorMode == "line") {				
		    this.floatingPanel.get_helpPanel().innerHTML = this.lineHelpString;	
			this.activeTool.mapTool.add_click(this._clickDelegate);
		} else {
		    this.floatingPanel.get_helpPanel().innerHTML = this.polyHelpString;
			this.activeTool.mapTool.add_click(this._dblClickDelegate);
		}
		this.activeTool.mapTool.add_dblClick(this._dblClickDelegate);
	},
	
		
	show: function()
	{
		floatingPanelManager.closeAll();		
		floatingPanelManager.open(this.floatingPanelId);
		
		this.set_tool(this.defaultTool);
	},

    _onClosePanel: function()
    {
        this.map.clear_tool();
    },


	
	_onMouseMove: function(sender, point){
		 /// <summary>
        /// Override the default onmousemove funtion for line/polygon tools 
        /// </summary>
        /// <param name="sender" type="MapsDirect.WebControls.Tools.ITool" mayBeNull="false">
        /// Current line tool
        /// </param> 
		/// <param name="point" type="MapsDirect.Geometry.Point" mayBeNull="false">
        /// Current mouse location
        /// </param>        
        Sys.Debug.trace("this.enableRealTimeUpdate = " + this.enableRealTimeUpdate);
        if(this.enableRealTimeUpdate == true) {
            this._calculate(sender, null, null);
        }
	},
	
	_addLineSegment : function(sender, e){
        this._calculate(sender, e, sender.graphic.geometry.segments.length-1);
	},
	
    _calculate: function (sender, e, segmentCount)
    {            
        //Sys.Debug.trace("_calculate().  measure.linearUnits = " + this.linearUnits);
		var distances = new Array();
        var totalDistance = 0;
        var segmentDistance = 0;
        var area = 0;
        var perimeter = 0;
        var roundFactor = Math.pow(10, 4);
        var xD, yD, tempDist, tempDist2, tempArea, x1, x2, y1, y2;
        var dPoints = new Array();
        if(sender == null) return;
        this.segments = sender.graphic.geometry.segments; 
        if(!segmentCount) segmentCount = this.segments.length;
         
        if(this.segments != null && segmentCount > 0){
            for(var i = 0; i < segmentCount; i++){
                var fromPoint = this.segments[i].fromPoint;
                var toPoint = this.segments[i].toPoint;
                if(measure.mapUnits == "degrees") {
                    // use great circle formula
                    tempDist = getDistanceBetweenDecimalDegreePoints(fromPoint, toPoint, "feet", false);
                    y1 = getDistanceBetweenDecimalDegreePoints(toPoint, {x: toPoint.x, y: 0}, "feet", false);
                    x1 = getDistanceBetweenDecimalDegreePoints(toPoint, {x: 0, y: toPoint.y}, "feet", false);
                    dPoints.push(new MapsDirect.Geometry.Point(x1, y1));
                    segmentDistance = convertUnits(tempDist, "feet", this.linearUnits);
                }else{
                    // get third side of triangle for distance
                    xD = Math.abs(toPoint.x - fromPoint.x);
                    yD = Math.abs(toPoint.y - fromPoint.y);
                    tempDist = Math.sqrt(Math.pow(xD, 2) + Math.pow(yD, 2));
                    segmentDistance = convertUnits(tempDist, this.mapUnits, this.linearUnits);
                }
                distances.push(segmentDistance);
                totalDistance += segmentDistance;
                
                segmentDistance = Math.round(segmentDistance * roundFactor) / roundFactor;
                totalDistance = Math.round(totalDistance * roundFactor) / roundFactor;
            }
        }
        if(this.activeTool.vectorMode == "poly")
        {
            if (this.segments.length >= 3)
            { 
                // add area calculation
                tempArea = 0;
                var mUnits = this.mapUnits;
                if (this.mapUnits == "degrees")
				{
					for(var j = 0; j < dPoints.length - 1; j++)
					{  
						x1 = dPoints[j].x;
						x2 = dPoints[j + 1].x;
						y1 = dPoints[j].y;
						y2 = dPoints[j + 1].y;
						mUnits = "feet";
						
						var xDiff = x2 - x1;
						var yDiff = y2 - y1;
						tempArea += (x1 * yDiff) - (y1 * xDiff);
						Sys.Debug.trace("tempArea = " + tempArea + ", xDiff = " + xDiff + ", yDiff = " + yDiff);
					}
				}else{
					for(var j = 0; j < this.segments.length; j++)
					{
						x1 = this.segments[j].fromPoint.x;
						x2 = this.segments[j].toPoint.x;
						y1 = this.segments[j].fromPoint.y;
						y2 = this.segments[j].toPoint.y;
	                    
						var xDiff = x2 - x1;
						var yDiff = y2 - y1;
						tempArea += (x1 * yDiff) - (y1 * xDiff);
						Sys.Debug.trace("tempArea = " + tempArea + ", xDiff = " + xDiff + ", yDiff = " + yDiff);
					}
				}
                tempArea = Math.abs(tempArea) / 2;
                area = convertAreaUnits(tempArea, mUnits, this.areaUnits);
                perimeter = Math.round(totalDistance * roundFactor) / roundFactor;
                area = Math.round(area * roundFactor) / roundFactor;           
            }
            $get("measurePerimeter").innerHTML = perimeter;
		    $get("measureArea").innerHTML = area;
        }else{		
		    $get("measureSegment").innerHTML = segmentDistance;
		    $get("measureTotalLength").innerHTML = totalDistance;
        }
    }
}
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();