
//Get the Browser
var isNav, isIE, isNav6
if (parseInt(navigator.appVersion) >= 4) 
{
	if (navigator.appName == "Netscape") 
	{
		if (parseInt(navigator.appVersion) >= 5)
		{
			isNav6 = true;
		}
		else
		{
			isNav = true;
		}
	} 
	else 
	{
		isIE = true;
	}
}

//////////////////////////////////////////////////////////////////////////////////////
////////////////////////////// Object IdentifyObject /////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
	
function IdentifiedLayer()
{
	this.LayerName = "";
	this.Recordset = new RecordsetObject();
}

//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// Object Map //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////

function MapLib()
{
	//Properties
	this.Width = 700;
	this.Height = 450;
	this.FullscreenWidth = -1;
	this.FullscreenHeight = -1;
	this.DivMapFrame = document.getElementById("mapframe");
	this.DivMap = document.getElementById("map");
	this.DivMapCanvas = document.getElementById("mapcanvas");
	this.DivMapImage = document.getElementById("mapimage");
	this.DivMapTransImage = document.getElementById("maptransimage");
	this.DivMapLoading = document.getElementById("maploading");
	this.DivFileReady = document.getElementById("mapfileready");
	this.DivSelectLayout = document.getElementById("mapSelectLayout");
	this.Extent = new Envelope();
	this.SelectExtent = new Envelope();
	this.FullExtent = new Envelope();
	this.ViewHistory = new Array();
	this.ViewHistoryImages = new Array();
	this.HistoryIndex = -1;
	this.ZoomToHistory = false;
	this.Layers = new Array();
	this.StartX = -1;
	this.StartY = -1;
	this.StartScreenX = -1;
	this.StartScreenY = -1;
	this.MouseX = -1;
	this.MouseY = -1;
	this.MouseScreenX = -1;
	this.MouseScreenY = -1;
	this.EndX = -1;
	this.EndY = -1;
	this.EndScreenX = -1;
	this.EndScreenY = -1;
	this.Action = "ZoomIn";
	this.Drawing = false;
	this.MouseDown = false;
	this.LoadImage = false;
	this.LoadFullscreenImage = false;
	this.LoadOverviewImage = false;
	this.LoadZoomToImage = false;
	this.LoadRecordset = false;
	this.LoadIdentify = false;
	this.LoadSingleIdentify = false;
	this.ZoomToLayerID = "";
	this.ZoomToFieldName = "";
	this.ZoomToFieldValue = "";
	this.AttributeQueryID = "";
	this.AttributeQueryArcIMSLayerID = "";
	this.AttributeQueryWhereClause = "";
	this.AttributeQueryUseView = false;
	this.ArcIMSInitialized = false;
	this.Scale = 0;
	this.IdentifyPoint;
	this.IdentifyResults = null; //Array of IdentifyObject
	this.ImageURL = "";
	this.LegendURL = "";
	
	//Methods
	this.ZoomIn = function()
	{
		this.Action = "ZoomIn";
		this.UpdateMouseCursor();
	}
	
	this.ZoomOut = function()
	{
		this.Action = "ZoomOut";
		this.UpdateMouseCursor();
	}

	this.ZoomExtent = function()
	{
        ServerProcess.AddCommand("CallMethod(Map,SetMapSize," + this.Height + "|" + this.Width + ");");		    
        ServerProcess.AddCommand("CallMethod(Map,SetVisibleLayers," + this.VisibleLayers() + ");");		    
        ServerProcess.AddCommand("CallMethod(Map,SetEnabledLayers," + this.EnabledLayers() + ");");		    
        ServerProcess.AddCommand("CallMethod(Map,SetDisabledLayers," + this.DisabledLayers() + ");");
		ServerProcess.AddCommand("CallMethod(Map,GetImage,null);");
		ServerProcess.Execute();
	}
	
	this.Pan = function mapPan()
	{
		this.Action = "Pan";
		this.UpdateMouseCursor();
	}
	
	this.Identify = function()
	{
		this.Action = "Identify";
		this.UpdateMouseCursor();
	}
	
	this.Select = function()
	{
		this.Action = "Select";
		this.UpdateMouseCursor();
	}
	
	this.ZoomToHistoryIndex = function(thisIndex)
	{
		if ((thisIndex >= 0) && (thisIndex < (this.ViewHistory.length)))  
		{
		    this.HistoryIndex = thisIndex;
			this.LoadImage = true;
			this.Extent.MinX = this.ViewHistory[this.HistoryIndex].MinX;
			this.Extent.MinY = this.ViewHistory[this.HistoryIndex].MinY;
			this.Extent.MaxX = this.ViewHistory[this.HistoryIndex].MaxX;
			this.Extent.MaxY = this.ViewHistory[this.HistoryIndex].MaxY;
			this.FlashMapImage(this.ViewHistoryImages[this.HistoryIndex]);
			this.ZoomToHistory = true;
			this.Refresh();
		}
	}
	
	this.ZoomPrevious = function()
	{
	    this.ZoomToHistoryIndex(this.HistoryIndex-1);

	}
	
	this.ZoomNext = function()
	{
	    this.ZoomToHistoryIndex(this.HistoryIndex+1);
	}
	
	this.AddMapCommands = function()
	{
        ServerProcess.AddCommand("CallMethod(Map,SetMapSize," + this.Height + "|" + this.Width + ");");		    
        ServerProcess.AddCommand("CallMethod(Map,SetExtent," + this.Extent.MinX + "|" + this.Extent.MinY + "|" + this.Extent.MaxX + "|" + this.Extent.MaxY + ");");		    
        ServerProcess.AddCommand("CallMethod(Map,SetVisibleLayers," + this.VisibleLayers() + ");");		    
        ServerProcess.AddCommand("CallMethod(Map,SetEnabledLayers," + this.EnabledLayers() + ");");		    
        ServerProcess.AddCommand("CallMethod(Map,SetDisabledLayers," + this.DisabledLayers() + ");");		    
	}
	
	this.ViewedLayers = function()
	{
		var l = "";
		for (var i=0;i<this.Layers.length;i++)
		{
			if ((this.Layers[i].Visible) && (this.Layers[i].Enabled))
			{
				if (l.length > 0) l += "!";
				l += this.Layers[i].ArcIMSLayerID;
			}
		}
		return l;
	}

	this.VisibleLayers = function()
	{
		var l = "";
		for (var i=0;i<this.Layers.length;i++)
		{
			//if ((this.Layers[i].Visible) && (this.Layers[i].Enabled))
			if (this.Layers[i].Visible)
			{
				if (l.length > 0) l += "!";
				l += this.Layers[i].ArcIMSLayerID;
			}
		}
		return l;
	}
	
	this.HiddenLayers = function()
	{
		var l = "";
		for (var i=0;i<this.Layers.length;i++)
		{
			if ((!this.Layers[i].Visible) || (!this.Layers[i].Enabled))
			{
				if (l.length > 0) l += "!";
				l += this.Layers[i].ArcIMSLayerID;
			}
		}
		return l;
	}

	this.EnabledLayers = function()
	{
		var l = "";
		for (var i=0;i<this.Layers.length;i++)
		{
			if (this.Layers[i].Enabled)
			{
				if (l.length > 0)l += "!";
				l += this.Layers[i].ArcIMSLayerID;
			}
		}
		return l;
	}
	
	this.DisabledLayers = function()
	{
		var l = "";
		for (var i=0;i<this.Layers.length;i++)
		{
			if (!this.Layers[i].Enabled)
			{
				if (l.length > 0) l += "!";
				l +=  this.Layers[i].ArcIMSLayerID;
			}
		}
		return l;
	}
	
	this.Refresh = function()
	{

		//TEMPORARY -PLEASE REMOVE
		if (this.LoadRecordset) 
		{
			this.LoadImage = false;
			this.LoadOverviewImage = false;
			this.LoadIdentify = false;
			this.LoadSingleIdentify = false;
		}
		//TEMPORARY -PLEASE REMOVE

		//Make the call for a new map image and/or data
		myDivLib.SetCursor(this.DivMapFrame,'wait');
		
		this.DivMapLoading.style.display="block";
		
		if (!this.ArcIMSInitialized)
		{
            ServerProcess.AddCommand("CallMethod(Map,SetMapSize," + this.Height + "|" + this.Width + ");");		    
		    ServerProcess.AddCommand("CallMethod(Map,Init,null);");
		    ServerProcess.AddCommand("CallMethod(Map,GetImage,null);");
		}
		
		if (this.LoadImage)
		{
		    this.AddMapCommands();
		    ServerProcess.AddCommand("CallMethod(Map,GetImage,null);");		    
		}
		
		ServerProcess.Execute();
	}
	
	this.OnMapLoaded = function()
	{
	    LayerList.Draw();
	}
	
	this.Refreshed = function()
	{
		this.LoadImage = false;
		this.LoadOverviewImage = false;
		this.LoadZoomToImage = false;
		this.LoadIdentify = false;
		this.LoadRecordset = false;
		this.LoadSingleIdentify = false;

		this.DivMapLoading.style.display="none";
		this.UpdateMouseCursor();
	}
		
	this.Resize = function(){this.UpdateMapImage();}
	this.UpdateMapImage = function()
	{
		this.DivMapFrame.style.width = this.Width;
		this.DivMapFrame.style.height = this.Height;
		this.DivMap.style.width = this.Width;
		this.DivMap.style.height = this.Height;
		this.DivMapCanvas.style.width = this.Width;
		this.DivMapCanvas.style.height = this.Height;
		this.DivMapImage.style.width = this.Width;
		this.DivMapImage.style.height = this.Height;

		this.DivMapLoading.style.left=(this.Width/2)-120;
		this.DivMapLoading.style.top=(this.Height/2)-20;

		this.DivFileReady.style.left=(this.Width/2)-100;
		this.DivFileReady.style.top=(this.Height/2)-40;

		this.DivSelectLayout.style.left=(this.Width/2)-150;
		this.DivSelectLayout.style.top=(this.Height/2)-75;

	}
	
	this.UpdateMouseCursor = function()
	{
		switch (this.Action)
		{
			case "Select":
				myDivLib.SetCursor(this.DivMapFrame,'default');
				break;
			case "ZoomIn":
				myDivLib.SetCursor(this.DivMapFrame,'crosshair');
				break;
			case "ZoomOut":
				myDivLib.SetCursor(this.DivMapFrame,'crosshair');
				break;
			case "Pan":
				myDivLib.SetCursor(this.DivMapFrame,'move');
				break;
			case "Identify":
				myDivLib.SetCursor(this.DivMapFrame,'help');
				break;
		}
	}
	
	this.GetCoordinateByMapPoint = function(mappoint)
	{
		var x = Map.Extent.MinX + (mappoint.x * (Map.Extent.MaxX - Map.Extent.MinX) / Map.Width);
		var y = Map.Extent.MaxY - (mappoint.y * (Map.Extent.MaxY - Map.Extent.MinY) / Map.Height);
		var retPoint = new Point(x,y);
		return retPoint;
	}

    this.AddToHistory = function(imageURL)
    {
		if (this.HistoryIndex < (this.ViewHistory.length-1))
		{
			while (this.HistoryIndex < (this.ViewHistory.length-1))
			{
				this.ViewHistory.pop();
				this.ViewHistoryImages.pop();
			}
		}
		this.ViewHistoryImages.push(imageURL);
		this.ViewHistory.push(new Envelope());
		this.ViewHistory[this.ViewHistory.length-1].MinX = this.Extent.MinX;
		this.ViewHistory[this.ViewHistory.length-1].MinY = this.Extent.MinY;
		this.ViewHistory[this.ViewHistory.length-1].MaxX = this.Extent.MaxX;
		this.ViewHistory[this.ViewHistory.length-1].MaxY = this.Extent.MaxY;
		this.HistoryIndex = this.ViewHistory.length-1;
    }
    
    this.ChangeOpacity = function(opacity, object) 
    {
        
        //object.opacity = (opacity / 100); 
        //object.MozOpacity = (opacity / 100); 
        //object.KhtmlOpacity = (opacity / 100); 
        //object.filter = "alpha(opacity=" + opacity + ")"; 
        object.style.opacity = this._opacity/100;
        //object.filters.alpha.opacity = opacity;

        if (opacity == 0)
        {object.style.visibility="hidden";}
        else
        {object.style.visibility="visible";}
    } 
    
    this.FadeInID = null;
    this.FadeOpacity = 0;
    
    this.StopFade = function() 
    {
        clearInterval(this.FadeInID);
    }
   
    this.StartFadeIn = function(object)
    {
        this.StopFade();
        var objref = this;
        this.FadeInID = setInterval(function() { objref.FadeIn(object); },200);
    }
    
    this.FadeIn = function(object) 
    {
        if (this.FadeOpacity < 100)
        {
            this.FadeOpacity += 10;
            this.ChangeOpacity(this.FadeOpacity,object);
        }
        else
        {
            this.StopFade();
        }
    }
    
    this.FlashMapImage = function(imageURL)
    {
 		this.DivMap.innerHTML = '<img id="mapImage" src="' + imageURL + '" border="0">';
    }
    
    this.CancelPrint = function()
    {
		this.DivSelectLayout.style.display="none";
    }
    
    this.SelectLayout = function()
    {
		this.DivSelectLayout.style.display="block";
    }

    this.Print = function(LayoutParams)
    {
		this.DivSelectLayout.style.display="none";
		this.DivMapLoading.style.display="block";
        ServerProcess.AddCommand("CallMethod(Map,SetExtent," + Map.Extent.MinX + "|" + Map.Extent.MinY + "|" + Map.Extent.MaxX + "|" + Map.Extent.MaxY + ");");		    
        ServerProcess.AddCommand("CallMethod(Map,SetEnabledLayers," + this.EnabledLayers() + ");");		    
        ServerProcess.AddCommand("CallMethod(Map,SetDisabledLayers," + this.DisabledLayers() + ");");		    
        ServerProcess.AddCommand("CallMethod(Map,GetLayout," + LayoutParams + ");");
        ServerProcess.Execute();
    }
    
    this.LoadPDF = function (pdfURL)
    {
		this.DivMapLoading.style.display="none";
        this.FileURL = pdfURL;
        this.DivFileReady.style.display = "block";
        //location.href = pdfURL;
    }
    
    this.FileURL = "";
    this.DownloadFile = function()
    {
        this.DivFileReady.style.display = "none";
        window.open(this.FileURL);
    }
    
	this.LoadMapImage = function(imageURL)
	{
		//Set up the History
		if (!this.ZoomToHistory)
		{
		    this.AddToHistory(imageURL);
		}
		else
		{
			this.ZoomToHistory = false;		
		}		
		
		//Update the layer visibility
		for (var i=0;i<this.Layers.length;i++)
		{
			this.Layers[i].Visible = ((this.Scale >= this.Layers[i].MinScale) && ((this.Scale <= this.Layers[i].MaxScale) || (this.Layers[i].MaxScale == -1)));
		}
				
		this.ImageURL = imageURL;


		this.DivMap.innerHTML = "";
		myDivLib.Move(this.DivMap,0,0);
		this.DivMap.innerHTML = '<img id="mapImage" src="' + imageURL + '" border="0">';
		this.Canvas.clear();
			
		this.Refreshed();
		
		this.OnMapLoaded();
	}
	
	this.LoadMapFeatures = function()
	{
		this.UpdateMouseCursor();
	}
	
	this.LoadMapIdentify = function()
	{
		this.UpdateMouseCursor();
	}
	
	this.CreateNewLayer = function()
	{
		return new Layer();
	}

	this.CreateNewIdentifiedLayer = function()
	{
		return new IdentifiedLayer();
	}
	
	this.CreateNewRecordset = function()
	{
		return new RecordsetObject();
	}

	this.GetLayerNameByID = function(ArcIMSLayerID)
	{
		for (var i=0; i<this.Layers.length; i++)
		{
			if (this.Layers[i].ArcIMSLayerID == ArcIMSLayerID)
			{
				return this.Layers[i].LayerName;
			}
		}
		return ArcIMSLayerID;
	}
	
	this.GetLayerByID = function(ArcIMSLayerID)
	{
		for (var i=0; i<this.Layers.length; i++)
		{
			if (this.Layers[i].ArcIMSLayerID == ArcIMSLayerID)
			{
				return this.Layers[i];
			}
		}
		return null;
	}
	
	this.GetLayerIDByName = function(LayerName)
	{
		for (var i=0; i<this.Layers.length; i++)
		{
			if (this.Layers[i].LayerName == LayerName)
			{
				return this.Layers[i].ArcIMSLayerID;
			}
		}
		return null;
	}

	this.Canvas = new jsGraphics("mapcanvas");
	this.ZoomToFeature = function(ArcIMSLayerID,FieldName,FieldValue,FieldType)
	{
		//Make the call for a new map image and/or data
		myDivLib.SetCursor(this.DivMapFrame,'wait');
		
		this.DivMapLoading.style.left=(this.Width/2)-120;
		this.DivMapLoading.style.top=(this.Height/2)-20;
		this.DivMapLoading.style.display="block";

        this.GetLayerByID(ArcIMSLayerID).Enabled = true;
        
	    this.AddMapCommands();
		ServerProcess.AddCommand("CallMethod(Map,ZoomToFeature," + ArcIMSLayerID + "|" + FieldName + "|" + FieldValue + "|" + FieldType + ");");		    
		ServerProcess.Execute();
    }
	
	this.IdentifyFeature = function(ArcIMSLayerID,FieldName,FieldValue)
	{
		this.AttributeQueryArcIMSLayerID = ArcIMSLayerID;
		this.AttributeQueryWhereClause = FieldName + "=" + FieldValue;
		this.AttributeQueryUseView = false;
		this.LoadSingleIdentify = true;
		this.Refresh();
	}

    this.OnMapPageLoaded = function(e)
    {
	    this.Refresh();		
    }

    this.OnMapLoad = function(e)
    {
	    this.UpdateMouseCursor();
	    this.Canvas.clear();
    	
	    return false;
    }

    this.OnMapMouseDown = function(e)
    {
	    this.StartX = this.MouseX;
	    this.StartY = this.MouseY;
	    this.StartScreenX = this.MouseScreenX;
	    this.StartScreenY = this.MouseScreenY;
	    this.MouseDown = true;
    	
	    return false;
    }

    this.OnMapMouseUp = function(e)
    {
	    if (this.MouseDown)
	    {
		    this.MouseDown = false;			
		    this.EndX = this.MouseX;
		    this.EndY = this.MouseY;
		    this.EndScreenX = this.MouseScreenX;
		    this.EndScreenY = this.MouseScreenY;	
    		
		    var mapWidth = this.Extent.MaxX-this.Extent.MinX;
		    var mapHeight = this.Extent.MaxY-this.Extent.MinY;

		    this.LoadImage = false;
		    this.LoadRecordset = false;
		    this.LoadIdentify = false;

		    //Update the extents from the navigation
		    switch (this.Action)
		    {
			    case "Select":
				    this.LoadRecordset = true;
				    this.LoadImage = true;
				    var clickPoint1 = new Point(this.StartX,this.StartY);
				    var clickPoint2 = new Point(this.EndX,this.EndY);
				    if ((Math.abs(clickPoint1.x - clickPoint2.x) < 4) || (Math.abs(clickPoint1.y - clickPoint2.y) < 4))
				    {
					    var avePoint = new Point(((clickPoint1.x + clickPoint2.x)/2),((clickPoint1.y + clickPoint2.y)/2));
					    var mapPoint = this.GetCoordinateByMapPoint(avePoint)
					    this.SelectExtent.MinX = mapPoint.x - (mapWidth/4);
					    this.SelectExtent.MinY = mapPoint.y - (mapHeight/4);
					    this.SelectExtent.MaxX = mapPoint.x + (mapWidth/4);
					    this.SelectExtent.MaxY = mapPoint.y + (mapHeight/4);
				    }
				    else
				    {
					    var mapPoint1 = this.GetCoordinateByMapPoint(clickPoint1);
					    var mapPoint2 = this.GetCoordinateByMapPoint(clickPoint2);
					    this.SelectExtent.MinX = (mapPoint1.x < mapPoint2.x)? mapPoint1.x : mapPoint2.x;
					    this.SelectExtent.MinY = (mapPoint1.y < mapPoint2.y)? mapPoint1.y : mapPoint2.y;
					    this.SelectExtent.MaxX = (mapPoint1.x > mapPoint2.x)? mapPoint1.x : mapPoint2.x;
					    this.SelectExtent.MaxY = (mapPoint1.y > mapPoint2.y)? mapPoint1.y : mapPoint2.y;
				    }
				    break;
			    case "Identify":
				    this.LoadIdentify = true;
				    var clickPoint = new Point(this.StartX,this.StartY);
				    this.IdentifyPoint = this.GetCoordinateByMapPoint(clickPoint);
				    
				    var mapWidth = this.Extent.MaxX - this.Extent.MinX;
				    //var rat = mapWidth/this.Width;
				    var searchRadius = mapWidth/this.Width * 4;
				    //***This is just a time-saver.  This ability should be added to this library
				    IdentifyFeatures(this.IdentifyPoint.x, this.IdentifyPoint.y, searchRadius);
				    
				    return false;
				    //***End of hack
				    
				    break;
			    case "ZoomIn":
				    this.LoadImage = true;
				    var clickPoint1 = new Point(this.StartX,this.StartY);
				    var clickPoint2 = new Point(this.EndX,this.EndY);
				    if ((Math.abs(clickPoint1.x - clickPoint2.x) < 4) || (Math.abs(clickPoint1.y - clickPoint2.y) < 4))
				    {
					    var avePoint = new Point(((clickPoint1.x + clickPoint2.x)/2),((clickPoint1.y + clickPoint2.y)/2));
					    var mapPoint = this.GetCoordinateByMapPoint(avePoint)
					    this.Extent.MinX = mapPoint.x - (mapWidth/4);
					    this.Extent.MinY = mapPoint.y - (mapHeight/4);
					    this.Extent.MaxX = mapPoint.x + (mapWidth/4);
					    this.Extent.MaxY = mapPoint.y + (mapHeight/4);
				    }
				    else
				    {
					    var mapPoint1 = this.GetCoordinateByMapPoint(clickPoint1);
					    var mapPoint2 = this.GetCoordinateByMapPoint(clickPoint2);
					    this.Extent.MinX = (mapPoint1.x < mapPoint2.x)? mapPoint1.x : mapPoint2.x;
					    this.Extent.MinY = (mapPoint1.y < mapPoint2.y)? mapPoint1.y : mapPoint2.y;
					    this.Extent.MaxX = (mapPoint1.x > mapPoint2.x)? mapPoint1.x : mapPoint2.x;
					    this.Extent.MaxY = (mapPoint1.y > mapPoint2.y)? mapPoint1.y : mapPoint2.y;
				    }
				    break;
			    case "ZoomOut":
				    this.LoadImage = true;
				    var clickPoint = new Point(this.EndX,this.EndY);
				    var mapPoint = this.GetCoordinateByMapPoint(clickPoint)
				    this.Extent.MinX = mapPoint.x - (mapWidth);
				    this.Extent.MinY = mapPoint.y - (mapHeight);
				    this.Extent.MaxX = mapPoint.x + (mapWidth);
				    this.Extent.MaxY = mapPoint.y + (mapHeight);
				    break;
			    case "Pan":
				    this.LoadImage = true;
				    var clickPoint1 = new Point(this.StartX,this.StartY);
				    var clickPoint2 = new Point(this.StartX + (this.EndScreenX-this.StartScreenX),this.StartY + (this.EndScreenY - this.StartScreenY));
				    if ((Math.abs(clickPoint1.x - clickPoint2.x) < 4) || (Math.abs(clickPoint1.y - clickPoint2.y) < 4))
				    {
					    var avePoint = new Point(((clickPoint1.x + clickPoint2.x)/2),((clickPoint1.y + clickPoint2.y)/2));
					    var mapPoint = this.GetCoordinateByMapPoint(avePoint)
					    this.Extent.MinX = mapPoint.x - (mapWidth/2);
					    this.Extent.MinY = mapPoint.y - (mapHeight/2);
					    this.Extent.MaxX = mapPoint.x + (mapWidth/2);
					    this.Extent.MaxY = mapPoint.y + (mapHeight/2);
				    }
				    else
				    {
					    var mapPoint1 = this.GetCoordinateByMapPoint(clickPoint1);
					    var mapPoint2 = this.GetCoordinateByMapPoint(clickPoint2);
					    var diffX = mapPoint1.x - mapPoint2.x;
					    var diffY = mapPoint1.y - mapPoint2.y;
					    this.Extent.MinX = this.Extent.MinX + diffX;
					    this.Extent.MinY = this.Extent.MinY + diffY;
					    this.Extent.MaxX = this.Extent.MaxX + diffX;
					    this.Extent.MaxY = this.Extent.MaxY + diffY;
				    }
				    break;
		    }
    		
		    this.Refresh();
	    }
	    return false;
    }

    this.OnMapMouseMove = function(e)
    {
	    var eventSourceID = isIE? event.srcElement.id : e.target.id;
	    if (eventSourceID == '') return false;
    	
	    this.MouseX = isIE? event.offsetX : e.layerX;
	    this.MouseY = isIE? event.offsetY : e.layerY;
	    this.MouseScreenX = isIE? event.screenX : e.screenX;
	    this.MouseScreenY = isIE? event.screenY : e.screenY;
    	
	    //Display the coordinates
	    var screenPoint = new Point(this.MouseX,this.MouseY);
	    var mapPoint = this.GetCoordinateByMapPoint(screenPoint);
    	
	    if (!this.Drawing && this.MouseDown)
	    {
    		
		    if (this.Action == "Pan")
		    {
			    myDivLib.Move(this.DivMap,(this.MouseScreenX-this.StartScreenX),(this.MouseScreenY-this.StartScreenY));
		    }
		    else if ((this.Action == "ZoomIn") || (this.Action == "Select"))
		    {
			    this.Drawing = true;

			    var top = (this.MouseY > this.StartY)? this.StartY : this.MouseY;
			    var bottom = (this.MouseY > this.StartY)? this.MouseY : this.StartY;
			    var left = (this.MouseX > this.StartX)? this.StartX : this.MouseX;
			    var right = (this.MouseX > this.StartX)? this.MouseX : this.StartX;

			    var width = Math.abs(right - left); //test
			    var height = Math.abs(bottom - top); //test
    			
			    this.Canvas.clear();
			    this.Canvas.setColor("#ff0000");
			    this.Canvas.setStroke(2);
    			
				//Draw Rectangle
				this.Canvas.drawRect(left,top,width,height);
				this.Canvas.paint();
				this.Drawing=false;
		    }
	    }

	    return false;
    }
}



