﻿var _shapeFillColor_Default = new VEColor( 0, 0, 255, 0.2 );	//blue
var _shapeFillColor_Highlight = new VEColor( 255, 255, 0, .2 ); // yellow
var _shapeLineColor_Default = new VEColor( 0, 0, 255, 0.5 );    //blue line
var _shapeLineColor_Highlight = new VEColor( 185, 0, 0, 0.5 );    //red line
var _shapeLineColor_Error = new VEColor( 185, 0, 0, 0.6 );		//black line
var _shapeCount = 0;
var _shapeBeingDrawn = null;

// ############################################################
// ############################################################
// ############################################################
// SHAPE BASE
// ############################################################
// ############################################################
// ############################################################

// Selection shape can be Rectangle, Circle or Polygon
function HbmShape()
{
	this.strIcon = null;
	this.ID = null;
	this.theShape = null;
	this.bIsDrawing = false;
	this.bIsInclusive = true;
	this.bBypassEvent = false;
}

HbmShape.prototype.InitializeDisplayIcon = function()
	{
		if( this.ID == null )
		{
			this.ID = ++_shapeCount;
			this.strIcon = "<div class='pinStyleShapeNumber'><div class='text'>" + this.ID + "</div></div>";
		}
		return this.strIcon;
	}
	
HbmShape.prototype.GetIconString = function() { return this.strIcon; }

HbmShape.prototype.IsDefined = function()
	{
		if( this.theShape != null ) 
			return true;
		else
			return false;
	}
	
HbmShape.prototype.RenderMenu = function(menuPrefix)
	{
		var strMenu = '<div class="tier3">';
		if (menuPrefix != undefined) strMenu += menuPrefix;
		strMenu += "<a href='javascript:DeleteShape(\"" + this.theShape.GetID() + "\"); GetListings();'>" + DelSelectionTxt() + "</a>";
		strMenu += '</div>';
		return strMenu;
	}

HbmShape.prototype.BlockPopup = function()
	{
		_map.AttachEvent( 'onmouseover', EVTHdlrOnMouseOverBlock );
	}

HbmShape.prototype.UnBlockPopup = function()
	{
		_map.DetachEvent( 'onmouseover', EVTHdlrOnMouseOverBlock );
	}
	
HbmShape.prototype.ShapeCompleted = function()
    {
		this.bIsDrawing = false;

		SetPointer('pointer');
		SetPointer('auto');

		//UpdateShapeList();
		this.theShape.SetTitle("LOAD:");
	    DeselectAllShapes(this.theShape.GetShapeLayer());
	    SelectShape(this.theShape);

		//mapInstructions('hidden');
        _map.AttachEvent("onclick", OnMouseClick);
        _map.AttachEvent("onmousemove", MapMouseMove);
        GetListings();
	    
    }
    
function EVTHdlrOnMouseOverBlock( e )
{
	return true;
}

function CreateNewShape(strType)
{
    clearShapeLayers();  //temporary fix. Shape doesn't scale unless we clear and redraw layer first.
    
    // Check for birds eye view
    if(_map.GetMapStyle() == VEMapStyle.Birdseye)
    {
        ShowListingSearchWarning('Searching is not available in Birds Eye view');
        return;
    }

    // Check to see if we're already drawing a shape
    if (_shapeBeingDrawn)
    {
        _shapeBeingDrawn.FinalizeDrawing();
    }

    // Check to see if layer exists
    if (typeof(_drawLayer)!="undefined")
    {
        // Delete all existing listing icons
        _drawLayer.DeleteAllShapes();
    }
    else
    {
        // Create layer
        _drawLayer = new VEShapeLayer();
        _map.AddShapeLayer(_drawLayer);
    }
    
    _map.DetachEvent("onclick", OnMouseClick);
	//mapInstructions('visible');

	var NewShape = null;
	switch(strType)
	{
		case 'p':
			NewShape = new ShapePolygon();
			break;
		case 'c':
			NewShape = new ShapeCircle();
			break;
		case 'r':
			NewShape = new ShapeRectangle();
			break;
		default: return;
	}
			
	NewShape.InitializeDrawing();
	SetPointer('crosshair');
}

