/*	This Javascript is compatible with only the following browser versions **
** Internet Explorer - Versions 6.0,5.5,5.0
** Netscape navigator - Version 7.0 and later
** Mozilla Firefox - Versions 1.0 and later
**************************************************/
var xmin,xmax,ymin,ymax; //Used for zoom box
var divLeft=-1,divTop=-1; //Used for netscape to represent top,left of map div tag
var Xoffset = 0; //Used for 'right to left' layout
var mouseX, mouseY; //Coordinate of last point clicked by user
var isNav = (window.navigator.appName.toLowerCase().indexOf("netscape")>=0);
var isIE = (window.navigator.appName.toLowerCase().indexOf("microsoft")>=0);
var isIE5 = (navigator.appVersion.indexOf("MSIE 5.01")>0); //Filters are not supported on IE 5.5

if(isIE)
{
    //VML namespace declaration. Required for drawing graphics in IE.
    //VML is supported in IE 5.0 and later versions.
    document.writeln('<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v"/>\n');
    document.writeln('<style type="text/css"> v\\:* { behavior: url(#default#VML);} </style>\n');
}
else
    document.writeln("<div id='canvas' style='position:absolute;left:0px;top:0px;width:500px;height:500px;visibility:hidden;'></div>");

var callBackMethod = null; //This method will be called when user finishes drawing a shape
var callBackVertexMove = null; //This method is called when user moves vertex of a shape. The shape is passed as paremeter to the call back method
var callBackVertexAdd = null;  //This method is called each time when a point is added while drawing a shape (Each point clicked).

//var buttonPressed=MouseButton.LEFT;
//var KeyPressed=Key.NONE;

var mapDivId;
var mapControlId;
var mapWidth;
var mapHeight;
var autoPostBack = false;
var graphicsObj	= null;
var mapDiv		=	null;	//Div tag that contains all map images
var graphicsDiv	=	null; //Div tag that contain all user drawn graphics by non IE browsers
var canvasDiv	=	null; //Used by non IE browsers to temporarily hold graphics
var contextMenuDiv = null; //Used for displaying context menu
var zoomBox 	=	null;
var clearPreviousDrawing = true;//Set it to false if the previous drawing has to be maintained. Used for vertex editing for adding a vertex
var addAsMultiPart = false; //Setting this to true creates a single shape with multiple parts until this set to false.
var overviewMap; //Reference to overview map pop-up window. Always check for !overviewMap.closed, before using it.
var mapObjects=null;
var shapesCol=new ShapeCollection(maxShapes); //Holds collection of user drawn shapes
var mapSourceSessionKey=null;
var mapscaleTextBox=null;
var m_fadeEffects = false && (isIE && !isIE5);//can be true only for IE >= 6 

//Initializes a map control object. 
function initializeMapControl(mapId)
{   
    if(mapDiv != null)
        mapDiv=null;
    if(graphicsDiv != null)
        graphicsDiv=null;
    if(graphicsObj !=null)
       graphicsObj=null;
    if(canvasDiv !=null)
        canvasDiv=null;
    if(zoomBox !=null)
        zoomBox=null;
    if(contextMenuDiv != null)
        contextMenuDiv=null;
        
    if(mapDiv == null)
        mapDiv=getObject('MapControlDiv');
    if(graphicsDiv == null)
        graphicsDiv=getObject('graphics');
    if(graphicsObj==null)
        graphicsObj=new jsGraphics('canvas');
    if(canvasDiv==null)
        canvasDiv=getObject('canvas');
    if(zoomBox==null)
        zoomBox=getObject('zoombox');
    if(contextMenuDiv == null)
        contextMenuDiv=getObject('mcContextMenu');
    
    var values = document.getElementsByName('customParams')[0].value.split("|");
    mapControlId = values[0];
    mapWidth = parseInt(values[1]);
    mapHeight = parseInt(values[2]);
    lineColor = values[3];
    lineWidth = parseInt(values[4]);
    lineStyle = values[5];
    fill = values[6];
    fillColor = values[7];
    fillType = values[8];
    fillOpacity = parseFloat(values[9]);
    maxShapes = parseInt(values[10]);
    pointSize = parseInt(values[11]);
    pointColor = values[12];
    pointType = eval('PointType.' + values[13]);
    isDrawVertice = values[14];
    vertexColor = values[15];
    
    mapExtents.xmin = parseFloat(values[16]);
    mapExtents.ymin = parseFloat(values[17]);
    mapExtents.xmax = parseFloat(values[18]);
    mapExtents.ymax = parseFloat(values[19]);
    
    var numberOfMaps = parseInt(values[20]);
    mapObjects = new Array();
    for(var i=0; i<numberOfMaps; i++){
        mapObjects.push(new MapObject('MapControlMap' + i,'MapImage' + i));
    }
    
    mapSourceSessionKey = values[21];
    
    shapesCol = new ShapeCollection(maxShapes)
    
    DefaultStyle = new DefaultTheme(lineColor,lineWidth,lineStyle,fill,fillColor,fillOpacity,fillType, pointColor, pointType);        
    
    setAutoPostback(values[22]);
}

//Events 
var removeShapesEventListeners;
function RegisterRemoveShapesEvent(callBackMethod)
{
//    if(typeof(callBackMethod)=='function')
//    {
        if(removeShapesEventListeners==null)
            removeShapesEventListeners=new Array();
        removeShapesEventListeners.push(callBackMethod);
//    }
}
//End events
    