//////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// Object DivLib ////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
var myDivLib = new DivLib();
function DivLib()
{
	this.Clip = divClip;
	this.Move = divMove;
	this.SetCursor = divSetCursor;
}

function divClip(obj,t,r,b,l)
{
	obj.style.clip = "rect("+t+"px "+r+"px "+b+"px "+l+"px)"
}

function divMove(obj,x,y)
{
	obj.style.left = x + "px";
	obj.style.top = y + "px";
}

function divSetCursor(obj,cursor)
{
	obj.style.cursor = cursor;
}

//////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// Object Layer /////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
	
function Layer()
{
	this.ArcIMSLayerID = -1;
	this.Enabled = false;
	this.LayerName = "";
	this.Visible = false;
	this.Recordset = null;
	this.urlImage = "";
	this.GroupName = "";
	this.MinScale = 0;
	this.MaxScale = 0;
}


//////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// Object Recordset ///////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
	
function RecordsetObject()
{
	this.ArcIMSLayerID = -1;
	this.Count = -1;
	this.HasMore = false;
	this.Envelope = new Envelope();
	this.FieldCount = -1;
	this.SpatialFilter = "";
	this.WhereClause = "";
	this.TableName = "";
	this.Fields = new Array();
	this.Aliases = new Array();
	this.Data = new Array(); //this will contain all of the data
	
	this.GetFieldIndexByName = function(name)
	{
		for (var i=0; i<this.Fields.length; i++)
		{
			if (this.Fields[i] == name) return i;
		}
		return -1;
	}
	
	this.Sort = function(fieldindex,sortorder)
	{
		var tempData = new Array();

		for (var i=0; i<this.Data.length; i++)
		{
			var thisFieldValue = this.Data[i][fieldindex];
			//alert(thisFieldValue);

			if (i==0)
			{	
				this.InsertRecord(tempData,this.Data[i],0);
			}
			else
			{
				var minIndex = 0;
				var maxIndex = tempData.length - 1;

				while (true)
				{
					if ((maxIndex-minIndex)==0)
					{
						var testFieldValue = tempData[minIndex][fieldindex];
						//alert(testFieldValue);
		
						if (((sortorder=='ASCENDING') && (testFieldValue<thisFieldValue)) || ((sortorder=='DESCENDING') && (testFieldValue>thisFieldValue)))
						{
							this.InsertRecord(tempData,this.Data[i],minIndex);
						}
						else if (((sortorder=='ASCENDING') && (testFieldValue>thisFieldValue)) || ((sortorder=='DESCENDING') && (testFieldValue<thisFieldValue)))
						{
							this.InsertRecord(tempData,this.Data[i],minIndex+1);
						}
						else //!!!!!!Need to check if the value is the same!!!!!!!
						{
							this.InsertRecord(tempData,this.Data[i],minIndex+1);
						}

						break;
					}
					else
					{
						var midIndex = Math.round((minIndex+maxIndex)/2);
						var testFieldvalue = tempData[midIndex][fieldindex];
						
						if (((sortorder=='ASCENDING') && (testFieldValue<thisFieldValue)) || ((sortorder=='DESCENDING') && (testFieldValue>thisFieldValue)))
						{
							maxIndex = midIndex;
						}
						else //!!!!!!Need to check if the value is the same!!!!!!!
						{
							minIndex = midIndex;
						}
					}
				}
			}
		}
		this.Data = tempData;
	}
		
	this.InsertRecord = function(dataset,record,index)
	{
		dataset.push(record);
		for (var i=dataset.length-1;i>index;i--)
		{
			dataset[i] = dataset[i-1];
		}
		dataset[index]=record;
	}
}