var DelSelectionTxt = function(  ){ return "Delete this shape"; };

// ############################################################
// ############################################################
// ############################################################
// RECTANGLE
// ############################################################
// ############################################################
// ############################################################

ShapeRectangle.prototype = new HbmShape;
ShapeRectangle.prototype.constructor = ShapeRectangle;
function ShapeRectangle()
{
	var self = this;
	
	this.Origin = null;

	this.handleEvent = hdlEvt;
	function hdlEvt(e)
	{
		switch( e.eventName )
		{
			case "onmousedown":
				return self.EVTHdlrOnMouseUpDownRectangle( e );
				break;
			case "onmouseup":
				return self.EVTHdlrOnMouseUpDownRectangle( e );
				break;
			case "onmousemove":
				return self.EVTHdlrOnMouseMoveRectangle( e );
				break;
		}
	}
	
	this.InitializeDrawing = initDraw;
	function initDraw()
	{
		this.bIsDrawing = true;
		this.BlockPopup();
		_map.AttachEvent( 'onmousedown', this.handleEvent );
		_shapeBeingDrawn = this;
	}
}

ShapeRectangle.prototype.CreateFromPoints = function( points )
	{
		if( points.length == 2 )
		{
			this.theShape = new VEShape( VEShapeType.Polygon, GetRectanglePoints( points ) );
			this.theShape.SetCustomIcon( this.InitializeDisplayIcon() );
			this.theShape.SetIconAnchor( points[0] );
            this.theShape.SetFillColor(_shapeFillColor_Default);
            this.theShape.SetLineColor(_shapeLineColor_Default);
            this.theShape.SetTitle("My Shape " + _shapeCount);
			this.theShape.SetDescription( this.RenderMenu() );
			_drawLayer.AddShape( this.theShape );
		}
	}

//ShapeRectangle.prototype.ExportToString = function()
//	{
//		if( this.theShape == null || this.bIsDrawing ) return;
//		
//		var strOut = ( this.bIsInclusive ? '' : '!' ) + 'r;';
//		var points = this.theShape.GetPoints();
//		strOut += points[0].Latitude + ',' + points[0].Longitude;
//		strOut += ',' + points[2].Latitude + ',' + points[2].Longitude;
//		return strOut;
//	}
	
ShapeRectangle.prototype.FinalizeDrawing = function()
	{
		this.UnBlockPopup();
		
		_map.DetachEvent( "onmouseup", this.handleEvent );
		_map.DetachEvent( "onmousedown", this.handleEvent );
		_map.DetachEvent( "onmousemove", this.handleEvent );

		if( this.IsDefined() )
		{
            this.ShapeCompleted();
			this.theShape.SetDescription( this.RenderMenu() );
		}

        _shapeBeingDrawn = null;

		return this.IsDefined();
	}

// OnMouseUpDown handler for Rectangle selection
ShapeRectangle.prototype.EVTHdlrOnMouseUpDownRectangle = function( e )
	{
		if (e.eventName == "onmousedown" && this.theShape == null )
		{
			var veLLPt = _map.PixelToLatLong( new VEPixel( e.mapX, e.mapY ) );
			this.Origin = veLLPt;
			this.CreateFromPoints( [ veLLPt, veLLPt ]  ) ;
			this.bIsDrawing = true;
			_map.AttachEvent( "onmousemove", this.handleEvent );
			_map.AttachEvent( "onmouseup", this.handleEvent );
			return true;
		}

		if( e.eventName == "onmouseup" && this.bIsDrawing )
		{
			if( this.theShape )
			{
				var pts = this.theShape.GetPoints();
				if( Math.abs( Math.abs(pts[0].Latitude) - Math.abs(pts[2].Latitude) ) < 0.001 ||
					Math.abs( Math.abs(pts[0].Longitude) - Math.abs(pts[2].Longitude) ) < 0.001 )
				{
					_drawLayer.DeleteShape( this.theShape );
					delete this.theShape;
					this.theShape = null;
					--_shapeCount;
				}
			}
			this.FinalizeDrawing();
			return true;
		}
	}