document.ondragstart=function(){return false;}
//document.onselectstart=function{return false;}
	
	function CallBack(e)
	{
	    //Called by map control when user finishes drawing graphics
		//This method is responsible for doing all post back to server
		if(!sessionExpired)
	    {
		    setSubmitValues(); //Prepares the geomtetry xml to be posted back
		    if(currentDrawMode == DrawMode.DRAG || currentDrawMode == DrawMode.ZOOMBOX)
		    {
		        RemoveAllShapes(); //Clear the geometry 

			    if(!window.m_lastActiveToolBar ||  !m_lastActiveToolBar)
			    {
				    alert("No tool selected. Please select a tool");
				    return;
			    }
    			
    			
			    var selectedTool = m_lastActiveToolBar.GetSelectedTool().ToolName;			   
			 
			    var w = Math.abs(xmax-xmin);
			    var h = Math.abs(ymax-ymin);
			    var l = (xmax < xmin) ?  xmax : xmin
			    var t = (ymax < ymin) ?  ymax : ymin;
			    
				var lyrStyles = _GetLyrMgrStyles();				
				switch(selectedTool)
				{
					case "ZoomIn":
					{
						showLoading();
				       			          
						if(Math.abs(xmax-xmin) < 2 && Math.abs(ymax-ymin) < 2)
						   try
						   {   
								PageMethods.ZoomIn(1, mapSourceSessionKey, xmin, ymin,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
						   }
						   catch(e)
						   {
								_OnPointWebControls.Map.MapControl.ZoomInAdmin(1, mapSourceSessionKey, xmin, ymin,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
						   } 
						else
					   { 
							try
						   {
								PageMethods.ZoomTo(1, mapSourceSessionKey, l, t, l+w, t+h,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
						   }
						   catch(e)
						   {
								_OnPointWebControls.Map.MapControl.ZoomToAdmin(1, mapSourceSessionKey, l, t, l+w, t+h,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
						   } 
					   } 

					break;
					}
					case "ZoomOut":
					{
						showLoading();
						if(Math.abs(xmax-xmin) < 2 && Math.abs(ymax-ymin) < 2)
					   { 
							try
						   { 
								PageMethods.ZoomOutPoint(1, mapSourceSessionKey, xmin, ymin,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
						   }
						   catch(e)
						   {
								_OnPointWebControls.Map.MapControl.ZoomOutPointAdmin(1, mapSourceSessionKey, xmin, ymin,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
						   } 
						} 
						else
					   {
							try
						   { 
							PageMethods.ZoomOut(1, mapSourceSessionKey, l, t, l+w, t+h,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
						   }
						   catch(e)
						   {
								 _OnPointWebControls.Map.MapControl.ZoomOutAdmin(1, mapSourceSessionKey, l, t, l+w, t+h,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
						   } 
					   } 
						break;
					}   
					case "DragPan":
					{
						showLoading();
						try
					   { 
							PageMethods.CenterTo(1, mapSourceSessionKey, (xmax-xmin) , (ymax-ymin),lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
					   } 
					   catch(e)
					   {
							_OnPointWebControls.Map.MapControl.CenterToAdmin(1, mapSourceSessionKey, (xmax-xmin) , (ymax-ymin),lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
					   }
					}    
				}
		    }
		    else
		    {
			    //Invoke call back method if it is set during SetDrawMode
			    var callBackReturnValue;
			    if(callBackMethod != null)
			    {
				    try
				    {
					    callBackReturnValue = eval(callBackMethod + '(GetLastShape())');									
				    }
				    catch(e)
				    {
				    }
			    }
    		    
			    //Post back if 'autoPostBack' is set to true and callback method returns false.
			    if(window.autoPostBack && (callBackReturnValue==null || callBackReturnValue == true) && currentDrawMode != DrawMode.NONE)
			    {
			        if(!isCntlKey(e))
			        {
			          __doPostBack(document.forms[0].__EVENTTARGET.value,document.forms[0].__EVENTARGUMENT.value);
				    }
		        }
		    }
		}
		else
		{
		    HandleSessionExpired();
		}	
	}
	
	//Parses response xml from server and refreshes map images
	 function HandleServerResponse(obj)
	 {	    
//	 	 hideLoading();	 
	     if(obj!=null)
	     {	      
	        if(obj.error == null)
	        {
	          var xmlStr = null;
	          //In Atlas,obj sends the response instead of object.value (AjaxPro sends in ajax.value)
	          if (obj.value)
	            xmlStr = obj.value;
	          else
	            xmlStr = obj;	            
	            try
	            {   
	                if(isIE)
	                {
	            	    objXmlDoc = new ActiveXObject("Msxml2.DOMDocument");
	            	    objXmlDoc.loadXML(xmlStr);	            	    
	                }
	                else
	                {
	                    objXmlDoc = new DOMParser().parseFromString(xmlStr, "text/xml");	                    
	                }
	                
	                //Parse for any error messages
	                var errorNodes = objXmlDoc.getElementsByTagName("ERROR");
                    if(errorNodes!=null && errorNodes.length>0)
                    {
                        var message = getAttributeValue(errorNodes[0],"message"); 
                        if(message !=null && message.length>0)
                        {
                            alert(message);
                        }
                    }
                    else
                    {
	                    RefreshMapContents(objXmlDoc);
	                    RefreshLayerManager(objXmlDoc);
                        RefreshMapTipLayers(objXmlDoc);						
                    }
                 }
                 catch(ex)
                 {
                    //alert('HandleServerResponse - exception:' + ex.message);
                 }
	        }
	        else
	        {
	            alert(obj.error);
	        }  
	    }
    }	
  		
	
    function openSavePopup(onPointSaveSelectionPath)
	{
	    if(!sessionExpired)
	    {
	        HandleSaveSelectionFrame(onPointSaveSelectionPath);
	    }
	    else
	    {
	        HandleSessionExpired();
	    }
	}
	function openRetrieveSelectionPopup(onPointVirtualDir)
	{
	  if(!sessionExpired)
	    {
	        HandleRetriveSelectionFrame(onPointVirtualDir + '?CMD=RetrieveSelections');
	    }
	    else
	    {
	        HandleSessionExpired();
	    }
	}
	
	function openRetrieveRedliningPopup(onPointVirtualDir)
	{
	     if(!sessionExpired)
	    {
	        HandleRetriveSelectionFrame(onPointVirtualDir + '?CMD=RetrieveRedlining');
	    }
	    else
	    {
	        HandleSessionExpired();
	    }
	}

	
	function GenerateUrlHandler(shape)
	{        
        var frame = window.frames[_GenerateUrlIframe];        
        if (frame && frame.window && frame.window.ReceiveShape)
        {
            frame.window.ReceiveShape(shape);
        }       
        
        return false;
    }
    
	function callBackOnVertexAdd()
	{
		if(callBackVertexAdd != null)
		{
		    try
		    {
		        eval(callBackVertexAdd + '()');
		    }catch(e){}
		}		
	}
	function callBackOnVertexMove(shape, index)
	{
		if(callBackVertexMove != null)
		{
		    try
		    {
		        eval(callBackVertexMove + '(shape,index)');
		    }
		    catch(e){alert(e)}
		}		
	}
	
	PanDirection={North:0,South:1,East:2,West:3,NorthEast:4,NorthWest:5,SouthEast:6,SouthWest:7}
	
	function PanClicked(dir)
	{
	    if(!sessionExpired)
		{
		    RemoveAllShapes(); //Clear the geometry 
		    showLoading();
		    var lyrStyles = _GetLyrMgrStyles();	
		    if(window.PageMethods)
		    {
		        PageMethods.Pan(1, mapSourceSessionKey, ('' + dir),lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
		    }
		    else
		    {
		        _OnPointWebControls.Map.MapControl.PanAjax(1, mapSourceSessionKey, ('' + dir),lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
		    }
		}		
	    else
	    {
	        HandleSessionExpired();
	    }	
	}
	
	function doFullView()
	{
	    
		if(!sessionExpired)
		{
			RemoveAllShapes(); //Clear the geometry 
			showLoading();
			var lyrStyles = _GetLyrMgrStyles();
			try
			{  
				PageMethods.ZoomToFullView(1, mapSourceSessionKey,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
			}
			catch(e)
			{
				_OnPointWebControls.Map.MapControl.ZoomToFullViewAdmin(1, mapSourceSessionKey,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
			}   
		}
		else
		{
			HandleSessionExpired();
		}	
	}
	
	function navigateMapHistory(direction)
	{
		if(!sessionExpired)
		{
			RemoveAllShapes(); //Clear the geometry 
			showLoading();
			var lyrStyles = _GetLyrMgrStyles();	
			if(direction=='PREVIOUS_MAP')
			{
				try
				{
					PageMethods.DisplayPreviousImages(1, mapSourceSessionKey,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
				}
				catch(e)
				{
					_OnPointWebControls.Map.MapControl.DisplayPreviousImagesAdmin(1, mapSourceSessionKey,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
				}  
			} 
			else if(direction=='NEXT_MAP')
			{
				try
				{
					PageMethods.DisplayNextImages(1, mapSourceSessionKey,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
				}
				catch(e)
				{
					_OnPointWebControls.Map.MapControl.DisplayNextImagesAdmin(1, mapSourceSessionKey,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
				} 
			}
		}
		else
		{
			HandleSessionExpired();
		}
	}
	//Refreshes map with a new scale value
	function doZoomToScale(scale)
	{	    
	    if(!sessionExpired)
	    {
		    if(scale != null && scale.length > 0)
		    {
				RemoveAllShapes();			    
				showLoading();
				var lyrStyles = _GetLyrMgrStyles();	
				try
				{
					PageMethods.ZoomToScale(1, mapSourceSessionKey, scale,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
				}
				catch(e)
				{
					_OnPointWebControls.Map.MapControl.ZoomToScaleAdmin(1, mapSourceSessionKey, scale,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);
				}
			}
			else
			{
			    alert("Please enter some numeric value for scale");
			}
		}
		else
	    {
	        HandleSessionExpired();
	    }	
	}
	
	//Uncomment this if you want to display the OverveiwMap in a new window and not iFrame.
	//var MapOverViewiFrame=null;
	//----------------------
	function doOverviewMap(path)
	{
	    if(!sessionExpired)
	    {
		    if( path ==null){
		        if (window.NGServerUrl)
			        {
				        path=NGServerUrl()+"/WebPages/Map/OverviewMap.aspx";
				    }
			    else
				    {
					    path=appBasePath + "/WebPages/Map/OverviewMap.aspx";
				    }
		        }
		    //If the HandleOverviewMapFrame function exist to show the window in a iFrame then call it else open a new window.
		    if (window.HandleOverviewMapFrame)
		      {
			    HandleOverviewMapFrame(path);
		      }
		    else
		     {
			    if (window.NGServerUrl)
				    {
					    path=NGServerUrl()+path;
				    }
			    else
				    {
					    //path=getApplicationPath()+path;
					    path = appBasePath + path;
				    }
    				
			    if(window.overviewMapWidth==null)
	    		    overviewMapWidth=180;
    		    if(window.overviewMapHeight==null)
		    	    overviewMapHeight=160;
			    MapOverViewiFrame=window.open(path,"Overview","dependent=yes,resizable=no,titlebar=no,toolbar=no,scrollbars=no,width=" + overviewMapWidth + ",height=" + overviewMapHeight + ",left=20,top=20, status=no");
				    MapOverViewiFrame.focus();
		    }
		}
		else
	    {
	        HandleSessionExpired();
	    }	
                
	}
	
    //----------------------
	function doLegend(path)
	{
	    if(!sessionExpired)
	    {
		    if (path==null) 
		    {
		        if (window.NGServerUrl)
				    {
					    path=NGServerUrl()+"/WebPages/Map/Legend.aspx";
				    }
			    else
				    {
					    path=appBasePath + "/WebPages/Map/Legend.aspx";
				    }
	        }

		    //If the HandleLegendFrame function exist to show the window in a iFrame then call it else open a new window.
		    if (window.HandleLegendFrame)
		      {
			    HandleLegendFrame(path);
		      }
		    else
		     {
    	
			    var legend=window.open(path,"Legend","titlebar=no,toolbar=no,width=400,height=500,left=20,top=20,status=no,resizable=yes");
				    legend.focus();
		    }
		}
		else
	    {
	        HandleSessionExpired();
	    }	
	}
	
	//Object that holds x and y coordinates of points clicked.
	//x,y values will be in pixel and relative to map image
	function Point(x,y)
	{
		this.x=x;
		this.y=y;
	}
	//Object that defines possible draw modes for the map control
	DrawMode=
	{
		POINT:0,
		LINE:1,
		POLY_LINE:2,
		POLYGON:3,
		RECTANGLE:4,
		CIRCLE:5,			
		OVAL:6,
		DRAG:7,
		ZOOMBOX:8,
		MAPTIP:9,
		EDIT:25,
		NONE:100
	};	
	MouseButton=
	{
		LEFT:0,
		RIGHT:1,
		MIDDLE:2,
		NONE:10
	};
	Key=
	{
		ALT:0,
		CONTROL:1,
		SHIFT:2,
		ENTER:3,
		NONE:10
	};
	PointType=
	{
		CIRCLE:0,
		TRIANGLE:1,
		SQUARE:2,
		STAR:3,
		CROSS:4
	};
	CursorType=
	{
		DEFAULT:'default',
		CROSSHAIR:'crosshair',
		HAND:(isIE?'hand':'pointer'),
		HELP:'help',
		MOVE:'move',
		POINTER:(isIE?'hand':'pointer'),
		PROGRESS:'progress',
		TEXT:'text',
		WAIT:'wait'		
	}

    var lineColor = '#ff0000';
    var lineWidth = 1;
    var lineStyle = 'SOLID';
    var fill = true;
    var fillColor;
    var fillType;
    var fillOpacity;
    var maxShapes = 3;
    var pointSize = 5;
    var pointColor = '#ff0000';
    var pointType = PointType.CURSOR;
    var isDrawVertice = true;
    var vertexColor ='#0000ff';

//Functions that change the graphics style

	if(window.pointType){
		pointType=eval("PointType." + pointType + ";");
	}else{
		pointType=PointType.CROSS;
	}
function DefaultTheme(lineColor,lineWidth,lineStyle,fill,fillColor,fillOpacity,fillType, pointColor, pointType)
{
	this.PointColor=pointColor;
	this.PointType=pointType;
	
	this.LineColor = lineColor;
	this.LineWidth = lineWidth;
	this.LineStyle = lineStyle;
	
	this.Fill = fill;
	this.FillColor = fillColor;
	this.FillOpacity = fillOpacity;
	this.FillType = fillType;
}

var DefaultStyle = null;

function SetFillStyle(allowFill, color, opacity, style) // allowFill=true/false, color='#FF0000' or 'Red', style='Solid', opacity=0 to 1.0
{
	if(arguments.length > 0)
		fill = allowFill;
	if(color)
		fillColor = color;
	if(opacity)		
		fillOpacity = opacity;
	if(style)
		fillType = style;
} 

function SetLineStyle(color, width, style)
{
	if(color)
		lineColor = color;
	if(width)
		lineWidth = width;
	if(style)
		lineStyle = style;
}
function SetMarkerStyle(color, markerType)
{
	if(color)
		pointColor = color;
	if(arguments.length > 1)
		SetMarkerType(markerType);
}
function SetFillColor(color)
{
	fillColor=color;
}
function SetLineColor(color)
{
	lineColor=color;
}
function SetLineWidth(width)
{
	lineWidth=width;
}
function SetMarkerType(markerType) //markerType = PointType.CIRCLE, PointType.TRIANGLE, PointType.SQUARE, PointType.STAR, PointType.CROSS
{
	var temp = -1;
	for(var i in PointType)
	{
		if(markerType==PointType[i])
		{
			temp=markerType;
			break;
		}
	}
		
	if(temp != -1)
		pointType=temp;
}
function ResetFillColor()
{
    if(DefaultStyle!=null)
	    fillColor = DefaultStyle.FillColor;
}

function ResetLineWidth()
{
    if(DefaultStyle!=null)
	    lineWidth = DefaultStyle.LineWidth;
}
function ResetLineColor()
{
    if(DefaultStyle!=null)
	    lineColor = DefaultStyle.LineColor;
}

function ResetAllStyles()
{
    if(DefaultStyle!=null)
    {
	    ResetMarkerStyle();
	    ResetLineStyle();
	    ResetFillStyle();
	    ResetNSTheme();
	}
}

function ResetFillStyle()
{
    if(DefaultStyle!=null)
    {
	    fill = DefaultStyle.Fill;
	    fillColor = DefaultStyle.FillColor;
	    fillOpacity = DefaultStyle.FillOpacity;
	    fillType = DefaultStyle.FillType;
    }	
	ResetNSTheme();	
}

function ResetLineStyle()
{
    if(DefaultStyle!=null)
    {
	    lineColor = DefaultStyle.LineColor;
	    lineWidth = DefaultStyle.LineWidth;
	    lineStyle = DefaultStyle.LineStyle;
    }	
	ResetNSTheme();	
}
function ResetMarkerStyle()
{
    if(DefaultStyle!=null)
    {
	    pointColor = DefaultStyle.PointColor;
	    pointType = DefaultStyle.PointType;
	}
}

//ResetNSTheme();

function ResetNSTheme()
{
	if(!isIE)
	{
		if(graphicsObj)
		{
			graphicsObj.setColor(lineColor);
			if(lineStyle=='dot' || lineStyle=='DOT' || lineStyle=='Dot')
				graphicsObj.setStroke(Stroke.DOTTED);
			else
				graphicsObj.setStroke(lineWidth);
		}
	}
}
//End of changing styles		
		

	//Method to set/change draw mode. Map control remains in this mode 
	//until it is changed by another call to this method
	function SetDrawMode(mode)
	{
	    
	    ResetAllStyles();
        if(mapDiv != null)
       { 
        if(shapesCol!=null){
            shapesCol.currentShape=null;
        }

		callBackMethod = null;
		callBackVertexAdd = null;
		callBackVertexMove = null; 		

		clearPreviousDrawing = true;	    	
		
		try{
		    if(arguments.length > 1)
		    {
			    callBackMethod = arguments[1];
			    if(callBackMethod != null && callBackMethod.indexOf('(')>0)
			    {
			        callBackMethod = callBackMethod.substr(0,callBackMethod.indexOf('('));
		        }
	        }
		    if(arguments.length > 2)
		    {
			    callBackVertexAdd=arguments[2];
			    if(callBackVertexAdd != null && callBackVertexAdd.indexOf('(')>0)
			    {
			        callBackVertexAdd = callBackVertexAdd.substr(0,callBackVertexAdd.indexOf('('));
			    }
	        }
		    if(arguments.length > 3)
		    {
			    callBackVertexMove=arguments[3];
			    if(callBackVertexMove != null && callBackVertexMove.indexOf('(')>0)
			    {
			        callBackVertexMove = callBackVertexMove.substr(0,callBackVertexMove.indexOf('('));			
			    }
		    }
		    if(arguments.length > 4)
			    clearPreviousDrawing = arguments[4];
	    }catch(ex){}
		
		var tempMode;
		for(var i in DrawMode)
		{
			if(mode==DrawMode[i])
			{
				tempMode=mode;
				break;
			}
		}	

//		if(tempMode!=null)
//		{
//			if(shapesCol && clearPreviousDrawing)
//			{
//                RemoveAllShapes();
//			}
//		}		
		mapDiv.onmousedown=null;
        mapDiv.onmouseover=null;
        mapDiv.onmousemove=null;
        mapDiv.onmouseout=null;
        
		if(tempMode==mode)
		{
			currentDrawMode = tempMode;
			switch(currentDrawMode)
			{
				case DrawMode.POINT:
					mapDiv.onmousedown=pointMouseDown;
					break;
				case DrawMode.LINE:
					mapDiv.onmousedown=lineMouseDown;
					break;
				case DrawMode.POLY_LINE:
					mapDiv.onmousedown=polygonMouseDown;
					break;
				case DrawMode.POLYGON:
					mapDiv.onmousedown=polygonMouseDown;
					break;
				case DrawMode.CIRCLE:
					mapDiv.onmousedown=circleMouseDown;
					break;
				case DrawMode.RECTANGLE:
					mapDiv.onmousedown=rectangleMouseDown;
					break;
				case DrawMode.OVAL:
					mapDiv.onmousedown=ovalMouseDown;
					break;
				case DrawMode.DRAG:
					mapDiv.onmousedown=dragMouseDown;
					break;
				case DrawMode.ZOOMBOX:
				    mapDiv.onmousedown=boxMouseDown;
					break;
				case DrawMode.NONE:
				    mapDiv.onmousedown=mapMouseDown;
				    break;
			   case DrawMode.MAPTIP:
					mapDiv.onmouseover=divOnMouseOver;
					mapDiv.onmousemove=divOnMouseMove;
					mapDiv.onmouseout=divOnMouseLeave;
					mapDiv.onmousedown=divOnMouseDown;
					break;
			}
		}
		mapDiv.onmouseover = function() 
			{ 
				var cursorType = GetCursor();
				mapDiv.style.cursor = cursorType;
			}
        }
	}
	
    function mapMouseDown(e)
    {
        if(isLeftMouseButton(e))
        {
            getXY(e);
            CallBack(e);
        }
    }
    
    function mapMouseMove(e)
    {
       getXY(e);
       /*
       var x=0,y=0;
       if(mapExtents)
       {
       	var x =  mapExtents.xmin + mouseX * (mapExtents.xmax - mapExtents.xmin)/mapWidth;
       	var y =  mapExtents.ymin + (mapHeight - mouseY)*(mapExtents.ymax-mapExtents.ymin)/mapHeight;
       }
       if(x!=0 && y!=0) 
       	window.status='x:' + x + ', y:' + y;   	
       */
    }

	//Default draw mode
	var currentDrawMode=DrawMode.ZOOMBOX;

	//Used to retrive top-left corner of map div tag.
	function getMapDiv(e)
	{
		divLeft = (e.pageX-e.layerX);
		divTop = (e.pageY-e.layerY);
	}

	// Get coordinates of cursor location appropriate to the browser
	function getXY(e) 
	{
		if(!e)
		{
			e = window.event;
		}
		
		if(e)
		{
			if(e.pageX)
			{
				if(divLeft==-1 && divTop==-1)
				{
					getMapDiv(e);
				}
				mouseX = e.pageX-divLeft;
				mouseY = e.pageY-divTop;
			}
			else if (e.x)
			{
			    if(divLeft==-1 && divTop==-1)
			    {
			        divLeft = e.clientX - e.x;
			        divTop = e.clientY - e.y;
			    }
			    mouseX = e.clientX - divLeft;
			    mouseY = e.clientY - divTop;
//				mouseX = e.x;// + document.body.scrollLeft;
//				mouseY = e.y;// + document.body.scrollTop;
			}
		}
	}
	
	if(isIE)
	{
	    window.onscroll  = function()
	    {
	        divLeft = -1;
	        divTop = -1;	         
	    }
	}
	
	//Some common methods
	function getObject(id)
	{
		return document.getElementById(id);		
	}
	function showObject(theObj) 
	{		
	  	if(theObj)
	  		theObj.style.visibility = "visible";
	}	
	function hideObject(theObj) 
	{		
	  	if(theObj)
			theObj.style.visibility = "hidden";
	}
	function getMouseButton(e)
	{
		if(!e)
			e = window.event;
		var btn = MouseButton.NONE;
		if(e)
		{
			if (e.button){
				if (e.button == 1)
					btn = MouseButton.LEFT;
				else if (e.button == 2)
					btn = MouseButton.RIGHT;
				else if (e.button == 4)
					btn = MouseButton.MIDLLE;
			}
			else if (e.which)
			{
				if (e.which == 1)
					btn = MouseButton.LEFT;
				else if (e.which == 2)
					btn = MouseButton.MIDDLE;
				else 
					btn = MouseButton.RIGHT;
			}
		}
		return btn;
	}
	
	function isLeftMouseButton(e)
	{
		var btn = getMouseButton(e);
		if(btn==MouseButton.LEFT)
			return true;
		else
			return false;
	}
	function isRightMouseButton(e)
	{
		var btn = getMouseButton(e);
		if(btn==MouseButton.RIGHT)
			return true;
		else
			return false;
	}
	function getKey(e)
	{
		if(!e)
			e=window.event;

		var key = Key.NONE;
		if(e.modifiers)
		{
			if(e.modifiers & Event.CONTROL_MASK)
				key = Key.CONTROL;
			else if(e.modifiers & Event.ALT_MASK)
				key = Key.ALT;
			else if(e.modifiers & Event.SHIFT_MASK)
				key = Key.SHIFT;
		}
		else
		{
			if(e.ctrlKey)
				key = Key.CONTROL;
			else if(e.altKey)
				key = Key.ALT;
			else if(e.shiftKey)
				key = Key.SHIFT;
		}
		return key;
	}
	function isCntlKey(e)
	{
		var key=getKey(e);
		if(key == Key.CONTROL)
			return true;
		else
			return false;
	}
	function isShiftKey(e)
	{
		var key=getKey(e);
		if(key == Key.SHIFT)
			return true;
		else
			return false;
	}
	function isEnterKey(e)
	{
		if(!e)
			e=window.event;		
		if(e)
			return (e.which && e.which==13) || (e.keyCode && e.keyCode==13);
	}
	function GetCursor()
	{
		var cursorType = CursorType.DEFAULT;
		switch(currentDrawMode)
		{
			case DrawMode.POINT:
			case DrawMode.LINE:
			case DrawMode.POLY_LINE:
			case DrawMode.POLYGON:
			case DrawMode.CIRCLE:
			case DrawMode.RECTANGLE:
			case DrawMode.OVAL:
			{
				cursorType=CursorType.CROSSHAIR;
				break;
			}
			case DrawMode.DRAG:
			{
				cursorType=CursorType.HAND;
				break;
			}
			case DrawMode.ZOOMBOX:
			{
			    if(isIE)
			    {
				    if(window.m_lastActiveToolBar)
				    {
					    if(m_lastActiveToolBar.GetSelectedTool())
					    {
						    var tool = m_lastActiveToolBar.GetSelectedTool().ToolName;				
    						
						    if(tool == 'ZoomIn')
						    {
						        cursorType = "url(" + document.getElementById('zoom_in_cur').value + ")";
						    }
						    else if(tool == 'ZoomOut')
						    {
						        cursorType = "url(" + document.getElementById('zoom_out_cur').value + ")";
						    }
					    }
				    }
				}
				else
				{
				    cursorType=CursorType.CROSSHAIR;
				}
				break;
			}
		}
		return cursorType;		
	}
//Begin of graphics functions

	//Generic VML methods for IE
	function getStroke()
	{
		if(isIE)
			return "<v:stroke color='" + lineColor + "' weight='" + lineWidth + "' dashstyle='" + lineStyle + "'/>";
		return "";
	}
	function getFill()
	{
		if(isIE)
		{
			if(fill)
				return "<v:fill on='true' type='" + fillType + "' color='" + fillColor + "' opacity='" + fillOpacity + "'/>";
			else
				return "<v:fill on='false' color='" + fillColor + "' opacity='0.0'/>";
		}
	}
	function getPoint_IE(x,y)
	{
		var size=pointSize;
		var l = x - size/2 - 1;
		var t = y - size/2 - 1;
		var temp="<v:shape style='position:absolute;width:" + size + "px;height:" + size + "px;left:" + l + "px;top:" + t + "px' ";
		temp+=" fillcolor='" + pointColor + "' strokecolor='" + pointColor + "'";
		temp+=" coordsize='10 10'>";
		switch(pointType)
		{
			case PointType.CIRCLE:
				temp = "<v:oval style='width:" + size + "px; height:" + size + "px; position:absolute; top:" + t + "px; left:" + l + "px;' fillcolor='" + pointColor + "'>";
				temp +='</v:oval>';			
				break;
			case PointType.TRIANGLE:
				temp+="<v:path v='m 5,0 l 9,10 1,10 x e'/></v:shape>";
				break;
			case PointType.STAR:
				temp+="<v:path v='m 5,0 l 4,3 0,3 3,6 2,9 5,7 8,9 7,6 10,3 6,3 x e'/></v:shape>";
				break;
			case PointType.CROSS:
				temp+="<v:path v='m 6,0 l 6,12 m 0,6 l 12,6 e'/></v:shape>";
				break;
			case PointType.SQUARE:
				temp+="<v:path v='m 0,0 l 10,0 10,10 0,10 x e'/></v:shape>";
				break;
		}
		return temp;
	}
	//End of VML methods
	
	//Non IE  draw method
	function drawShape(points,shapeType)
	{
		 var temp;
	    if(!sessionExpired)
	    {
		    var xPoints=new Array();
		    var yPoints=new Array();
		    var x1,y1,x2,y2;
		    var includeMouse=true;

		    if(arguments.length>3)
		    {
			    x1=arguments[2];
			    y1=arguments[3];
			    x2=arguments[4];
			    y2=arguments[5];
		    }
		    else
		    {
			    if(arguments.length==3)
				    includeMouse=arguments[2];
			    for(i=0;i<points.length;i++)
			    {
				    xPoints.push(points[i].x);
				    yPoints.push(points[i].y);
			    }
			    if(includeMouse)
			    {
				    xPoints.push(mouseX);
				    yPoints.push(mouseY);
			    }
		    }
    //		if(clearPreviousDrawing || currentDrawMode==DrawMode.EDIT || currentDrawMode==DrawMode.NONE)
    //		{
    //		    graphicsObj.clear();
    //		}    
		    graphicsObj.setColor(lineColor);
		    graphicsObj.setStroke(lineWidth);

		    switch(shapeType)
		    {
			    case DrawMode.LINE:
				    graphicsObj.drawLine(x1,y1,x2,y2);
				    break;
			    case DrawMode.POLY_LINE:
				    graphicsObj.drawPolyLine(xPoints,yPoints);
				    break;
			    case DrawMode.POLYGON:
				    graphicsObj.drawPolygon(xPoints,yPoints);			
				    break;
			    case DrawMode.POINT:
			    case DrawMode.CIRCLE:
				    graphicsObj.drawEllipse(x1,y1,x2,y2);
				    break;
			    case DrawMode.ELLIPSE:
				    graphicsObj.drawEllipse(x1,y1,x2,y2);
				    break;
			    case DrawMode.RECTANGLE:
				    graphicsObj.drawRect(x1,y1,x2,y2);
				    break;
		    }
		    graphicsObj.paint();		
		    temp=canvasDiv.innerHTML;
		    graphicsObj.clear();	
		}
		else
		{
		    HandleSessionExpired();
		}    	
		return temp;
	}
	
	//Drawing, editing vertices
	function drawVertice(x,y, index, shapeId, withEvents)
	{
		var temp;
		if(!sessionExpired)
		{
		    var w = Math.round(lineWidth/2);
		    if(w==0)w=1;
		    var s = w*2; //Size of vertex rectangle
    		
		    if(isIE) //Draw as vml
		    {
		        var cursorType = '';
			    temp = "<v:rect ";
			    if(withEvents)
			    {
			        cursorType = "cursor:" + CursorType.MOVE +  ";";
				    temp += "onmouseover='this.fillcolor=&quot;green&quot;;this.strokecolor=&quot;green&quot;;this.style.height=" + s*2 + ";this.style.width=" + s*2 + ";' ";
				    temp += "onmouseout='this.fillcolor=&quot;red&quot;;this.strokecolor=&quot;red&quot;;this.style.height=" + s + ";this.style.width=" + s + ";' "
				    temp += "onmousedown='vertexMouseDown(this," + shapeId + "," + index + ");' ";
				    temp += "ondblclick='polygonDblClick();' ";
			    }
			    temp += "style='position:absolute;" + cursorType + "width:" + s + "px;height:" + s + "px;left:" + (x-w) + "px;top:" + (y-w) + "px;' fillcolor='" + vertexColor + "' strokecolor='" + vertexColor + "'/>";
		    }
		    else //Draw a div object
		    {
			    temp ="<div id='vert" + index + "' ";
			    temp += "style='background-color: " + vertexColor + ";position:absolute;" + cursorType +  "width:" + (s+1) + "px;height:" + (s+1) + "px;left:" + (x-w) + "px;top:" + (y-w) + "px;' ";
			    if(withEvents)
			    {
				    temp += " onmouseover='this.style.backgroundColor=&quot;green&quot;;this.style.height=&quot;" + (s+5) + "px&quot;;this.style.width=&quot;" + (s+5) + "px&quot;;' ";
				    temp += " onmouseout='this.style.backgroundColor=&quot;" + vertexColor + "&quot;;this.style.width=&quot;" + (s+1) + "px&quot;;this.style.height=&quot;" + (s+1) + "px&quot;;' ";
				    temp += " onmousedown='vertexMouseDown(this," + shapeId + "," + index + ", event);'";			
			    }
			    temp += "></div>";
		    }
		}
		else
		{
		    HandleSessionExpired();
		}
		return temp;
	}	
	
	
	var vertexStartLeft,vertexStartTop, vx1, vy1;
	var vertex, editShape, vmlObj, vertexIndex;
	var drawModeBeforeVertexMove;
	var vertexSize;
	
	function vertexMouseDown(ver, shapeId, vertIndex, event)
	{
		if(isLeftMouseButton(event))
		{
			editShape = shapesCol.GetShapeById(shapeId);
			if(editShape.type==DrawMode.POLYGON || editShape.type==DrawMode.POLY_LINE || editShape.type==DrawMode.LINE)
			{			
				if(isIE)
				{
					vmlObj = document.getElementById(('vml' + shapeId));
				}
				else
				{
					if(divLeft==-1 && divTop==-1)
					{
						if(editShape.points.length>0)
						{
							divLeft = event.pageX - editShape.points[vertIndex].x;
							divTop  = event.pageY - editShape.points[vertIndex].y;
						}
						else
						{
							divLeft = event.pageX - (vertIndex==0)?editShape.xmin:editShape.xmax;
							divTop  = event.pageY - (vertIndex==0)?editShape.ymin:editShape.ymax;
						}
					}
					drawModeBeforeVertexMove = currentDrawMode;
					currentDrawMode = DrawMode.EDIT;
				}
				if(editShape && ver)
				{
					getXY(event);									
					vertex = ver;
					vertexIndex = vertIndex;
					vertexStartLeft = parseInt(vertex.style.left);
					vertexStartTop = parseInt(vertex.style.top);
					vertexSize=parseInt(vertex.style.width)/4;
					vx1 = mouseX;
					vy1 = mouseY;
						
					mapDiv.onmousemove = vertexMouseMove;
					document.onmouseup= vertexMouseUp;
					
					if(isIE)
						window.event.cancelBubble=true;	
					else if(event && event.stopPropagation)
						event.stopPropagation(); //For Firefox
				}
			}
		}
		return false;
	}
	function vertexMouseMove(e)
	{
		if(vertex && editShape)
		{
			getXY(e);
			vertex.style.left = mouseX  + 'px';
			vertex.style.top =  mouseY  + 'px';
			
			editShape.movePoint(mouseX, mouseY, vertexIndex);
			if(isIE)		
			{
				if(editShape.points.length>0){
					var temp='';
					for(i=0;i<editShape.points.length;i++)
						temp+=editShape.points[i].x + 'px,' + editShape.points[i].y + "px ";
				
					if(editShape.type==DrawMode.POLYGON)
						temp+=editShape.points[0].x + 'px,' + editShape.points[0].y + "px ";		
					vmlObj.points.value=temp;
				}
				else{
					vmlObj.from=editShape.xmin + 'px,' + editShape.ymin + 'px';
					vmlObj.to=editShape.xmax + 'px,' + editShape.ymax + 'px';
				}
			}
			else
			{
				editShape.Close();
				shapesCol.Refresh();
			}
		}
		return false;
	}
	function vertexMouseUp(e)
	{
		getXY();
		if(vx1==mouseX && vy1==mouseY)			//User has just clicked on the vertex. Excutes if there are any callback methods		
		{
		    if(currentDrawMode == DrawMode.NONE)
			    CallBack(e);
		}
        else
        {
		     if(vertex)
		    {
			    vertex.style.left = (mouseX-vertexSize)  + 'px';
			    vertex.style.top =  (mouseY-vertexSize)  + 'px';
    	
			    callBackOnVertexMove(editShape, vertexIndex);
		    }
		}
		
		document.onmousemove = null;
		document.onmouseup= null;
		editShape = null;
		vertex = null;
		vmlObj = null;		
		
		if(!isIE)
		{
			currentDrawMode = drawModeBeforeVertexMove;
		}
		vx1 = -1;
		vy1 = -1;
	}
/////////////////////////	
	//Line segment related functions
	function lineMouseDown(e)
	{
		if(isLeftMouseButton(e)){
			createShape(e);
			getXY(e);
			if(shapesCol.currentShape.xmin==-1 && shapesCol.currentShape.ymin==-1)
			{
				shapesCol.currentShape.xmin=mouseX;
				shapesCol.currentShape.ymin=mouseY;				
				mapDiv.onmousemove=lineMouseMove;				
			}
			else
			{
		        shapesCol.currentShape.xmax=mouseX;
		        shapesCol.currentShape.ymax=mouseY;				
                shapesCol.Refresh();				
				if(checkShape(e))
				{
				    mapDiv.onmousemove=null;
				}
			}	
		}
	}
	function lineMouseMove(e)
	{
		getXY(e);
		shapesCol.Refresh();								
	}	
	function getLine_IE(x1,y1,x2,y2,width,color,shapeId)
	{
		var temp='';
		var id='', w='', c='';

		if(width)
			w="strokeweight='" + width + "px'";
		
		if(color)
			c="strokecolor='" + color + "'"; 
		
		if(shapeId)
			id="id='vml" +  shapeId + "'";
		
		if(width || color)
			temp = "<v:line " + id + "  style='position:absolute;left:0px;top:0px;' from='" + x1 + "px," + y1 + "px' to='" + x2 + "px," + y2 + "px' " + w + " " + c + "></v:line>\n";			
		else
			temp = "<v:line " + id + " from='" + x1 + "," + y1 + "' to='" + x2 + "," + y2 + "' style='position:absolute;left:0px;top:0px;'>" + getStroke() + "</v:line>";
		return temp;
	}
	function getLine(x1,y1,x2,y2,shapeId, includeMouse, allowVertexMove)
	{
		var temp='';
        if(includeMouse)
        {
            x2=mouseX;
            y2=mouseY;
        }
		if(isIE)
			temp = getLine_IE(x1,y1,x2,y2,null,null,shapeId);
		else
			temp = drawShape(null,DrawMode.LINE,x1,y1,x2,y2)

		if(isDrawVertice)
		{
			temp+=drawVertice(x1,y1,0,shapeId, true, allowVertexMove);
			if(!includeMouse)
			{
			    temp+=drawVertice(x2,y2,1,shapeId, true, allowVertexMove);			
			}
		}
		return temp;
	}
	
	//Polygon methods
	function getPolygon_IE(points,shapeType,includeMouse, shapeId)
	{
		var temp='';
		for(var i=0;i<points.length;i++)
			temp+=points[i].x + 'px,' + points[i].y + 'px,';

		if(includeMouse)
			temp+=mouseX + 'px,' + mouseY + 'px,';
	
		if(shapeType==DrawMode.POLYGON && points.length>1)
			temp+=points[0].x + 'px,' + points[0].y + 'px';
		
		var str="<v:polyline ondblclick='polygonDblClick();' id='vml" + shapeId + "' points='" + temp + "' style='position:absolute;left:0px;top:0px;'>";
		str+=getStroke();
		
		if(shapeType==DrawMode.POLYGON)
			str+=getFill();
		else
			str+="<v:fill on='false' opacity='0.0'/>";
		str+="</v:polyline>";
		return str;
	}

	function getPolygon(points,shapeType, includeMouse, shapeId, allowVertexMove)
	{
		var temp='';
		if(isIE)
			temp = getPolygon_IE(points, shapeType, includeMouse, shapeId);
		else
			temp = drawShape(points,shapeType,includeMouse);	
		
		if(isDrawVertice)
		{
			for(var i=0;i<points.length;i++)
			{
				temp+=drawVertice(points[i].x,points[i].y, i, shapeId, allowVertexMove);
		    }
		}
		
		return temp;		
	}	
	
	var indexToDelete = -1;
	function polygonMouseDown(e)
	{
		if(isLeftMouseButton(e))
		{
			getXY(e);	
			if( Math.abs(mouseX-px) < 2 && Math.abs(mouseY-py) < 2)
			{
				polygonDblClick(e);
			}
			else
			{
				createShape(e);
				shapesCol.currentShape.AddPoint(new Point(mouseX,mouseY));	
				
				mapDiv.onmousemove=polygonMouseMove;	
				mapDiv.ondblclick=polygonDblClick;
				graphicsDiv.ondblclick=polygonDblClick;
				document.ondblclick=polygonDblClick;	

				px = mouseX;
				py = mouseY;
				
				callBackOnVertexAdd();			
			}
		}
		else //Right
		{
			getXY(e);	
		    if(shapesCol.currentShape!=null)
		    {
//			    document.oncontextmenu = function(){return false;}		  
                document.oncontextmenu =   DisplayContextMenu;
		    }
		}
	}
	function ContextMenuMouseOut(e)
	{
	    if(!isIE)
        {
	        var tg = (window.event) ? e.srcElement : e.target;
	        if (tg.nodeName == 'DIV') 
	        {
	            var reltg = (e.relatedTarget) ? e.relatedTarget : e.toElement;

	            while (reltg != tg && reltg.nodeName != 'BODY')
		            reltg= reltg.parentNode;
    	        
	            if (reltg != tg) 
                    contextMenuDiv.style.visibility = 'hidden';
            }
        }
	}
	function DisplayContextMenu()
	{		    	
            if(shapesCol.currentShape != null)
            {
                indexToDelete = shapesCol.currentShape.FindVertex(mouseX, mouseY);
                
                var tdDeleteVetex = getObject('tdDeleteVertex');
                var tdCompleShape = getObject('tdCompleShape');
                
                if(tdDeleteVetex!=null && tdCompleShape!=null)
                {
                    if(indexToDelete >= 0)
                    {
                        tdDeleteVetex.style.color = '';
                        tdDeleteVetex.onmouseover= function(){tdDeleteVetex.style.backgroundColor='highlight';tdDeleteVetex.style.color='white'};
                        tdDeleteVetex.onmouseout = function(){tdDeleteVetex.style.backgroundColor='';tdDeleteVetex.style.color=''};
                        tdDeleteVetex.onmousedown = DeleteVertex;
                        tdDeleteVetex.style.cursor = 'pointer';
                        
                        tdCompleShape.style.cursor = 'default';
                        tdCompleShape.style.color = 'gray';		            
                        tdCompleShape.onmouseover = '';
                        tdCompleShape.onmouseout = '';
                        tdCompleShape.onmousedown = null;
                    }
                    else
                    {
                        tdDeleteVetex.style.cursor = 'default';
                        tdDeleteVetex.style.color = 'gray';		            
                        tdDeleteVetex.onmouseover = '';
                        tdDeleteVetex.onmouseout = '';
                        tdDeleteVetex.onmousedown = null;
                        
                        tdCompleShape.style.color = '';
                        tdCompleShape.style.cursor = 'pointer';
                        tdCompleShape.onmouseover= function(){tdCompleShape.style.backgroundColor='highlight';tdCompleShape.style.color='white'};
                        tdCompleShape.onmouseout = function(){tdCompleShape.style.backgroundColor='';tdCompleShape.style.color=''};
                        tdCompleShape.onmousedown = CompleteShape;
                    }
                    
                    contextMenuDiv.style.left = (mouseX - 1) + 'px';
                    contextMenuDiv.style.top = (mouseY - 1) + 'px';   
                    
                    contextMenuDiv.style.visibility = 'visible';
                    document.oncontextmenu = '';
                }
            }
      
        return false;	
	}
	
	function DeleteVertex()
	{
        contextMenuDiv.style.visibility = 'hidden';				    
	    if(shapesCol.currentShape!=null)
		{
		    shapesCol.currentShape.deletePoint(indexToDelete, false);
		}
	}
	function CompleteShape(e)
	{
	    contextMenuDiv.style.visibility = 'hidden';		
		if(shapesCol.currentShape!=null)
		{
            shapesCol.currentShape.AddPoint(new Point(mouseX,mouseY));	
            polygonDblClick(e);		
		}
	}
	function polygonMouseMove(e)
	{
		getXY(e);		
		shapesCol.Refresh();
	}
	var px=0,py=0;	
	function polygonClick(e)
	{
		getXY(e);
	}
	function polygonDblClick(e)
	{
		if(shapesCol.currentShape!=null)
		{
			getXY(e);		
			px=0;py=0;
		
			if(checkShape(e))
			{
			    mapDiv.onmousemove=null;		
			    mapDiv.ondblclick=null;	
			    graphicsDiv.ondblclick=null;	
			    document.ondblclick=null;		
			}
		}
		
		if(isIE)
		{
			window.event.cancelBubble=true;	
		}
	}

	function createShape(e)
	{
		var btn = getMouseButton(e);
		var key = getKey(e);
		   if(!shapesCol.currentShape)
		    {
			    if(!addAsMultiPart && shapesCol.shapes.length > 0 && !isCntlKey(e))
			    {
				    if(currentDrawMode == DrawMode.POINT)
				    {
				        for(var i=0; i<shapesCol.ShapeCount(); i++)
				        {
				            if(shapesCol.GetShape(i).key != Key.CONTROL)
				            {
				                shapesCol.RemoveShape(i);
				            }
				        }
				    }
				    else
				    {
				        shapesCol.Clear();				
				    }
			    }	
    			
			    if(addAsMultiPart && (currentDrawMode == DrawMode.POLYGON || currentDrawMode == DrawMode.POLY_LINE || 
								    currentDrawMode == DrawMode.LINE || currentDrawMode == DrawMode.POINT))
			    {
				    var multiShape = shapesCol.GetLastShape();
				    if(multiShape==null || !IsMultiPartShape(multiShape))
				    {
					    multiShape=new MultiPartShape(currentDrawMode);
					    shapesCol.AddShape(multiShape);
				    }
				    shapesCol.currentShape=multiShape.GetNewShape();
			    }
			    else
			    {
				    shapesCol.currentShape = new Shape(currentDrawMode, key, btn);
				    shapesCol.AddShape(shapesCol.currentShape);
			    }
		    }		
	}
		
	//Circle functions
	function circleMouseDown(e)
	{
		if(isLeftMouseButton(e)){
			createShape(e);			
			getXY(e);			
			if(shapesCol.currentShape.xmin==-1 && shapesCol.currentShape.ymin==-1)
			{
				shapesCol.currentShape.xmin=mouseX;
				shapesCol.currentShape.ymin=mouseY;
				mapDiv.onmousemove=cicleMouseMove;
			}
			else
			{
				shapesCol.currentShape.xmax=mouseX;
				shapesCol.currentShape.ymax=mouseY;
				if(checkShape(e))
				{
				    mapDiv.onmousemove=null;
				}
			}
		}
	}
	function cicleMouseMove(e)
	{
		getXY(e);		
		var x1=shapesCol.currentShape.xmin;
		var y1=shapesCol.currentShape.ymin;
		var r=Math.sqrt((mouseX-x1)*(mouseX-x1) + (mouseY-y1)*(mouseY-y1));		
		shapesCol.currentShape.radius=r;
		shapesCol.Refresh();
	}
	function getCircle(xmin,ymin,r)
	{
		if(isIE)
			return getEllipse_IE(xmin-r,ymin-r,r*2,r*2,true,true,xmin,ymin,mouseX,mouseY);
		else
			return drawShape(null,DrawMode.CIRCLE,xmin-r,ymin-r,r*2,r*2);
	}

	function getEllipse_IE(x,y,width,height,radius,center,xmin,ymin,xmax,ymax)
	{
		var temp='';
		temp += "<v:oval style='width:" + width + "px; height:" + height + "px; position:absolute; top:" + y + "px; left:" + x + "px;'>";
		temp +=getStroke();
		temp +=getFill();
		temp +='</v:oval>';
		if(radius)
			temp += getLine_IE(xmin,ymin,xmax,ymax,1,'black');
		if(center)
		{
			temp += getLine_IE(xmin - 4,ymin,xmin + 4,ymin);
			temp += getLine_IE(xmin,ymin-4,xmin,ymin+4);
		}
		return temp;
	}
	
	//Oval related functions
	function ovalMouseDown(e)
	{
		if(isLeftMouseButton(e)){
			createShape(e);			
			getXY(e);			
			if(shapesCol.currentShape.xmin==-1 && shapesCol.currentShape.ymin==-1)
			{
				shapesCol.currentShape.xmin=mouseX;
				shapesCol.currentShape.ymin=mouseY;
				mapDiv.onmousemove=ovalMouseMove;
			}
			else
			{
				shapesCol.currentShape.xmax=mouseX;
				shapesCol.currentShape.ymax=mouseY;
				shapesCol.currentShape.Close();
				shapesCol.currentShape=null;			
				shapesCol.Refresh();	
				mapDiv.onmousemove=null;
				CallBack(e);				
			}
		}
	}
	function ovalMouseMove(e)
	{
		getXY(e);		
		var x1=shapesCol.currentShape.xmin;
		var y1=shapesCol.currentShape.ymin;
		var w=Math.abs(mouseX-x1);
		var h=Math.abs(mouseY-y1);		
		shapesCol.currentShape.width=w;
		shapesCol.currentShape.height=h;
		shapesCol.Refresh();
	}	
	function drawOval(x1,y1,w,h)
	{
		if(isIE)
			return getEllipse_IE(x1-w,y1-h,w*2,h*2,false,true,x1,y1,mouseX,mouseY);
		else
			return drawShape(null, DrawMode.ELLIPSE,x1-w,y1-h,w*2,h*2);			
	}
	//Drag related functions
	function dragMouseDown(e)
	{
		if(isLeftMouseButton(e)){
			getXY(e);
			xmin = mouseX;
			ymin = mouseY;
			xmax = mouseX;
			ymax = mouseY;
			document.onmousemove=dragMouseMove;
			mapDiv.onmouseup=dragMouseUp;			
			document.onmouseup=dragMouseUp;
						
			if(m_fadeEffects)
			{
				mapDiv.style.filter="progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)";
				mapDiv.filters[0].Apply();
			}				
		}
	}
	function dragMouseMove(e)
	{
			getXY(e);
			mapDiv.style.left=(parseInt(mapDiv.style.left) + mouseX - xmax) + 'px';
			mapDiv.style.top=(parseInt(mapDiv.style.top) + mouseY- ymax) + 'px';
			xmax =mouseX;
			ymax= mouseY;
			if(isIE)
				panClipMap_IE();
			else
				panClipMap();
	}
	function dragMouseUp(e)
	{
			mapDiv.onmousemove=null;
			mapDiv.onmouseup=null;	
			document.onmousemove=null;
			document.onmouseup=null;						
			CallBack(e);
	}
	function panClipMap_IE()
	{
		var l='auto',r='auto',t='auto',b='auto';

		if(xmax>xmin)
			r=mapWidth-(xmax-xmin);
		else
			l=xmin-xmax;
		
		if(ymax>ymin)
			b=parseInt(mapDiv.style.height) - (ymax-ymin);
		else
			t=ymin-ymax;
		mapDiv.style.clip='rect(' + t + ' ' +  r + ' ' + b + ' ' + l +')';
	}
	function panClipMap()
	{
		var l='0px',r=mapDiv.style.width,t='0px',b=mapDiv.style.height;

		if(xmax>xmin)
			r=(mapWidth-(xmax-xmin)) + 'px';
		else
			l=(xmin-xmax) + 'px';
		
		if(ymax>ymin)
			b=(parseInt(mapDiv.style.height) - (ymax-ymin)) + 'px';
		else
			t=(ymin-ymax) + 'px';
		mapDiv.style.clip='rect(' + t + ' ' +  r + ' ' + b + ' ' + l +')';
	}	
	//Point methods
	function pointMouseDown(e)
	{
		if(isLeftMouseButton(e)){
			getXY(e);
			createShape(e);	
			shapesCol.currentShape.xmin = mouseX;
			shapesCol.currentShape.ymin = mouseY;
			checkShape(e);
 		}
	}
	
	function getPoint(x,y)
	{
		if(isIE)
			return getPoint_IE(x,y);
		else
			return drawShape(null, DrawMode.CIRCLE,x-pointSize/2,y-pointSize/2,pointSize,pointSize);			
	}
	
	//Rectangle related functions
	function rectangleMouseDown(e)
	{
		if(isLeftMouseButton(e))
		{
			getXY(e);
			createShape(e);			
			if(shapesCol.currentShape.xmin==-1 && shapesCol.currentShape.ymin==-1)
			{			
			    shapesCol.currentShape.xmin = mouseX;
			    shapesCol.currentShape.ymin = mouseY;
			    mapDiv.onmousemove=rectangleMouseMove;
//    			mapDiv.onmouseup=rectangleMouseUp;
            }
            else
            {
		        mapDiv.onmousemove=null;
		                    
		        shapesCol.currentShape.xmax = mouseX;
		        shapesCol.currentShape.ymax = mouseY;		

		        checkShape(e);
            }
		}
	}
	function rectangleMouseMove(e)
	{
		getXY(e);
		shapesCol.currentShape.xmax = mouseX;
		shapesCol.currentShape.ymax = mouseY;		
		shapesCol.Refresh();			
	}

	function getRectangle(xmin,ymin,xmax,ymax)
	{
		var w=Math.abs(xmax-xmin);
		var h=Math.abs(ymax-ymin);
		var l=xmin,t=ymin;
		if(xmax<xmin)
			l=xmax;
		if(ymax<ymin)
			t=ymax;

		if(isIE){
			var temp="<v:rect style='position:absolute;left:" + l + "px;top:" + t + "px;width:" + w + "px;height:" + h + "px;'>";
			temp +=getStroke();
			temp +=getFill();
			temp +='</v:rect>';		
			return temp;				
		}else{
			return drawShape(null,DrawMode.RECTANGLE,l,t,w,h);
		}
	}
	
	//Box related functions
	var boxBorderWidth=0;
	function boxMouseDown(e)
	{
		if(isLeftMouseButton(e)){
			getXY(e);
			xmin = mouseX;
			ymin = mouseY;
			xmax = mouseX;
			ymax = mouseY;	
			if(zoomBox && zoomBox.style.borderWidth)
				boxBorderWidth=parseInt(zoomBox.style.borderWidth)*2;
			clipLayer();
			mapDiv.onmousemove = boxMouseMove;
			mapDiv.onmouseup = boxMouseUp;
//			mapDiv.style.cursor = GetCursor(CursorType.CROSSHAIR);
			return false;
		}
	}	
	function clipLayer() {	

		var w = Math.abs(xmax-xmin);
		var h = Math.abs(ymax-ymin);
		var l = (xmin > xmax)? xmax : xmin;
		var t = (ymin > ymax)? ymax : ymin;

		if( w > (mapWidth - l))
			w = mapWidth-l;
		if( h > (mapHeight - t))
			h = mapHeight - t;
		
		if(!isIE){
		    if(w > boxBorderWidth)
		        w-=boxBorderWidth;
		    if(h > boxBorderWidth)
		        h-=boxBorderWidth;
	    }
		
		zoomBox.style.left = l + 'px';
		zoomBox.style.top = t + 'px';
		zoomBox.style.width = w + 'px';
		zoomBox.style.height = h + 'px';		
	}

	function boxMouseUp(e)
	{
		hideObject(zoomBox);
		mapDiv.onmousemove=null;
		mapDiv.onmouseup=null;
		var points=new Array(new Point(xmin,ymin),new Point(xmax,ymax));
		CallBack(e);
		return true;
	}
	
	function boxMouseMove(e)
	{
		getXY(e);
		xmax=mouseX;
		ymax=mouseY;
		clipLayer();
		if(Math.abs(xmax-xmin)>1 || Math.abs(ymax-ymin)>1)
			showObject(zoomBox);
	}
	//End of Rectangle functions
	
	function setMapPosition()
	{
	    hideLoading();	 
		mapDiv.style.left='0px';
		mapDiv.style.top='0px';				
		if(isIE)
			mapDiv.style.clip='rect(auto)';
		else
			mapDiv.style.clip='rect(0px,'+ mapDiv.style.width + ',' + mapDiv.style.height + ',0px)';
	}

	var mapObjects=new Array();
	function MapObject(divId, mapImageId)
	{
		this.Url = null;
		this.MapDiv = getObject(divId);
		this.MapImageId = mapImageId;
		this.SetUrl=function(url)
		{
			if(url && url.length>1)	
			{
				var theMap=getObject(this.MapImageId);
				if(theMap)
				{
				    if(theMap.src.toLowerCase()==url.toLowerCase())
				    {
				        setMapPosition();
				    }
					theMap.src=url;
					theMap.onload=setMapPosition;
					showObject(this.MapDiv);
				}
			}
			else
				hideObject(this.MapDiv);
		}
	}
	
	var mapExtents = new MapExtents();
	
	function MapExtents()
	{
		this.xmin=0;
		this.xmax=0;
		this.ymin=0;
		this.ymax=0;
		
		this.SetExtents=function(xmin,ymin,xmax,ymax)
		{
			this.xmin=xmin;
			this.xmax=xmax;
			this.ymin=ymin;
			this.ymax=ymax;
		}
		this.IsValid=function()
		{
			return !(this.xmin==0 && this.ymin==0 && this.xmax==0 && this.ymax==0);
		}
	}
	
	function GetImageCount()
	{
		return mapObjects.length;
	}
	
	function GetMapURL(ind)
	{
		if(ind >= 0 && ind < mapObjects.length)
		{
			return mapObjects[ind].Url;
		}
	}
	
	function SetMapImages(urls)
	{   
	    if(urls != null && urls.length > 0)
	    {
		    for(var i = 0; i < urls.length; i++)
		    {
			    if(i < mapObjects.length)
			    {
				    mapObjects[i].SetUrl(urls[i]);
			    }
		    }
	    }
	}
	
    function RefreshMap(xmin, ymin, xmax, ymax, isMapCoordinates )
	{	   
	    if(!sessionExpired)
		{
			var lyrStyles = _GetLyrMgrStyles();	
			
			//Remove any existing client shapes
			RemoveAllShapes();
		    if(arguments.length >= 4)
		    {
		        if(isMapCoordinates)
		            PageMethods.ZoomToEnvelope(1, mapSourceSessionKey, xmin, ymin, xmax, ymax,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);		        
		         else 
		            PageMethods.ZoomTo(1, mapSourceSessionKey, xmin, ymin, xmax, ymax,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);		     
		    }
		    else
		    { 
			    PageMethods.RefreshMaps(1, mapSourceSessionKey,lyrStyles.Regular,lyrStyles.Active,lyrStyles.Greyed,lyrStyles.Group,lyrStyles.RootLevel,HandleServerResponse);			
			    
		    } 
	    }
	    else
	    {
	        HandleSessionExpired();
	    }	
	}
	
	function showLoading()
	{
		var loadObj=getObject("LoadDiv");
		showObject(loadObj);
	}
	function hideLoading()
	{
		var loadObj=getObject("LoadDiv");
		hideObject(loadObj);
	}

//Expected XML structure from server
//	<MAP>
//		<MAPURLS>
//			<MAPURL url="http://server/image1.jpg"/>
//			<MAPURL url="http://server/image2.jpg"/>
//		</MAPURLS>
//		<SCALE value="1739056.34" zoomlevel="3"/>
//		<EXTENTS minx="" miny="" maxx="" maxy=""/>
//		<IMAGE width="600" height="420"/>
//      <PREVIOUSMAP has="true"/>
//      <NEXTMAP has="true"/>
//	</MAP>
	

	function ProcessCallBack(responseXml)
	{
		var mapNodes = parseXmlNodes(responseXml , "MAP");
		if(mapNodes)
		{
		    var mapNode;
		    if(mapNodes.length != null)
		    {
		        mapNode=mapNodes[0];
		    }
		    else
		    {
		        mapNode=mapNodes;
		    }
		    RefreshMapContents(mapNode);
		}
	}

	var currentScale;
	function RefreshMapContents(xmlDocument)
	{
		mapDiv.onmouseup = null;
		mapDiv.onmousemove = null;
		document.onmouseup = null;
		document.onmousemove = null;

		if(xmlDocument != null)
		{
		    var mapNode = xmlDocument.getElementsByTagName("MAP")[0];
		    var valid = getAttributeValue(mapNode, "valid");
		    
		    if(valid == 'True')
		    {
                document.getElementById('spanInvalidMapMessage').style.visibility = 'hidden';		    
		        
		        var containMapImages = false;
			    var urlNodeList = xmlDocument.getElementsByTagName("MAPURL");
    			
			    if(urlNodeList && urlNodeList.length>0)
			    {
				    if(m_fadeEffects && currentDrawMode!=DrawMode.DRAG)
				    {
					    mapDiv.style.filter="progid:DXImageTransform.Microsoft.Fade()";
					    mapDiv.filters[0].Apply();
				    }				
    				
				    for(i=0;i<urlNodeList.length;i++)
				    {
					    var url = getAttributeValue(urlNodeList.item(i),"url");
    					
					    if(url!=null && url.length>0)
					    {
					        containMapImages = true;
					    }   
					    mapObjects[i].SetUrl(url);										    
				    }
				    
				    hideLoading();
				    
				    if(m_fadeEffects && currentDrawMode!=DrawMode.DRAG)
				    {
					    mapDiv.filters[0].Play();
					}
			    }
                
                if(!containMapImages)
                {
                    alert("Failed to refresh maps from server");
                }
                			
			    var scaleNode=xmlDocument.getElementsByTagName("SCALE");
    			
			    if(scaleNode && scaleNode.length > 0)
			    {
				    var scale=getAttributeValue(scaleNode.item(0), "value");
				    
				    if(scale)
				    {
					    currentScale = scale;
					    setScale(scale);
				    }
			    }
			    
			    var extentNode = xmlDocument.getElementsByTagName("EXTENTS");
			    if(extentNode && extentNode.length > 0)
			    {
				    mapExtents.xmin=parseFloat(getAttributeValue(extentNode.item(0),"minx"));
				    mapExtents.ymin=parseFloat(getAttributeValue(extentNode.item(0),"miny"));
				    mapExtents.xmax=parseFloat(getAttributeValue(extentNode.item(0),"maxx"));
				    mapExtents.ymax=parseFloat(getAttributeValue(extentNode.item(0),"maxy"));
			    }
			    
			    try
			    {
				    if(MapOverViewiFrame && mapExtents)
				    {
					    if(MapOverViewiFrame.closed==null || !MapOverViewiFrame.closed)
					    {
					        MapOverViewiFrame.SetExtents(mapExtents.xmin,mapExtents.ymin,mapExtents.xmax,mapExtents.ymax);
						    MapOverViewiFrame.focus();
					    }
				    }	
			    }
			    catch(ex)
			    {
			    }
    			
		        try
		        {
		            if(m_fadeEffects && currentDrawMode == DrawMode.DRAG)
		            {
			            mapDiv.style.filter="progid:DXImageTransform.Microsoft.BasicImage(grayscale=0)";
			            mapDiv.filters[0].Apply();
		            }	
		        }
		        catch(ex)
		        {
		        }
    			
		        var tool = FindTool('PreviousMap');
		        if(tool != null)
		        {
		            var previousMapNodes = xmlDocument.getElementsByTagName("PREVIOUSMAP");
		            if(previousMapNodes != null && previousMapNodes.length > 0)
		            {
		                var available = getAttributeValue(previousMapNodes.item(0),"available");
                        (available == 'True')? tool.Enable(): tool.Disable();
    	            }
                }
   			
   			    tool = FindTool('NextMap');
   			    if(tool != null)
   			    {
		            var nextMapNodes = xmlDocument.getElementsByTagName("NEXTMAP");
		            if(nextMapNodes != null && nextMapNodes.length>0)
		            {
		               var available = getAttributeValue(nextMapNodes.item(0),"available");			        
                       (available == 'True')? tool.Enable(): tool.Disable();
		            }
                }			    		
			}	
			else
			{
                document.getElementById('spanInvalidMapMessage').style.visibility = 'visible';
            }			
		}
	}
	function setScale(scale)
	{
		if(window.mapscaleTextBox)
		{
			var theScaleBox=getObject(mapscaleTextBox);
			if(theScaleBox)
			{
				theScaleBox.value=scale;
            }
		}
	}
	
	function getAttributeValue(node,attributeName)
	{
		if(node && node.attributes)
		{
			attrNode=node.attributes.getNamedItem(attributeName);
			if(attrNode)
				return attrNode.nodeValue;
		}
	}

//Object that represents user drawn shapes like line, circle, polygon etc.
//Close method is called to cache the html required to draw the shape.
function Shape(type, key, btn)
{
	this.type=type;
	this.points=new Array();
	this.vertex=new Array();
	this.height=0;
	this.width=0;
	this.radius=0;
	this.html='';
	this.xmin=-1;
	this.ymin=-1;
	this.xmax=-1;
	this.ymax=-1;
	this.closed=false;
	this.key = key
	this.mouseButton = btn;
	this.ID = Math.round(Math.random()*10000000);
	this.errorMessage = '';
	this.allowVertexMove = true;
	
	this.AddPoint = function(point)
	{
		this.points.push(point);
	}
	this.ReplaceLastPoint = function(point)
	{
		this.points.pop();
		this.points.push(point);
	}
	this.GenerateHtml=function(includeMouse)
	{
		var temp='';
		switch(this.type)
		{
			case DrawMode.POINT:
			{
				return getPoint(this.xmin,this.ymin);
			}
			case DrawMode.LINE:
			{
				return getLine(this.xmin,this.ymin,this.xmax,this.ymax, this.ID, includeMouse, this.allowVertexMove)
			}
			case DrawMode.POLY_LINE:
			{
				return getPolygon(this.points, this.type, includeMouse, this.ID, this.allowVertexMove);
			}
			case DrawMode.POLYGON:
			{
				return getPolygon(this.points, this.type, includeMouse, this.ID, this.allowVertexMove);
			}
			case DrawMode.CIRCLE:
			{
				return getCircle(this.xmin,this.ymin,this.radius);
			}
			case DrawMode.OVAL:
			{
				return drawOval(this.xmin,this.ymin,this.width,this.height);
			}
			case DrawMode.RECTANGLE:
			{
				return getRectangle(this.xmin,this.ymin,this.xmax,this.ymax);
			}
		}
		return temp;
	}
	this.RemoveLastVertex = function()
	{
		if(this.type==DrawMode.POLY_LINE || this.type==DrawMode.POLYGON)
		{
			this.points.pop();
			if(this.closed)
				this.Close();
		}
	}
	this.GetHtml=function()
	{
		if(this.closed)
			return this.html;
		else
			return this.GenerateHtml(true);
	}
	this.Close=function()
	{
		this.closed=true;
		this.html=this.GenerateHtml(false);
	}
	this.movePoint = function(x,y,index)
	{
		if(this.type==DrawMode.POLYGON || this.type==DrawMode.POLY_LINE)
		{
			if( index >= 0 && index < this.points.length)
			{
				this.points[index].x = x;
				this.points[index].y = y;
			}
		}
		else if(this.type==DrawMode.LINE)
		{
			if(index==0)
			{
				this.xmin=x;
				this.ymin=y;
			}
			else if(index==1)
			{
				this.xmax=x;
				this.ymax=y;
			}
		}
	}
	this.insertPoint = function(x,y,index)
	{
	    var newPoint = new Point;
	    newPoint.x=x;
	    newPoint.y=y
	    this.points.splice(index,0,newPoint);
	    this.Close();
	}
	this.deletePoint = function(index, close)
	{
	    this.points.splice(index,1);
	    
	    if(close)
	        this.Close();
	}
	this.isValid = function()
	{
		var temp = false;
		this.errorMessage = '';
		switch(this.type)
		{
			case DrawMode.POINT:
				temp = (this.xmin!=-1 || this.ymin!=-1);
				this.errorMessage = 'Invalid point';
				break;
			case DrawMode.LINE:
				temp = ((this.xmin!=-1 || this.ymin!=-1) && (this.xmax!=-1 || this.ymax!=-1));
				this.errorMessage = 'Invalid start or end point for the line';
				break;
			case DrawMode.POLY_LINE:
				temp = (this.points && this.points.length>1);
				this.errorMessage = 'Invalid points for polyline. Polyline needs at least 2 points';
				break;
			case DrawMode.POLYGON:
				temp = (this.points && this.points.length>2);
				this.errorMessage = 'Invalid number of points for polygon. Polygon needs at least 3 points';
				break;
			case DrawMode.CIRCLE:
				temp = ((this.xmin!=-1 || this.ymin!=-1) && this.radius > 0);
				this.errorMessage = 'Invalid number of points for Circle.Start point needs to be diffrent from End point';
				break;
			case DrawMode.OVAL:
				temp = true; 
				break;
			case DrawMode.RECTANGLE:
				temp = ((this.xmin!=-1 || this.ymin!=-1) && (this.xmax!=-1 || this.ymax!=-1));
				this.errorMessage = 'Invalid points for rectangle';
				break;
		}
		return temp;		
	}
	this.GetPartXml=function()
	{
		var temp;
		switch(this.type)
		{
			case DrawMode.POINT:
				temp = GetPartXml(new Array(new Point(this.xmin,this.ymin)));
				break;
			case DrawMode.LINE:
				temp = GetPartXml(new Array(new Point(this.xmin,this.ymin),new Point(this.xmax,this.ymax)));
				this.errorMessage = 'Invalid start or end point for the line';
				break;
			case DrawMode.POLY_LINE:
			case DrawMode.POLYGON:
				temp = GetPartXml(this.points);
				break;
		}
		return temp;		
	}
	this.AddVertex = function(x,y)
	{
		if(this.type == DrawMode.POLYGON || this.type == DrawMode.POLY_LINE || this.type == DrawMode.LINE)
		{
		    if(this.type == DrawMode.LINE)
		    {
		        this.AddPoint(new Point(this.xmin,this.ymin));
		        this.AddPoint(new Point(this.xmax,this.ymax));
		        this.type=DrawMode.POLY_LINE;
		    }
		
			if(this.points.length >= 2)
			{
				var indexInsertPoint = 0;
				var tangetDistance = 10000;
				for(i=0; i<this.points.length; i++)
				{
					var j = (i == this.points.length-1) ? 0 : i+1;
					var x1=this.points[i].x;
					var y1=this.points[i].y;
					
					var x2=this.points[j].x;
					var y2=this.points[j].y;
					
					var midX = (x1+x2)/2;
					var midY = (y1+y2)/2;
					
					var intersects = false;

//					var temp = GetTangentDistance(x1,y1,x2,y2,x,y);
                    var temp = GetDistance(midX, midY, x,y);
                    
					if(temp<tangetDistance)
					{
						tangetDistance = temp;
						indexInsertPoint = i;
					}
				} 
				this.insertPoint(x,y,indexInsertPoint+1);
			}
		}
	}
	this.SetPoints = function(points)
	{
	    if(points){
		    if(this.type==DrawMode.POLYGON || this.type==DrawMode.POLY_LINE)
		        this.points = points;
		    else if(this.type==DrawMode.LINE && points.length==2)
		        {this.xmin=points[0].x;this.ymin=points[0].y;this.xmax=points[1].x;this.ymax=points[1].y;}
		    else if(this.type==DrawMode.POINT && points.length>0)
		        {this.xmin=points[0].x;this.ymin=points[0].y;}	
		}
	}
	this.FindVertex = function(x, y)
	{
	    //Implement only for POLY_LINE and POLYGON
	    if(this.points.length > 0)
	    {
	        for(var i=0;i<this.points.length;i++)
	        {
	            if( this.points[i].x >= x-2 && this.points[i].x <= x+2
	                && this.points[i].y >= y-2 && this.points[i].y <= y+2)
	            {
	                return i;        
	            }
	        }
	    }
	    return -1;
	}	
}

function toMapUnits(x,y)
{
  if(mapExtents)
  {
  	var x1 =  mapExtents.xmin + x * (mapExtents.xmax - mapExtents.xmin)/mapWidth;
  	var y1 =  mapExtents.ymin + (mapHeight - y)*(mapExtents.ymax-mapExtents.ymin)/mapHeight;
  	return new Point(x1,y1);	  	
  }
}

function GetTangentDistance(x1,y1,x2,y2,px,py)
{
	y1 = mapHeight - y1; //Swap Y coordinate values
	y2 = mapHeight - y2;
	py = mapHeight - py;
	
	var tangentDistance = 10000;
	var lineDistance = GetDistance(x1,y1,x2,y2);
	
	var u = (((px - x1) * (x2 - x1)) + ((py - y1) * (y2 - y1))) / (lineDistance*lineDistance);
	if(u > 0 && u < 1)
	{
		var nx = x1 + u * (x2 - x1);
		var ny = y1 + u * (y2 - y1);
		tangentDistance=GetDistance(nx,ny,px,py);
	}
	return tangentDistance;
}

function GetDistance(x1,y1,x2,y2)
{
	return Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
}

//Validates a shape and if valid, then invokes the call back. If not valid, removes the shape
function checkShape(e)
{
    var valid = false;
	if(shapesCol.currentShape.isValid())
	{
	    valid = true;
	    shapesCol.currentShape.Close();	
		shapesCol.Refresh();	
	    shapesCol.currentShape=null;							
	    
		CallBack(e);			
	}
	else
	{
		alert(shapesCol.currentShape.errorMessage);
		//RemoveLastShape();
	}	
	return valid;	
}

//Represents collection of shapes drawn. maxShapes defines maximum shapes that can be drawn at any time.
//If a new shape is drawn and the number of shapes exceeds the maximum, the first shape is removed from collection
//to accommodate the new shape.
function ShapeCollection(maxShapes)
{
	this.shapes=new Array();
	this.currentShape=null;
	this.maxsize=maxShapes;
	
	this.AddShape=function(shape)
	{
		if(shape)
		{
			if(this.shapes.length==this.maxsize )
			{
//			    if(clearPreviousDrawing)
				this.shapes.shift();
			}	
			this.shapes.push(shape);
		}
	}
	this.DeleteLastShape=function()
	{
		if(this.shapes && this.shapes.length>=1)
			this.shapes.pop();
	}
	this.Clear = function()
	{
		this.shapes=new Array();
	}
	this.ShapeCount = function()
	{
		return this.shapes.length;
	}
	this.Refresh = function()
	{
	    if(graphicsDiv!=null)
	    {
		    graphicsDiv.innerHTML='';
		    var temp='';
		    if(this.shapes)
		    {
			    var j=0;
			    for(j=0;j<this.shapes.length;j++)
				    temp+=this.shapes[j].GetHtml();
		    }
		    graphicsDiv.innerHTML=temp;		
		}
	}
	this.GetShape = function(ind)
	{
		if(ind >=0 && ind < this.shapes.length)
			return this.shapes[ind];
	}
	this.GetLastShape = function()
	{
		if( this.shapes.length > 0)
			return this.shapes[this.shapes.length-1];
		return;
	}
	this.RemoveShape = function(ind)
	{
		if(ind >=0 && ind < this.shapes.length)
			this.shapes.splice(ind,1);
	}
	this.GetShapeById = function(id)
	{
		if(this.shapes && this.shapes.length>0)
		{
			for(i=0; i<this.shapes.length;i++)
			{
				if(this.shapes[i].ID == id)
					return this.shapes[i];

				if(IsMultiPartShape(this.shapes[i]))
				{
					for(j=0;j<this.shapes[i].shapes.length;j++)
					{
						if(this.shapes[i].shapes[j].ID==id)
							return this.shapes[i].shapes[j];
					}
				}
			}
		}
	}
}

//Represents multi-part shapes. Each part is stored as a shape internally.
//This will be enhanced later for each part to have one or more holes.
function MultiPartShape(shapeType)
{
	this.shapes = new Array();
	this.type = shapeType;
	this.ID = Math.round(Math.random()*10000000);	
	
	this.AddPart = function(points)
	{
		var shape=this.GetNewShape();
		shape.SetPoints(points);
	}
	this.GetNewShape = function()
	{
		var shape = new Shape();
		shape.type = this.type;
		this.shapes.push(shape);		
		return shape;
	}
	this.GetPartCount = function()
	{
		return this.shapes.length;		
	}
	this.GetPart=function(index)
	{
		if(index >= 0 && index < this.shapes.length)
			return this.shapes[index];	
	}
	this.RemovePart=function(index)
	{
		if(index >= 0 && index < this.shapes.length)
			return this.shapes.splice(index,1);
	}
	this.GetHtml=function()
	{
		var temp='';
		if(this.shapes)
		{
		    var n=this.shapes.length;
			for(var j=0;j<n;j++)
				temp+=this.shapes[j].GetHtml();
		}
		return temp;
	}
	this.GetPartXml=function()
	{
		var temp='';
		var n=this.shapes.length;
		for(i=0;i<n;i++)
			temp+=this.shapes[i].GetPartXml();
		return temp;
	}
	this.Close=function()
	{
	    var n=this.shapes.length;
		for(i=0;i<n;i++)
			this.shapes[i].Close();
	}
	this.AddVertex = function(x,y)
	{
		if(this.shapes.length>0)
			this.shapes[0].AddVertex(x,y);
	}	
	this.FindVertex = function(x, y)
	{
	    return -1;
	}	
}

function GetShape(ind)
{
	return shapesCol.GetShape(ind);
}
function GetShapeCount()
{
	return shapesCol.ShapeCount();
}
function GetLastShape()
{
	return shapesCol.GetLastShape();
}
function AddShape(shape)
{
    shapesCol.AddShape(shape);
	shape.Close();
	shapesCol.Refresh();   	
}
function RemoveShape(ind)
{
	shapesCol.RemoveShape(ind);
	shapesCol.Refresh();   
}
function RemoveLastShape()
{
	shapesCol.DeleteLastShape();
	shapesCol.Refresh();	
}
function RemoveAllShapes()
{
	shapesCol.Clear();
	shapesCol.Refresh();	
	
	var mapControl = document.getElementsByName(mapControlId + "_geometry");
	if(mapControl && mapControl.length)
		document.getElementsByName(mapControlId + "_geometry")[0].value = null;
		
    if(removeShapesEventListeners!=null)
    {
        for(var i=0;i<removeShapesEventListeners.length;i++){
            eval(removeShapesEventListeners + '()');
        }
    }
}

function SetMaximumShapes(maxShapes)
{
	if(shapesCol && maxShapes)
	{
		shapesCol.maxsize = maxShapes;
	}
}

function IsMultiPartShape(shape)
{
	return isIE ? shape.GetNewShape != null : shape.__proto__==MultiPartShape.prototype;
}
/*
	<XML>
		<GEOMETRY>
			(m)<POLYGON>
				(m)<PART coords="">(m)<HOLE coords=""/></PART>
			</POLYGON>	
			(m)<POLYLINE>
				(m)<PART coords=""/>
			</POLYLINE>
			(m)<LINE>
				(m)<PART coords=""/>
			</LINE>
			(m)<POINT>
				(m)<PART coords=""/>			
			</POINT>
			(m)<CIRCLE center="" radius=""/>
			(m)<ELLIPSE center="" width="" height=""/>
			(m)<RECTANGLE xmin="" ymin="" xmax="" ymax=""/>
		</GEOMETRY>
	</XML>
*/
function setSubmitValues()
{
	var temp='<XML><GEOMETRY>';
	var n=shapesCol.ShapeCount();
	for(i=0; i<n; i++)
	{	
		var shp = shapesCol.GetShape(i);
		if(shp)
		{
			switch(shp.type)
			{
				case DrawMode.POINT:
					temp+='<POINT>' + shp.GetPartXml() + '</POINT>';
					break;
				case DrawMode.LINE:
					temp+='<LINE>' + shp.GetPartXml() + '</LINE>';
					break;
				case DrawMode.POLY_LINE:
					temp+='<POLYLINE>' + shp.GetPartXml() + '</POLYLINE>';
					break;
				case DrawMode.POLYGON:
					temp+='<POLYGON>' + shp.GetPartXml() + '</POLYGON>';
					break;
				case DrawMode.CIRCLE:
					temp+='<CIRCLE center="' + shp.xmin + ',' + shp.ymin + '" radius="'+ shp.radius + '"/>';
					break;
				case DrawMode.RECTANGLE:
					temp+='<RECTANGLE xmin="' + shp.xmin + '" ymin="' + shp.ymin + '" xmax="' + shp.xmax + '" ymax="' + shp.ymax + '"/>';
					break;
				case DrawMode.OVAL:
					temp+='<ELLIPSE center="' + shp.xmin + ',' + shp.ymin + '" width="' + shp.width + '" height="' + shp.height + '"/>';
					break;
			}	
		}
	}
	temp+='</GEOMETRY></XML>';
	temp=escape(temp);
	document.getElementsByName(mapControlId + "_geometry")[0].value=temp;
}

function GetPartXml(points)
{
	var temp='<PART coords="';
	if(points)
	{
	    var n=points.length;
		for(j=0; j<n; j++)
		{
			if(j>0)temp+=' ';
			temp+=points[j].x + ',' + points[j].y;					
		}
	}	
	temp+='"/>';
	return temp;
}

function setAutoPostback(value)
{
	if(value==true || value=='true' )
		autoPostBack = true;
	else
		autoPostBack = false;
}
function showSelectionTools()
{
	showObject(getObject('mapCtlSelections'));
}
function hideSelectionTools()
{
	hideObject(getObject('mapCtlSelections'));
}

function addVertex()
{
    document.forms[0].__EVENTTARGET.value="td_EDITING_VERTEX_TOOLSAddVertex"; 
    var shp = shapesCol.GetLastShape();
    shp.AddVertex(mouseX,mouseY);
    shapesCol.Refresh();
   
    return false;
}	

function numOrdA(a, b){ return (a-b); }
/*
function setClearPreviousDrawing(flag)
{
    clearPreviousDrawing=flag;
}*/
function deleteVertex()
{
    if(shapesCol)
    {
        document.forms[0].__EVENTTARGET.value="td_EDITING_VERTEX_TOOLSDeleteVertex"; 
        var shp = shapesCol.GetLastShape();
	     //validate shape with 1 deleted point
	    var validShape=true;
        switch(shp.type)
        {
            case DrawMode.POLY_LINE:
             if((shp.points.length-1)<=1)
             {
                 validShape=false;
                alert("Invalid shape");
                break;
             }
            break;                
            case DrawMode.POLYGON:
             if((shp.points.length-1)<=2)
             {
                validShape=false;
                alert("Invalid shape");
                break;
             }
             break;            
        }    
        if(validShape==true)
        {
	    if(shp && shp.points.length>=2)
	    {
	        var firstPointIndex = -1;
	      
	        var tpoints = shp.points;
	        var distance = new Array();
	        var distanceIndex = new Array();
    	    for(i=0; i<tpoints.length;i++)
    	    {
    	        var x1=tpoints[i].x;
    	        var y1=tpoints[i].y;
    	        var distancex=x1-mouseX;
    	        var distancey=y1-mouseY;
    	        var totalDis=Math.sqrt(Math.pow(distancex,2)+Math.pow(distancey,2));
    	        distance.push(totalDis);
    	        distanceIndex.push(totalDis+":"+i);
    	    }   
    	    distance.sort(numOrdA);
    	    var smallestDis=distance[0];
    	    if(smallestDis<5)
    	    {
    	        for(i=0;i<distanceIndex.length;i++)
    	        {
    	            var pos = distanceIndex[i].indexOf(":");
    	            var dis = distanceIndex[i].substring(0, pos);
    	            if(dis==smallestDis)
    	            {
    	                firstPointIndex=distanceIndex[i].substring(pos+1);
    	            }
    	            if(firstPointIndex>-1)
    	                break;
    	        }
    	        //insert the  new point in between firstPointIndex and secondPointIndex
    	        //if firstPointIndex or secondPointIndex is 0 the insert the popint at the end
    	       
    	        if(firstPointIndex>-1)
    	        {
   	                shp.deletePoint(firstPointIndex, true);
    	        }
    	        
    	        shapesCol.Refresh();
    	    }
    	}
    	}
	}
	return false;
}


function parseXmlNodes(xmlString, startNode)
{
    var xmlNodes;
    if(xmlString)
    {
    	try
    	{
    	    var xmlDoc;
    	    if(isIE)
    	    {
	            xmlDoc = new ActiveXObject("Msxml2.DOMDocument.3.0");
	            xmlDoc.async = false;
	            xmlDoc.resolveExternals = false;
	            xmlDoc.loadXML(xmlString);
	        }
	        else
	        {
                var domParser = new DOMParser();
                var xmlDoc = domParser.parseFromString(xmlString, "text/xml");
	        }
	        if(startNode)
	            xmlNodes = xmlDoc.getElementsByTagName(startNode);
	        else
	            xmlnodes=xmlDoc;
	    }
	    catch(ex){}        
    }
    return xmlNodes;
}

function DrawClientShapes()
{
    var geometryNodes = parseXmlNodes(geometryXml, "GEOMETRY");
    DrawShapesFromXml(geometryNodes);
    setSubmitValues();
}

/* XML is parsed as
	<XML>
		<GEOMETRY>
			<SHAPE type="POLYGON|POLY_LINE|LINE|POINT">
				(m)<PART coords="">(m)<HOLE coords=""/></PART>
			</SHAPE>	
		</GEOMETRY>
	</XML>
*/
function DrawShapesFromXml(geometryNodes)
{
      
      if (geometryNodes != null && geometryNodes.length > 0)
      {
         var shapeNodes = geometryNodes.item(0).getElementsByTagName("SHAPE");
         if(shapeNodes)
         {
             for(i=0;i<shapeNodes.length;i++)
             {
             	var shapeType=shapeNodes.item(i).getAttribute("type");
     		    var partNodes=shapeNodes.item(i).getElementsByTagName("PART");     		 
                var type;  
			    switch(shapeType)
			    {
			         case "POINT":
			              type=DrawMode.POINT;
			              break;
			         case "LINE":
			     	    type=DrawMode.LINE;	   
			     	    break;
			         case "POLYLINE":
			             type=DrawMode.POLY_LINE;	   
			             break;
			         case "POLYGON":
			             type=DrawMode.POLYGON;
			             break;
			     } 

     		     var shape;                  	     		 
     		     var n=partNodes.length;
     		     if(n>1) //Create multi-part shape
     		     {
     		 	    shape= new MultiPartShape(type);
     		 	    for(j=0; j<n;j++)
     		 	    {
                      	    var value=partNodes.item(j).getAttribute("coords");        
	                 	    shape.AddPart(GetPoints(value));
     		 	    }
     		     }
     		     else if(n==1) 
     		     {
                 	    shape = new Shape(type);      
                 	    var value=partNodes.item(0).getAttribute("coords");          		 	
                 	    shape.SetPoints(GetPoints(value));    		 	
     		     }
                if(shape)
                	AddShape(shape);         
              }
          }
      }	
}

function GetPoints(value)
{
      var points=new Array();                  	           		 	
	  if(value)
	  {
	       var pts = eval("new Array(" + value + ")");
	       var n=pts.length;
	       for(i=0;i<n;i=i+2)
	            points.push(new Point(parseInt(pts[i]),parseInt(pts[i+1])));
	  }	
	  return points;
}

function submitScale(e)
{
    //if(isEnterKey(e))
    //{
    //    var scaleBox = document.getElementById(mapscaleTextBox);
    //    if(scaleBox)
    //    {
    //        doZoomToScale(scaleBox.value);        
    //    }
        
    //}
}
function getExtents()
{
	if(mapExtents!=null)
	{
		return mapExtents.xmin + "," + mapExtents.ymin + "," + mapExtents.xmax + "," + mapExtents.ymax;
	}
}

function PostSelections()
{
    if(window.autoPostBack)
    {
        document.forms[0].__EVENTTARGET.value = "tb_SELECTION_TOOLS_APPLY";
        document.forms[0].__EVENTARGUMENT.value = "ApplySelection";
    }
}

//m_lyrNodeStyle, etc. are defined in LyrMgr.js.
//If LyrMgr.js is not included in a page, then accessing those variable causes exceptions (like in AdminTool/embeddable map, etc.)
//This function returns a structure of layer manager styles if available, else blank values.
function _GetLyrMgrStyles()
{
 var lyrCSS = "";
 try{lyrCSS = m_lyrNodeStyle;}catch(e){};
 
 var activeCSS = "";
 try{activeCSS = m_activeNodeStyle;}catch(e){};
 
 var greyedCSS = "" 
 try{greyedCSS = m_greyedNodeStyle;}catch(e){};
 
 var groupCSS = "";
 try{groupCSS = m_groupNodeStyle;}catch(e){};
 
 var mapCss = ""; 
 try{mapCss = m_mapNodeStyle;}catch(e){};
 
 return {Regular:lyrCSS,Active:activeCSS,Greyed:greyedCSS,Group:groupCSS,RootLevel:mapCss}; 
}