//////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// Object Envelope ///////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
	
function Envelope()
{
	this.MinX = -1;
	this.MinY = -1;
	this.MaxX = -1;
	this.MaxY = -1;
}

//////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// Object Line /////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
	
function Line(fromx,fromy,tox,toy)
{
	this.FromX = fromx;
	this.FromY = fromy;
	this.ToX = tox;
	this.ToY = toy;
}

//////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////// Object Point /////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
	
function Point(x,y)
{
	this.x = x;
	this.y = y;
}


	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
/* This notice must be untouched at all times.

wz_jsgraphics.js    v. 2.3
The latest version is available at
http://www.walterzorn.com
or http://www.devira.com
or http://www.walterzorn.de

Copyright (c) 2002-2004 Walter Zorn. All rights reserved.
Created 3. 11. 2002 by Walter Zorn (Web: http://www.walterzorn.com )
Last modified: 29. 9. 2004

Performance optimizations for Internet Explorer
by Thomas Frank and John Holdsworth.
fillPolygon method implemented by Matthieu Haller.

High Performance JavaScript Graphics Library.
Provides methods
- to draw lines, rectangles, ellipses, polygons
  with specifiable line thickness,
- to fill rectangles and ellipses
- to draw text.
NOTE: Operations, functions and branching have rather been optimized
to efficiency and speed than to shortness of source code.

LICENSE: LGPL

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (LGPL) as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA,
or see http://www.gnu.org/copyleft/lesser.html 
*/