// OnMouseMove handler for Rectangle drawing
ShapeRectangle.prototype.EVTHdlrOnMouseMoveRectangle = function( e )
	{
//		this.PanMap( e );
		
		// To speed up rendering appearance in IE7 only process every other event.
		this.bBypassEvent = !this.bBypassEvent;
		if( this.bBypassEvent ) return;
		
		var veLLPt = _map.PixelToLatLong( new VEPixel( e.mapX, e.mapY ) );
		 
		if( this.theShape != null )
		{
			this.theShape.SetPoints( GetRectanglePoints( [this.Origin, veLLPt] ) );
			this.theShape.SetIconAnchor( this.Origin );
		}
	}

function GetRectanglePoints( points )
{
	if( points.length == 2 )
	{
		var veLLOrigin = points[0];
		var veLLPt = points[1];
		// always draw longitudinally from origin to lat of mouse loc, then
		// latitudinally to mouse, then longitudinally again and back to origin.
		points.splice( 1, 0, new VELatLong( veLLPt.Latitude, veLLOrigin.Longitude ) );
		points.push( new VELatLong( veLLOrigin.Latitude, veLLPt.Longitude ) , veLLOrigin );
	}

	return points;
}

// ############################################################
// ############################################################
// ############################################################
// CIRCLE
// ############################################################
// ############################################################
// ############################################################

ShapeCircle.prototype = new HbmShape;
ShapeCircle.prototype.constructor = ShapeCircle;
function ShapeCircle()
{
	var self = this;

	this.theLine = null;
	this.theCircleOrigin = null;
	this.radiusLabel = null;

	this.handleEvent = hdlEvt;
	function hdlEvt( e )
	{
		switch( e.eventName )
		{
			case "onmousedown":
				return self.EVTHdlrOnMouseUpDownCircle( e );
				break;
			case "onmouseup":
				return self.EVTHdlrOnMouseUpDownCircle( e );
				break;
			case "onmousemove":
				return self.EVTHdlrOnMouseMoveCircle( e );
				break;
		}
	}
	
	this.InitializeDrawing = initDraw;
	function initDraw()
	{
		this.bIsDrawing = true;
		this.BlockPopup();
		_map.AttachEvent( 'onmouseup', this.handleEvent );
		_map.AttachEvent( 'onmousedown', this.handleEvent );
		_shapeBeingDrawn = this;
	}
}

ShapeCircle.prototype.CreateFromPoints = function( points, rad )
	{
		if( points.length >= 1 )
		{
			this.theShape = new VEShape( VEShapeType.Polygon, [ points[0], points[0], points[0] ] );
			this.theShape.SetCustomIcon( this.InitializeDisplayIcon() );
			this.theShape.SetIconAnchor( points[0] );
            this.theShape.SetFillColor(_shapeFillColor_Default);
            this.theShape.SetLineColor(_shapeLineColor_Default);
            this.theShape.SetTitle("My Shape " + _shapeCount);
			this.theShape.SetDescription( this.RenderMenu() );
			_drawLayer.AddShape( this.theShape );
			
			this.theLine = new VEShape( VEShapeType.Polyline, points );
			_drawLayer.AddShape( this.theLine );

			this.UpdateCircle( points, rad );
		}
	}
	