var jg_ihtm, jg_ie, jg_fast, jg_dom, jg_moz,
jg_n4 = (document.layers && typeof document.classes != "undefined");


function chkDHTM(x, i)
{
	x = document.body || null;
	jg_ie = x && typeof x.insertAdjacentHTML != "undefined";
	jg_dom = (x && !jg_ie &&
		typeof x.appendChild != "undefined" &&
		typeof document.createRange != "undefined" &&
		typeof (i = document.createRange()).setStartBefore != "undefined" &&
		typeof i.createContextualFragment != "undefined");
	jg_ihtm = !jg_ie && !jg_dom && x && typeof x.innerHTML != "undefined";
	jg_fast = jg_ie && document.all && !window.opera;
	//jg_fast = false;
	jg_moz = jg_dom && typeof x.style.MozOpacity != "undefined";
}


function pntDoc()
{
	this.wnd.document.write(jg_fast? this.htmRpc() : this.htm);
	this.htm = '';
}


function pntCnvDom()
{
	var x = document.createRange();
	x.setStartBefore(this.cnv);
	x = x.createContextualFragment(jg_fast? this.htmRpc() : this.htm);
	this.cnv.appendChild(x);
	this.htm = '';
}


function pntCnvIe()
{
	this.cnv.insertAdjacentHTML("BeforeEnd", jg_fast? this.htmRpc() : this.htm);
	this.htm = '';
	//this.cnv.innerHTML += jg_fast? this.htmRpc() : this.htm;
	//this.htm = '';
	//this.cnv.innerText += jg_fast? this.htmRpc() : this.htm;
	//this.htm = '';
}