ShapeCircle.prototype.UpdateCircle = function( points, radius )
	{
		if( radius == null && points.length > 1 )
		{
			radius = GetRadiusInKM( points[0].Clone(), points[1].Clone() );
		}

		if( radius != null )
		{
			var thePoints = GetCirclePoints( points[0], radius, 6 );
			this.theShape.SetPoints( thePoints );
			radius = (radius*0.6214).toFixed(2); // radius = (UseMiles?radius*0.6214:radius).toFixed(2);
			this.radiusLabel = radius + ' miles'; // this.radiusLabel = radius + (UseMiles ? ' miles' : ' km');
			this.theLine.SetPoints( points );
			this.theLine.SetCustomIcon('<div style="background:#FFFFCC;font-size:small;text-decoration:none;font:arial;white-space:nowrap;">' + this.radiusLabel + '</div>');
		}
	}

//ShapeCircle.prototype.ExportToString = function()
//	{
//		if( this.theShape == null || this.bIsDrawing ) return;
//		
//		var strOut = ( this.bIsInclusive ? '' : '!' ) + 'c;';
//		strOut += this.theCircleOrigin.Latitude + ',' + this.theCircleOrigin.Longitude + ',' + GetRadiusInKM( this.theCircleOrigin.Clone(), this.theShape.GetPoints()[0].Clone() );
//		return strOut;
//	}

ShapeCircle.prototype.FinalizeDrawing = function()
	{	
		this.UnBlockPopup();

		_map.DetachEvent( "onmouseup", this.handleEvent );
		_map.DetachEvent( "onmousedown", this.handleEvent );
		_map.DetachEvent( "onmousemove", this.handleEvent );

		if( this.theLine != null )
		{
			_drawLayer.DeleteShape( this.theLine );
			delete this.theLine;
			this.theLine = null;

			if( this.IsDefined() )
			{
                this.ShapeCompleted();
                var menuPrefix = "Radius: " + this.radiusLabel + "<br>";
                this.theShape.SetDescription( this.RenderMenu(menuPrefix) );
			}
		}

        _shapeBeingDrawn = null;

		return this.IsDefined();
	}
	
ShapeCircle.prototype.EVTHdlrOnMouseUpDownCircle = function( e )
	{
		if( e.eventName == "onmousedown" && this.theShape == null )
		{
			var centerLL = _map.PixelToLatLong( new VEPixel( e.mapX, e.mapY )  );
			this.theCircleOrigin = centerLL.Clone();
			this.CreateFromPoints( [ centerLL, centerLL ] );
			_map.AttachEvent( "onmousemove", this.handleEvent );
			this.bIsDrawing = true;
		}
		else if( e.eventName == "onmouseup" && this.bIsDrawing )
		{
			if( this.theShape )
			{
				var pts = this.theShape.GetPoints();
				if( Math.abs( Math.abs(pts[0].Latitude) - Math.abs(this.theCircleOrigin.Latitude) ) < 0.001 &&
					Math.abs( Math.abs(pts[0].Longitude) - Math.abs(this.theCircleOrigin.Longitude) ) < 0.001 )
				{
					_drawLayer.DeleteShape( this.theShape );
					delete this.theShape;
					this.theShape = null;
					--_shapeCount;
				}
			}
			this.FinalizeDrawing();
		}
		
		return true;
	}
	
ShapeCircle.prototype.EVTHdlrOnMouseMoveCircle = function( e )
	{
//		this.PanMap( e );

		// To speed up rendering appearance in IE7 only process every other event.
		this.bBypassEvent = !this.bBypassEvent;
		if( this.bBypassEvent ) return;
		
		if( this.theCircleOrigin && this.theShape )
		{
			var curLatLong = _map.PixelToLatLong( new VEPixel( e.mapX, e.mapY ) );
			this.UpdateCircle( [ this.theCircleOrigin, curLatLong ] );
		}
		
		return true;
	}


function GetRadiusInKM(p1, p2) {
	p1.Latitude= latLonToRadians(p1.Latitude);
	p1.Longitude= latLonToRadians(p1.Longitude);
	
	p2.Latitude= latLonToRadians(p2.Latitude);
	p2.Longitude= latLonToRadians(p2.Longitude);	
	var R = 6371; // earth's mean radius in km
	var dLat  = Math.abs(p2.Latitude- p1.Latitude);
	var dLong = Math.abs(p2.Longitude- p1.Longitude);
	var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
		Math.cos(p1.Latitude) * Math.cos(p2.Latitude) * Math.sin(dLong/2) * Math.sin(dLong/2);
	var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
	var disKm = R * c;

	return disKm;
}

//  convert lat/long in degrees to radians
function latLonToRadians( point ) {
	return point * Math.PI / 180;	
}

function GetCirclePoints(loc, radius, jagginess)
{
	var R = 6371; // earth's mean radius in km
	var lat = latLonToRadians(loc.Latitude);
	var lon = latLonToRadians(loc.Longitude);
	var d = parseFloat(radius)/R;  // d = angular distance covered on earth's surface
	var locs = new Array();
	var jags = 1;
	if( jagginess != null ) jags = jagginess;
	
	for (x = 0; x <= 360; x+=jags) 
	{ 
		var p2 = new VELatLong( loc.Latitude, loc.Longitude );
		brng = latLonToRadians( x ); //rad
		p2.Latitude = Math.asin(Math.sin(lat)*Math.cos(d) + Math.cos(lat)*Math.sin(d)*Math.cos(brng));
		p2.Longitude = ((lon + Math.atan2(Math.sin(brng)*Math.sin(d)*Math.cos(lat), Math.cos(d)-Math.sin(lat)*Math.sin(p2.Latitude))) * 180) / Math.PI;
		p2.Latitude = (p2.Latitude * 180) / Math.PI;
		locs.push(p2);
	}

	return locs; 
}

// ############################################################
// ############################################################
// ############################################################
// POLY
// ############################################################
// ############################################################
// ############################################################

ShapePolygon.prototype = new HbmShape;
ShapePolygon.prototype.constructor = ShapePolygon;
function ShapePolygon()
{
	var self = this;
	
	// Used during drawing
	this.polyOrigin = null;
	this.polyOriginPin = null;
	this.polyLastPixel = null;
	this.NormalColourLine = _shapeLineColor_Default;
	this.ErrorColourLine = _shapeLineColor_Error;
	
	this.handleEvent = hdlEvt;
	function hdlEvt( e )
	{
		switch( e.eventName )
		{
			case "onmouseup":
				self.EVTHdlrOnMouseUpPoly( e );
				break;
			case "onmousemove":
				self.EVTHdlrOnMouseMovePoly( e );
				break;
//			case "onkeypress":
//				self.EVTHdlrKeybEnter( e );
//				break;
			case "onmouseover":
				self.EVTHdlrUpdatePopupActions( e );
				break;
		}
	}
	
	this.InitializeDrawing = initDraw;
	function initDraw()
	{
		this.bIsDrawing = true;
		this.BlockPopup();
		_map.AttachEvent( 'onmouseup', this.handleEvent );
		_shapeBeingDrawn = this;
	}
}

ShapePolygon.prototype.CreateFromPoints = function( points )
{
	if( points.length > 2 )
	{
		this.theShape = new VEShape( VEShapeType.Polygon, points );
		this.theShape.SetCustomIcon( this.InitializeDisplayIcon() );
		this.theShape.SetIconAnchor( points[0] );
        this.theShape.SetFillColor(_shapeFillColor_Default);
        this.theShape.SetLineColor(_shapeLineColor_Default);
        this.theShape.SetTitle("My Shape " + _shapeCount);
		this.theShape.SetDescription( this.RenderMenu() );
		_drawLayer.AddShape( this.theShape );
	}
}