function pntCnvIhtm()
{
	this.cnv.innerHTML += this.htm;
	this.htm = '';
}


function pntCnv()
{
	this.htm = '';
}


function mkDiv(x, y, w, h)
{
	this.htm += '<div style="position:absolute;'+
		'left:' + x + 'px;'+
		'top:' + y + 'px;'+
		'width:' + w + 'px;'+
		'height:' + h + 'px;'+
		'clip:rect(0,'+w+'px,'+h+'px,0);'+
		'background-color:' + this.color +
		(!jg_moz? ';overflow:hidden' : '')+
		';"><\/div>';
}


function mkDivIe(x, y, w, h)
{
	this.htm += '%%'+this.color+';'+x+';'+y+';'+w+';'+h+';';
}


function mkDivPrt(x, y, w, h)
{
	this.htm += '<div style="position:absolute;'+
		'border-left:' + w + 'px solid ' + this.color + ';'+
		'left:' + x + 'px;'+
		'top:' + y + 'px;'+
		'width:0px;'+
		'height:' + h + 'px;'+
		'clip:rect(0,'+w+'px,'+h+'px,0);'+
		'background-color:' + this.color +
		(!jg_moz? ';overflow:hidden' : '')+
		';"><\/div>';
}


function mkLyr(x, y, w, h)
{
	this.htm += '<layer '+
		'left="' + x + '" '+
		'top="' + y + '" '+
		'width="' + w + '" '+
		'height="' + h + '" '+
		'bgcolor="' + this.color + '"><\/layer>\n';
}