//ShapePolygon.prototype.ExportToString = function()
//	{
//		if( this.theShape == null || this.bIsDrawing ) return;
//		
//		var strOut = ( this.bIsInclusive ? '' : '!' ) + 'p;';
//		var points = this.theShape.GetPoints();
//		var seperator = '';
//		for( var i=0; i < points.length; i++ )
//		{
//			strOut += seperator + points[i].Latitude + ',' + points[i].Longitude;
//			seperator = ',';
//		}
//		return strOut;
//	}

ShapePolygon.prototype.FinalizeDrawing = function()
	{
		this.UnBlockPopup();
		
		if( this.theShape && this.bIsDrawing )
		{
			// Delete if not yet a polygon
			if( this.theShape.GetType() != VEShapeType.Polygon )
			{
				_map.DeleteShape( this.poly );
				delete this.theShape;
				this.theShape = null;
			}
			else
			{ 
				this.theShape.SetCustomIcon( this.GetIconString() );
				this.theShape.SetIconAnchor( this.polyOrigin );
                this.theShape.SetTitle("My Shape " + _shapeCount);
				this.theShape.SetDescription( this.RenderMenu() );
				//this.theShape.ShowIcon();
				//_map.AttachEvent( "onmouseover", this.handleEvent );
			}
		}
		
		_map.DetachEvent( "onmouseup", this.handleEvent );
		_map.DetachEvent( "onmousemove", this.handleEvent );

		if( this.polyOriginPin )
		{
			_map.DeleteShape( this.polyOriginPin );
			delete this.polyOriginPin;
			delete this.polyOrigin;
		}
		this.polyOrigin = null;
		this.polyLastPixel = null;

        if (this.theShape)
        {
            this.ShapeCompleted();
        }
		
        _shapeBeingDrawn = null;

		return this.IsDefined();
	}


ShapePolygon.prototype.FinishPolygon = function( points )
	{
		this.theShape.SetLineColor( this.NormalColourLine );
		// Remove the last segment and re-attach directly to origin (implicit in setpoints)
		points.pop(); points.pop();
		this.theShape.SetPoints( points );
		this.FinalizeDrawing();
	}

//ShapePolygon.prototype.EVTHdlrKeybEnter = function( e )
//	{
//		if( e.eventName == "onkeypress" && this.bIsDrawing && ( e.keyCode == 32 || e.keyCode == 13 ) &&
//			this.theShape && this.theShape.GetType() == VEShapeType.Polygon )
//		{
//			var points = this.theShape.GetPoints();
//			if( points.length > 4 )
//			{
//				this.FinishPolygon( points );
//			}
//		}
//		else if( e.eventName == "onkeypress" && this.bIsDrawing && (e.keyCode == 8 || e.keyCode == 46) &&
//			 this.theShape && this.theShape.GetType() == VEShapeType.Polygon )
//		{
//			var points = this.theShape.GetPoints();
//			if( points.length > 4 )
//			{
//				points.splice( points.length-3, 1 );
//				this.theShape.SetPoints( points );
//			}
//		}	
//	}