var regex =  /%%([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);/g;
function htmRpc()
{
	return this.htm.replace(
		regex,
		'<div style="overflow:hidden;position:absolute;background-color:'+
		'$1;left:$2;top:$3;width:$4;height:$5"></div>\n');
}


function htmPrtRpc()
{
	return this.htm.replace(
		regex,
		'<div style="overflow:hidden;position:absolute;background-color:'+
		'$1;left:$2;top:$3;width:$4;height:$5;border-left:$4px solid $1"></div>\n');
}


function mkLin(x1, y1, x2, y2)
{
	if (x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1;

	if (dx >= dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx,
		ox = x;
		while ((dx--) > 0)
		{
			++x;
			if (p > 0)
			{
				this.mkDiv(ox, y, x-ox, 1);
				y += yIncr;
				p += pru;
				ox = x;
			}
			else p += pr;
		}
		this.mkDiv(ox, y, x2-ox+1, 1);
	}

	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy,
		oy = y;
		if (y2 <= y1)
		{
			while ((dy--) > 0)
			{
				if (p > 0)
				{
					this.mkDiv(x++, y, 1, oy-y+1);
					y += yIncr;
					p += pru;
					oy = y;
				}
				else
				{
					y += yIncr;
					p += pr;
				}
			}
			this.mkDiv(x2, y2, 1, oy-y2+1);
		}
		else
		{
			while ((dy--) > 0)
			{
				y += yIncr;
				if (p > 0)
				{
					this.mkDiv(x++, oy, 1, y-oy);
					p += pru;
					oy = y;
				}
				else p += pr;
			}
			this.mkDiv(x2, oy, 1, y2-oy+1);
		}
	}
}


function mkLin2D(x1, y1, x2, y2)
{
	if (x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1;

	var s = this.stroke;
	if (dx >= dy)
	{
		if (s-3 > 0)
		{
			var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx;
			_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
		}
		else var _s = s;
		var ad = Math.ceil(s/2);

		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx,
		ox = x;
		while ((dx--) > 0)
		{
			++x;
			if (p > 0)
			{
				this.mkDiv(ox, y, x-ox+ad, _s);
				y += yIncr;
				p += pru;
				ox = x;
			}
			else p += pr;
		}
		this.mkDiv(ox, y, x2-ox+ad+1, _s);
	}

	else
	{
		if (s-3 > 0)
		{
			var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy;
			_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
		}
		else var _s = s;
		var ad = Math.round(s/2);

		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy,
		oy = y;
		if (y2 <= y1)
		{
			++ad;
			while ((dy--) > 0)
			{
				if (p > 0)
				{
					this.mkDiv(x++, y, _s, oy-y+ad);
					y += yIncr;
					p += pru;
					oy = y;
				}
				else
				{
					y += yIncr;
					p += pr;
				}
			}
			this.mkDiv(x2, y2, _s, oy-y2+ad);
		}
		else
		{
			while ((dy--) > 0)
			{
				y += yIncr;
				if (p > 0)
				{
					this.mkDiv(x++, oy, _s, y-oy+ad);
					p += pru;
					oy = y;
				}
				else p += pr;
			}
			this.mkDiv(x2, oy, _s, y2-oy+ad+1);
		}
	}
}


function mkLinDott(x1, y1, x2, y2)
{
	if (x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1,
	drw = true;
	if (dx >= dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx;
		while ((dx--) > 0)
		{
			if (drw) this.mkDiv(x, y, 1, 1);
			drw = !drw;
			if (p > 0)
			{
				y += yIncr;
				p += pru;
			}
			else p += pr;
			++x;
		}
		if (drw) this.mkDiv(x, y, 1, 1);
	}

	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy;
		while ((dy--) > 0)
		{
			if (drw) this.mkDiv(x, y, 1, 1);
			drw = !drw;
			y += yIncr;
			if (p > 0)
			{
				++x;
				p += pru;
			}
			else p += pr;
		}
		if (drw) this.mkDiv(x, y, 1, 1);
	}
}


function mkOv(left, top, width, height)
{
	var a = width>>1, b = height>>1,
	wod = width&1, hod = (height&1)+1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	ox = 0, oy = b,
	aa = (a*a)<<1, bb = (b*b)<<1,
	st = (aa>>1)*(1-(b<<1)) + bb,
	tt = (bb>>1) - aa*((b<<1)-1),
	w, h;
	while (y > 0)
	{
		if (st < 0)
		{
			st += bb*((x<<1)+3);
			tt += (bb<<1)*(++x);
		}
		else if (tt < 0)
		{
			st += bb*((x<<1)+3) - (aa<<1)*(y-1);
			tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
			w = x-ox;
			h = oy-y;
			if (w&2 && h&2)
			{
				this.mkOvQds(cx, cy, -x+2, ox+wod, -oy, oy-1+hod, 1, 1);
				this.mkOvQds(cx, cy, -x+1, x-1+wod, -y-1, y+hod, 1, 1);
			}
			else this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, oy-h+hod, w, h);
			ox = x;
			oy = y;
		}
		else
		{
			tt -= aa*((y<<1)-3);
			st -= (aa<<1)*(--y);
		}
	}
	this.mkDiv(cx-a, cy-oy, a-ox+1, (oy<<1)+hod);
	this.mkDiv(cx+ox+wod, cy-oy, a-ox+1, (oy<<1)+hod);
}


function mkOv2D(left, top, width, height)
{
	var s = this.stroke;
	width += s-1;
	height += s-1;
	var a = width>>1, b = height>>1,
	wod = width&1, hod = (height&1)+1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	aa = (a*a)<<1, bb = (b*b)<<1,
	st = (aa>>1)*(1-(b<<1)) + bb,
	tt = (bb>>1) - aa*((b<<1)-1);

	if (s-4 < 0 && (!(s-2) || width-51 > 0 && height-51 > 0))
	{
		var ox = 0, oy = b,
		w, h,
		pxl, pxr, pxt, pxb, pxw;
		while (y > 0)
		{
			if (st < 0)
			{
				st += bb*((x<<1)+3);
				tt += (bb<<1)*(++x);
			}
			else if (tt < 0)
			{
				st += bb*((x<<1)+3) - (aa<<1)*(y-1);
				tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
				w = x-ox;
				h = oy-y;

				if (w-1)
				{
					pxw = w+1+(s&1);
					h = s;
				}
				else if (h-1)
				{
					pxw = s;
					h += 1+(s&1);
				}
				else pxw = h = s;
				this.mkOvQds(cx, cy, -x+1, ox-pxw+w+wod, -oy, -h+oy+hod, pxw, h);
				ox = x;
				oy = y;
			}
			else
			{
				tt -= aa*((y<<1)-3);
				st -= (aa<<1)*(--y);
			}
		}
		this.mkDiv(cx-a, cy-oy, s, (oy<<1)+hod);
		this.mkDiv(cx+a+wod-s+1, cy-oy, s, (oy<<1)+hod);
	}

	else
	{
		var _a = (width-((s-1)<<1))>>1,
		_b = (height-((s-1)<<1))>>1,
		_x = 0, _y = _b,
		_aa = (_a*_a)<<1, _bb = (_b*_b)<<1,
		_st = (_aa>>1)*(1-(_b<<1)) + _bb,
		_tt = (_bb>>1) - _aa*((_b<<1)-1),

		pxl = new Array(),
		pxt = new Array(),
		_pxb = new Array();
		pxl[0] = 0;
		pxt[0] = b;
		_pxb[0] = _b-1;
		while (y > 0)
		{
			if (st < 0)
			{
				st += bb*((x<<1)+3);
				tt += (bb<<1)*(++x);
				pxl[pxl.length] = x;
				pxt[pxt.length] = y;
			}
			else if (tt < 0)
			{
				st += bb*((x<<1)+3) - (aa<<1)*(y-1);
				tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
				pxl[pxl.length] = x;
				pxt[pxt.length] = y;
			}
			else
			{
				tt -= aa*((y<<1)-3);
				st -= (aa<<1)*(--y);
			}

			if (_y > 0)
			{
				if (_st < 0)
				{
					_st += _bb*((_x<<1)+3);
					_tt += (_bb<<1)*(++_x);
					_pxb[_pxb.length] = _y-1;
				}
				else if (_tt < 0)
				{
					_st += _bb*((_x<<1)+3) - (_aa<<1)*(_y-1);
					_tt += (_bb<<1)*(++_x) - _aa*(((_y--)<<1)-3);
					_pxb[_pxb.length] = _y-1;
				}
				else
				{
					_tt -= _aa*((_y<<1)-3);
					_st -= (_aa<<1)*(--_y);
					_pxb[_pxb.length-1]--;
				}
			}
		}

		var ox = 0, oy = b,
		_oy = _pxb[0],
		l = pxl.length,
		w, h;
		for (var i = 0; i < l; i++)
		{
			if (typeof _pxb[i] != "undefined")
			{
				if (_pxb[i] < _oy || pxt[i] < oy)
				{
					x = pxl[i];
					this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, _oy+hod, x-ox, oy-_oy);
					ox = x;
					oy = pxt[i];
					_oy = _pxb[i];
				}
			}
			else
			{
				x = pxl[i];
				this.mkDiv(cx-x+1, cy-oy, 1, (oy<<1)+hod);
				this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
				ox = x;
				oy = pxt[i];
			}
		}
		this.mkDiv(cx-a, cy-oy, 1, (oy<<1)+hod);
		this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
	}
}


function mkOvDott(left, top, width, height)
{
	var a = width>>1, b = height>>1,
	wod = width&1, hod = height&1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
	st = (aa2>>1)*(1-(b<<1)) + bb,
	tt = (bb>>1) - aa2*((b<<1)-1),
	drw = true;
	while (y > 0)
	{
		if (st < 0)
		{
			st += bb*((x<<1)+3);
			tt += (bb<<1)*(++x);
		}
		else if (tt < 0)
		{
			st += bb*((x<<1)+3) - aa4*(y-1);
			tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3);
		}
		else
		{
			tt -= aa2*((y<<1)-3);
			st -= aa4*(--y);
		}
		if (drw) this.mkOvQds(cx, cy, -x, x+wod, -y, y+hod, 1, 1);
		drw = !drw;
	}
}


function mkRect(x, y, w, h)
{
	var s = this.stroke;
	this.mkDiv(x, y, w, s);
	this.mkDiv(x+w, y, s, h);
	this.mkDiv(x, y+h, w+s, s);
	this.mkDiv(x, y+s, s, h-s);
}


function mkRectDott(x, y, w, h)
{
	this.drawLine(x, y, x+w, y);
	this.drawLine(x+w, y, x+w, y+h);
	this.drawLine(x, y+h, x+w, y+h);
	this.drawLine(x, y, x, y+h);
}


function jsgFont()
{
	this.PLAIN = 'font-weight:normal;';
	this.BOLD = 'font-weight:bold;';
	this.ITALIC = 'font-style:italic;';
	this.ITALIC_BOLD = this.ITALIC + this.BOLD;
	this.BOLD_ITALIC = this.ITALIC_BOLD;
}
var Font = new jsgFont();


function jsgStroke()
{
	this.DOTTED = -1;
}
var Stroke = new jsgStroke();