ShapePolygon.prototype.EVTHdlrOnMouseUpPoly = function( e )
	{
		if( e.eventName == "onmouseup" )
		{
			if( this.bIsDrawing && this.polyOrigin )
			{
				var curPixel = new VEPixel( e.mapX, e.mapY );
				var curLatLong = _map.PixelToLatLong( curPixel );
				var points = this.theShape.GetPoints();

				if( (e.elementID && e.elementID.indexOf( this.polyOriginPin.GetID() ) >= 0) || e.rightMouseButton )
				{
					if( this.theShape.GetType() != VEShapeType.Polygon || points.length <= 4 ) return;
					this.FinishPolygon( points );
					return;
				}
				if( Math.abs( e.mapX - this.polyLastPixel.x ) > 4 || Math.abs( e.mapY - this.polyLastPixel.y ) > 4 )
				{
					var bIsLine = this.theShape.GetType() == VEShapeType.Polyline;

					if( !bIsLine && points.length > 4 && FinalSegmentCrossesAnother( points ) )
					{
						this.theShape.SetLineColor( this.ErrorColourLine );
						return;
					}
					else
					{
						this.theShape.SetLineColor( this.NormalColourLine );
					}

					var nIndex = 1;
					if( this.theShape.GetType() == VEShapeType.Polygon )
						nIndex = points.length - 2;
					
					points.splice( nIndex, 1, curLatLong, curLatLong );

					if( bIsLine )
					{
						_drawLayer.DeleteShape( this.theShape );
						points.push( this.polyOrigin );
						this.theShape = new VEShape( VEShapeType.Polygon, points );
                        this.theShape.SetFillColor(_shapeFillColor_Default);
                        this.theShape.SetLineColor(_shapeLineColor_Default);
						//this.theShape.SetCustomIcon( this.GetIconString() );
						this.theShape.SetCustomIcon("../App_Themes/Default/Images/Map/polygonFinish.gif");
						//this.theShape.HideIcon();  //hides icon when drawing line
						_drawLayer.AddShape( this.theShape );
					}
					else
					{
						this.theShape.SetPoints( points );
					}
					this.polyLastPixel = curPixel;
				}
			}
			else
			{	// start off as a line, then start with the poly
				this.polyLastPixel = new VEPixel( e.mapX, e.mapY );
				this.polyOrigin = _map.PixelToLatLong( this.polyLastPixel );
				
				this.polyOriginPin = new VEShape( VEShapeType.Pushpin, this.polyOrigin );
				this.polyOriginPin.SetCustomIcon( this.InitializeDisplayIcon() );
				_drawLayer.AddShape( this.polyOriginPin );

				this.theShape = new VEShape( VEShapeType.Polyline, [this.polyOrigin,this.polyOrigin] );
                this.theShape.SetFillColor(_shapeFillColor_Default);
                this.theShape.SetLineColor(_shapeLineColor_Default);
				this.theShape.SetCustomIcon( this.GetIconString() );
				this.theShape.HideIcon(); //hides icon when drawing shape
				_drawLayer.AddShape( this.theShape );
				this.bIsDrawing = true;
				_map.AttachEvent( "onmousemove", this.handleEvent );
//				_map.AttachEvent( 'onkeypress', this.handleEvent );
			}
		}
	}
	
ShapePolygon.prototype.EVTHdlrOnMouseMovePoly = function( e )
	{
//		this.PanMap( e );

		// To speed up rendering appearance in IE7 only process every other event.
		this.bBypassEvent = !this.bBypassEvent;
		if( this.bBypassEvent ) return;

		var pts = this.theShape.GetPoints();
		var nIndex = 1;
		if( this.theShape.GetType() == VEShapeType.Polygon )
			nIndex = pts.length - 2;
			
		pts[nIndex] = _map.PixelToLatLong( new VEPixel( e.mapX, e.mapY ) );
		this.theShape.SetPoints( pts );
	}
	
function FinalSegmentCrossesAnother( points )
{
	// Get the segment in question.
	var A = points[ points.length - 2 ];
	var B = points[ points.length - 3 ];
	
	// Now parse all previous segments
	for( var i=points.length - 3; i >= 1; --i )
	{
		var C = points[i];
		var D = points[i-1];
		
		if( ArePointsClockWise( A,B,C ) == ArePointsClockWise( B,A,D ) && ArePointsClockWise( C,D,A ) == ArePointsClockWise( D,C,B ) )
			return true;
	}
	
	return false;
}

function ArePointsClockWise( P1, P2, P3 )
{
	return ( (P2.Latitude - P1.Latitude) * (P3.Longitude - P1.Longitude) ) < ( (P2.Longitude - P1.Longitude) * (P3.Latitude - P1.Latitude) );
}