function jsGraphics(id, wnd)
{
	this.setColor = new Function('arg', 'this.color = arg.toLowerCase();');

	this.setStroke = function(x)
	{
		this.stroke = x;
		if (!(x+1))
		{
			this.drawLine = mkLinDott;
			this.mkOv = mkOvDott;
			this.drawRect = mkRectDott;
		}
		else if (x-1 > 0)
		{
			this.drawLine = mkLin2D;
			this.mkOv = mkOv2D;
			this.drawRect = mkRect;
		}
		else
		{
			this.drawLine = mkLin;
			this.mkOv = mkOv;
			this.drawRect = mkRect;
		}
	};


	this.setPrintable = function(arg)
	{
		this.printable = arg;
		if (jg_fast)
		{
			this.mkDiv = mkDivIe;
			this.htmRpc = arg? htmPrtRpc : htmRpc;
		}
		else this.mkDiv = jg_n4? mkLyr : arg? mkDivPrt : mkDiv;
	};


	this.setFont = function(fam, sz, sty)
	{
		this.ftFam = fam;
		this.ftSz = sz;
		this.ftSty = sty || Font.PLAIN;
	};


	this.drawPolyline = this.drawPolyLine = function(x, y, s)
	{
		for (var i=0 ; i<x.length-1 ; i++ )
			this.drawLine(x[i], y[i], x[i+1], y[i+1]);
	};


	this.fillRect = function(x, y, w, h)
	{
		this.mkDiv(x, y, w, h);
	};


	this.drawPolygon = function(x, y)
	{
		this.drawPolyline(x, y);
		this.drawLine(x[x.length-1], y[x.length-1], x[0], y[0]);
	};


	this.drawEllipse = this.drawOval = function(x, y, w, h)
	{
		this.mkOv(x, y, w, h);
	};


	this.fillEllipse = this.fillOval = function(left, top, w, h)
	{
		var a = (w -= 1)>>1, b = (h -= 1)>>1,
		wod = (w&1)+1, hod = (h&1)+1,
		cx = left+a, cy = top+b,
		x = 0, y = b,
		ox = 0, oy = b,
		aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
		st = (aa2>>1)*(1-(b<<1)) + bb,
		tt = (bb>>1) - aa2*((b<<1)-1),
		pxl, dw, dh;
		if (w+1) while (y > 0)
		{
			if (st < 0)
			{
				st += bb*((x<<1)+3);
				tt += (bb<<1)*(++x);
			}
			else if (tt < 0)
			{
				st += bb*((x<<1)+3) - aa4*(y-1);
				pxl = cx-x;
				dw = (x<<1)+wod;
				tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3);
				dh = oy-y;
				this.mkDiv(pxl, cy-oy, dw, dh);
				this.mkDiv(pxl, cy+oy-dh+hod, dw, dh);
				ox = x;
				oy = y;
			}
			else
			{
				tt -= aa2*((y<<1)-3);
				st -= aa4*(--y);
			}
		}
		this.mkDiv(cx-a, cy-oy, w+1, (oy<<1)+hod);
	};



/* fillPolygon method, implemented by Matthieu Haller.
This javascript function is an adaptation of the gdImageFilledPolygon for Walter Zorn lib.
C source of GD 1.8.4 found at http://www.boutell.com/gd/

THANKS to Kirsten Schulz for the polygon fixes!

The intersection finding technique of this code could be improved
by remembering the previous intertersection, and by using the slope.
That could help to adjust intersections to produce a nice
interior_extrema. */
	this.fillPolygon = function(array_x, array_y)
	{
		var i;
		var y;
		var miny, maxy;
		var x1, y1;
		var x2, y2;
		var ind1, ind2;
		var ints;

		var n = array_x.length;

		if (!n) return;


		miny = array_y[0];
		maxy = array_y[0];
		for (i = 1; i < n; i++)
		{
			if (array_y[i] < miny)
				miny = array_y[i];

			if (array_y[i] > maxy)
				maxy = array_y[i];
		}
		for (y = miny; y <= maxy; y++)
		{
			var polyInts = new Array();
			ints = 0;
			for (i = 0; i < n; i++)
			{
				if (!i)
				{
					ind1 = n-1;
					ind2 = 0;
				}
				else
				{
					ind1 = i-1;
					ind2 = i;
				}
				y1 = array_y[ind1];
				y2 = array_y[ind2];
				if (y1 < y2)
				{
					x1 = array_x[ind1];
					x2 = array_x[ind2];
				}
				else if (y1 > y2)
				{
					y2 = array_y[ind1];
					y1 = array_y[ind2];
					x2 = array_x[ind1];
					x1 = array_x[ind2];
				}
				else continue;

				 // modified 11. 2. 2004 Walter Zorn
				if ((y >= y1) && (y < y2))
					polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);

				else if ((y == maxy) && (y > y1) && (y <= y2))
					polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);
			}
			polyInts.sort(integer_compare);
			for (i = 0; i < ints; i+=2)
				this.mkDiv(polyInts[i], y, polyInts[i+1]-polyInts[i]+1, 1);
		}
	};


	this.drawString = function(txt, x, y)
	{
		this.htm += '<div style="position:absolute;white-space:nowrap;'+
			'left:' + x + 'px;'+
			'top:' + y + 'px;'+
			'font-family:' +  this.ftFam + ';'+
			'font-size:' + this.ftSz + ';'+
			'color:' + this.color + ';' + this.ftSty + '">'+
			txt +
			'<\/div>';
	}


	this.drawImage = function(imgSrc, x, y, w, h)
	{
		this.htm += '<div style="position:absolute;'+
			'left:' + x + 'px;'+
			'top:' + y + 'px;'+
			'width:' +  w + ';'+
			'height:' + h + ';">'+
			'<img src="' + imgSrc + '" width="' + w + '" height="' + h + '">'+
			'<\/div>';
	}


	this.clear = function()
	{
		this.htm = "";
		if (this.cnv) this.cnv.innerHTML = this.defhtm;
	};


	this.mkOvQds = function(cx, cy, xl, xr, yt, yb, w, h)
	{
		this.mkDiv(xr+cx, yt+cy, w, h);
		this.mkDiv(xr+cx, yb+cy, w, h);
		this.mkDiv(xl+cx, yb+cy, w, h);
		this.mkDiv(xl+cx, yt+cy, w, h);
	};

	this.setStroke(1);
	this.setFont('verdana,geneva,helvetica,sans-serif', String.fromCharCode(0x31, 0x32, 0x70, 0x78), Font.PLAIN);
	this.color = '#000000';
	this.htm = '';
	this.wnd = wnd || window;

	if (!(jg_ie || jg_dom || jg_ihtm)) chkDHTM();
	if (typeof id != 'string' || !id) this.paint = pntDoc;
	else
	{
		this.cnv = document.all? (this.wnd.document.all[id] || null)
			: document.getElementById? (this.wnd.document.getElementById(id) || null)
			: null;
		this.defhtm = (this.cnv && this.cnv.innerHTML)? this.cnv.innerHTML : '';
		this.paint = jg_dom? pntCnvDom : jg_ie? pntCnvIe : jg_ihtm? pntCnvIhtm : pntCnv;
	}

	this.setPrintable(false);
}



function integer_compare(x,y)
{
	return (x < y) ? -1 : ((x > y)*1);
}


