////////////////////////////////////////////////////////////////////////////////////////////
// MappingControl tool client-side script
////////////////////////////////////////////////////////////////////////////////////////////

addNamespace("Tools");

////////////////////////////////////////////////////////////////////////////////////////////

Tools.SettingsClass = Class.create();
Tools.SettingsClass.prototype =
{
	initialize: function()
	{
		this.reset();
	},
	
	reset: function()
	{
		this.allowMultipleSelections = true;
		this.allowKeyboardZoom = true;
		this.allowKeyboardPan = true;
	}
};

////////////////////////////////////////////////////////////////////////////////////////////

Tools.ToolBoxClass = Class.create();
Tools.ToolBoxClass.prototype =
{
	initialize: function()
	{
		this.items = new Core.Collection();
		this.current = null;
	},
	
	// add a tool to the collection
	add: function(tool)
	{
		if (this.items.contains(tool.id))
			this.items.remove(tool.id);
		
		this.items.add(tool);
	},
	
	// create a tool and add it to the collection
	create: function(id)
	{
		if (id == null)
		{
			new Tools.DummyTool();
			new Tools.PanTool();
			new Tools.CenterTool();
			new Tools.ZoomTool();
			new Tools.SelectionTool();
			new Tools.CoordinateTool();
			new Tools.InfoTool();
			new Tools.DrawTextTool();
			new Tools.DrawSymbolTool();
		}
		else
			eval("new Tools." + id + "Tool()");
	},
	
	// get a tool based on its id
	get: function(id)
	{
		return this.items.get(id);
	},
	
	// stop the current tool and set the new tool but don't start it
	select: function(id)
	{
		if (this.current != null)
			this.current.stop();
		
		this.current = this.get(id);
	},
	
	// stop the current tool and start the new tool
	use: function(id, map)
	{	
		if (!map && this.current)
			var map = this.current.map;
		if (!map)
			var map = Mapping.Current;
		if (!map)
			return;
		
		this.select(id);
		
		return this.current.start(map);
	},
	
	// use the tool without selecting it
	quickUse: function(id, map, arg)
	{
		var tool = Tools.ToolBox.get(id);
		if (!tool) return;
		
		var oldMap = tool.map;
		tool.map = map;
		
		eval("tool." + arg);
		
		tool.map = oldMap;
	}
};
Tools.ToolBox = new Tools.ToolBoxClass();

////////////////////////////////////////////////////////////////////////////////////////////

Tools.ToolBase = Class.create();
Tools.ToolBase.prototype =
{
	base: function(id)
	{
		this.id = id;
		this.running = false;
		this.map = null;
		this.capturing = false;
	},
	
	activate: function(map)
	{
		Tools.ToolBox.current = this;
		this.running = true;
		this.map = map;
		
		return true;
	},
	
	deactivate: function()
	{
		Tools.ToolBox.current = null;
		this.running = false;
		this.map = null;
		
		return true;
	},
	
	onevent: function(e)
	{
		Core.Utility.setEvent(e);
	}
};

////////////////////////////////////////////////////////////////////////////////////////////

Tools.DummyTool = Class.inherit(Tools.ToolBase, 
{
	initialize: function()
	{
		this.base("$$Dummy");
		Tools.ToolBox.add(this);
	}
});

////////////////////////////////////////////////////////////////////////////////////////////

Tools.PanTool = Class.inherit(Tools.ToolBase, 
{
	initialize: function()
	{
		this.base("Pan");
		
		this.moveX = this.moveY = 0;
		this.currentX = this.currentY = 0;
		this.timer = new Core.Timer();
		this.delay = 150;
		this.keyboardDelay = 400;
		
		Tools.ToolBox.add(this);
	},
	
	// start the tool for the specified map
	start: function(map)
	{
		if (this.running)
			return false;
		
		this._onmousedown = map.image.onmousedown;
		this._onmouseup = document.onmouseup;
		this._onmousemove = document.onmousemove;
		map.image.onmousedown = this.onmousedown.bindAsEventListener(this);
		document.onmouseup = this.onmouseup.bindAsEventListener(this);
		document.onmousemove = this.onmousemove.bindAsEventListener(this);
		
		if (map.toolSettings.allowKeyboardPan)
		{
			this._onkeydown = document.onkeydown;
			document.onkeydown = this.onkeydown.bindAsEventListener(this);
			map.showInformation("Use the arrow keys or click and drag the mouse to pan the map", this.id);
		}
		else
			map.showInformation("Click and drag the mouse to pan the map", this.id);
		
		Drawing.Window.setCursor("move", map.image);
		
		return this.activate(map);
	},
	
	// stop the tool
	stop: function()
	{
		this.currentX = this.currentY = 0;
		
		if (this.timer.running)
			this.timer.stop();
		
		this.map.image.onmousedown = this._onmousedown;
		document.onmouseup = this._onmouseup;
		document.onmousemove = this._onmousemove;
		
		if (this.map.toolSettings.allowKeyboardPan)
			document.onkeydown = this._onkeydown;
		
		Drawing.Window.setCursor("auto", this.map.image);
		this.map.hideInformation(this.id);
		
		this.deactivate();
	},
	
	// onmousedown
	onmousedown: function(e)
	{
		Drawing.Window.setCursor("move", document.body);
		
		this.onevent(e);
		this.capturing = true;
		this.currentX = Core.Utility.getClientX();
		this.currentY = Core.Utility.getClientY();
	},
	
	// onmouseup
	onmouseup: function(e)
	{
		if (!this.running || !this.capturing)
			return;
		
		Drawing.Window.setCursor("auto", document.body);
		this.onevent(e);
		
		if (this.map.serverEvents.contains(this.map.id + "_MapPanServerEvent"))
			this.pan(-this.moveX, -this.moveY);
		
		this.capturing = false;
	},
	
	// onmousemove
	onmousemove: function(e)
	{
		if (!this.running || !this.capturing)
			return;
		
		this.onevent(e);
		
		var offsetX = this.currentX - Core.Utility.getClientX();
		var offsetY = this.currentY - Core.Utility.getClientY();
		this.moveX += offsetX;
		this.moveY += offsetY;
		this.currentX = Core.Utility.getClientX();
		this.currentY = Core.Utility.getClientY();
		
		if (!this.map.serverEvents.contains(this.map.id + "_MapPanServerEvent"))
		{
			this.timer.delay = this.delay;
			this.timer.ontimer = function()
			{
				Tools.ToolBox.current.pan(-Tools.ToolBox.current.moveX, -Tools.ToolBox.current.moveY);
				Tools.ToolBox.current.moveX = Tools.ToolBox.current.moveY = 0;
			};
			this.timer.start();
		}
		
		this.map.container.style.overflow = "hidden";
		
		
		var top = Number(this.map.image.style.top.replace("px",""));
		var left = Number(this.map.image.style.left.replace("px",""));
		this.map.image.style.left = Core.Utility.toSize(left - offsetX);
		this.map.image.style.top = Core.Utility.toSize(top - offsetY);
		
		var clipLeft = 0;
		var clipTop = 0;
		var clipRight = this.map.width;
		var clipBottom = this.map.height;
		
		if (offsetX - left < 0)
			clipRight += offsetX - left;
		else
			clipLeft = offsetX - left;
		
		if (offsetY - top < 0)
			clipBottom += offsetY - top;
		else
			clipTop = offsetY - top;
		
		Core.Debug.write("Clipping: " + clipTop + " " + clipRight + " " + clipBottom + " " + clipLeft);
		
		this.map.image.style.clip = "rect(" + clipTop + "px " + clipRight + "px " + clipBottom + "px " + clipLeft + "px)";
	},
	
	// onkeydown
	onkeydown: function(e)
	{
		if (!this.running || !this.map.toolSettings.allowKeyboardPan)
			return;
		
		this.onevent(e);
		var e = Core.Utility.lastEvent;
		
		var keyCode = e.which ? e.which : (e.keyCode ? e.keyCode : (e.charCode ? e.charCode : 0));
		
		if (this.capturing)
		{
			if (keyCode == 27) // escape
			{
				this.timer.stop();
				this.capturing = false;
				this.moveX = this.moveY = 0;
				this.map.resetPosition();
				Drawing.Window.setCursor("auto", document.body);
			}
		}
		else
		{
			if (keyCode == 38) // up
				this.moveY -= 100;
			else if (keyCode == 40) // down
				this.moveY += 100;
			else if (keyCode == 37) // left
				this.moveX -= 100;
			else if (keyCode == 39) // right
				this.moveX += 100;
			else if (this._onkeydown) // pass back to the original handler
				return this._onkeydown(e);
			else return;
			
			this.timer.delay = this.keyboardDelay;
			this.timer.ontimer = function()
			{
				Tools.ToolBox.current.pan(-Tools.ToolBox.current.moveX, -Tools.ToolBox.current.moveY);
				Tools.ToolBox.current.moveX = Tools.ToolBox.current.moveY = 0;
				Drawing.Window.setCursor("auto", null);
			};
			this.timer.start();
		}
	},
	
	// pan the map
	pan: function(x, y)
	{
		this.map.pan(x, y, true);
	}
});

////////////////////////////////////////////////////////////////////////////////////////////

Tools.ZoomTool = Class.inherit(Tools.ToolBase, 
{
	initialize: function()
	{
		this.base("Zoom");
		
		this.mode = Mapping.ZoomOptions.ZoomIn;
		this.rectangle = null;
		this.startPoint = new Mapping.IntegerPoint();
		this.dynamic = true;
		this.timer = new Core.Timer();
		this.onzoom = null;
		
		Tools.ToolBox.add(this);
	},
	
	// start the tool for the specified map
	start: function(map)
	{
		if (this.running)
			return false;
		
		this.rectangle = new Drawing.Rectangle();
		this.rectangle.parent = map.container;
		this.rectangle.redraw = false;
		this.rectangle.color = Drawing.Colors.DarkGray;
		this.rectangle.backColor = Drawing.Colors.DarkGray;
		this.rectangle.opacity = 0.2;
		this.rectangle.lineStyle = Drawing.LineStyle.Dotted();
		this.rectangle.lineWidth = 0.75;
		
		this._onmousedown = map.image.onmousedown;
		this._onmouseup = document.onmouseup;
		this._onmousemove = document.onmousemove;
		map.image.onmousedown = this.onmousedown.bindAsEventListener(this);
		document.onmouseup = this.onmouseup.bindAsEventListener(this);
		document.onmousemove = this.onmousemove.bindAsEventListener(this);
		
		if (map.toolSettings.allowKeyboardZoom)
		{
			this._onkeydown = document.onkeydown;
			document.onkeydown = this.onkeydown.bindAsEventListener(this);
		}
		
		Drawing.Window.setCursor("crosshair", map.image);
		map.showInformation("Click and drag to zoom in on an area of the map.  Hold down SHIFT to zoom out", this.id);
		
		return this.activate(map);
	},
	
	// stop the tool
	stop: function()
	{
		this.startPoint = new Mapping.IntegerPoint();
		
		if (this.rectangle)
		{
			this.rectangle.remove();
			this.rectangle = null;
		}
		
		Drawing.Window.setCursor("auto", this.map.image);
		this.map.hideInformation(this.id);
		
		this.map.image.onmousedown = this._onmousedown;
		document.onmouseup = this._onmouseup;
		document.onmousemove = this._onmousemove;
		
		if (this.map.toolSettings.allowKeyboardZoom)
			document.onkeydown = this._onkeydown;
		
		this.deactivate();
	},
	
	// onmousedown
	onmousedown: function(e)
	{
		this.capturing = true;
		this.onevent(e);
		this.startPoint = new Mapping.IntegerPoint(this.map.mouseX(), this.map.mouseY());
	},
	
	// onmousemove
	onmousemove: function(e)
	{
		if (!this.running || !this.capturing)
			return;
		
		this.onevent(e);
		
		var left = this.startPoint.X;
		var top = this.startPoint.Y;
		var right = this.map.mouseX();
		var bottom = this.map.mouseY();
		
		// clip
		if (right < left)
		{
			var tmp = right;
			right = left;
			left = tmp;
		}
		
		if (bottom < top)
		{
			var tmp = bottom;
			bottom = top;
			top = tmp;
		}
		
		if (left < 0) left = 0;
		if (top < 0) top = 0;
		if (right > this.map.width) right = this.map.width;
		if (bottom > this.map.height) bottom = this.map.height;
		
		Core.Debug.write("Zoom: " + left + ", " + top + ", " + right + ", " + bottom);
		
		if (this.rectangle.left != left || this.rectangle.top != top ||
			this.rectangle.right != right || this.rectangle.bottom != bottom)
		{
			this.rectangle.move(left, top, right, bottom);
			this.rectangle.update(false);
		}
	},
	
	// onmouseup
	onmouseup: function(e)
	{
		if (!this.running || !this.capturing)
			return;
		
		this.onevent(e);
		var e = Core.Utility.lastEvent;
		
		if (this.dynamic)
		{
			if (e.shiftKey)
				this.mode = Mapping.ZoomOptions.ZoomOut;
			else
				this.mode = Mapping.ZoomOptions.ZoomIn;
		}
		
		if (Core.Utility.numbersAreClose(this.startPoint.X, this.map.mouseX(), 5) || Core.Utility.numbersAreClose(this.startPoint.Y, this.map.mouseY(), 5))
			this.zoomPoint(2, this.startPoint);
		else
			this.zoomRectangle(this.startPoint.X, this.startPoint.Y, this.map.mouseX(), this.map.mouseY());
		
		this.rectangle.hide();
		this.capturing = false;
	},
	
	// onkeydown
	onkeydown: function(e)
	{
		if (!this.running || !this.map.toolSettings.allowKeyboardZoom)
			return;
		
		this.onevent(e);
		var e = Core.Utility.lastEvent;
		
		var keyCode = e.which ? e.which : (e.keyCode ? e.keyCode : (e.charCode ? e.charCode : 0));
		
		if (this.capturing)
		{
			if (keyCode == 27) // escape
			{
				this.capturing = false;
				this.rectangle.hide();
			}
		}
		else
		{
			var oldMode = this.mode;
			
			if (keyCode == 107 || keyCode == 187) // in
				this.mode = Mapping.ZoomOptions.ZoomIn;
			else if (keyCode == 109 || keyCode == 109) // out
				this.mode = Mapping.ZoomOptions.ZoomOut;
			else if (this._onkeydown) // pass back to the original handler
				return this._onkeydown(e);
			else return;
			
			this.zoomPoint(2, Math.ceil(this.map.width / 2), Math.ceil(this.map.height / 2));
			
			this.mode = oldMode;
		}
	},
	
	// zoom on a point
	zoomPoint: function(factor, screenPoint)
	{
		if (this.onzoom) this.onzoom(this.mode);
		this.map.zoomPoint(this.mode, factor, screenPoint, true);
	},
	
	// zoom to a rectangle
	zoomRectangle: function(left, top, right, bottom)
	{
		if (this.onzoom) this.onzoom(this.mode);
		this.map.zoomRectangle(this.mode, left, top, right, bottom, true);
	}
});

////////////////////////////////////////////////////////////////////////////////////////////

Tools.CenterTool = Class.inherit(Tools.ToolBase, 
{
	initialize: function()
	{
		this.base("Center");
		
		Tools.ToolBox.add(this);
	},
	
	// start the tool for the specified map
	start: function(map)
	{
		if (this.running)
			return false;
		
		this._onmousedown = map.image.onmousedown;
		map.image.onmousedown = this.onmousedown.bindAsEventListener(this);
		
		Drawing.Window.setCursor("crosshair", map.image);
		map.showInformation("Click the mouse on the map to re-center the view", this.id);
		
		return this.activate(map);
	},
	
	// stop the tool
	stop: function()
	{
		Drawing.Window.setCursor("auto", this.map.image);
		this.map.hideInformation(this.id);
		
		this.map.image.onmousedown = this._onmousedown;
		this.deactivate();
	},
	
	onmousedown: function(e)
	{
		if (!this.running)
			return;
		
		this.onevent(e);
		
		var point = new Mapping.IntegerPoint(this.map.mouseX(), this.map.mouseY());
		
		Core.Debug.write("Center: " + point);
		
		this.map.center(point, true);
	}
});

////////////////////////////////////////////////////////////////////////////////////////////

Tools.SelectionTool = Class.inherit(Tools.ToolBase, 
{
	initialize: function()
	{
		this.base("Selection");
		
		this.onfeatureselect = null;
		this.onfailedselect = null;
		this.tolerance = 20;
		this._useTolerance = false;

		Tools.ToolBox.add(this);
	},
	
	// start the tool for the specified map
	start: function(map)
	{
		if (this.running)
			return false;
		
		Drawing.Window.setCursor("pointer", map.image);
		this._onmousedown = map.image.onmousedown;
		map.image.onmousedown = this.onmousedown.bindAsEventListener(this);
		this._onmousemove = map.image.onmousemove;
		map.image.onmousemove = this.onmousemove.bindAsEventListener(this);
		this._onmousewheel = map.image.onmousewheel;
		map.image.onmousewheel = this.onmousewheel.bindAsEventListener(this);
		
		if (map.toolSettings.allowMultipleSelections)
			map.showInformation("Click on an item to select it.  CTRL adds to and SHIFT removes from selection", this.id);
		else
			map.showInformation("Click on an item to select it.", this.id);
		
		this.circle = new Drawing.Circle(200, 200, this.tolerance);
		this.circle.parent = map.container;
		this.circle.redraw = false;
		this.circle.backColor = Drawing.Colors.DarkGray;
		this.circle.opacity = 0.2;
		this.circle.lineStyle = Drawing.LineStyle.None();
		this.circle.update(false);
		this.circle.hide();
		
		if (this.circle._control)
		{
			this.circle._control.onmousedown = this.onmousedown.bindAsEventListener(this);
			this.circle._control.onmousemove = this.onmousemove.bindAsEventListener(this);
			this.circle._control.onmousewheel = this.onmousewheel.bindAsEventListener(this);
			Drawing.Window.setCursor("pointer", this.circle._control);
		}
		
		return this.activate(map);
	},
	
	// stop the tool
	stop: function()
	{
		this.map.hideInformation(this.id);
		
		if (this.circle)
		{
			this.circle.remove();
			this.circle = null;
		}
		
		this.map.image.onmousemove = this._onmousemove;
		this.map.image.onmousedown = this._onmousedown;
		this.map.image.onmousewheel = this._onmousewheel;
		
		Drawing.Window.setCursor("auto", this.map.image);
		this.deactivate();
	},
	
	// onmousemove
	onmousemove: function(e)
	{
		if (!this.running)
			return;
		
		this.onevent(e);
		
		if (this._useTolerance)
		{
			this.circle.radius = this.tolerance;
			this.circle.positionAt(this.map.mouseX(), this.map.mouseY());
			this.circle.update(false);
		}
	},
	
	// mouse wheel event (IE only)
	onmousewheel: function(e)
	{
		if (!e) var e = window.event;
		if (!this._useTolerance || !e.wheelDelta) return;
		
		var delta = 120;
		var change = Math.ceil(Math.min(e.wheelDelta / delta));
		var values = new Array(0,1,2,3,4,5,6,10,15,20,25,30,35,40,50,75,100,200,300);
		var index = -1;
		
		for (var i = 0; i < values.length; i++)
		{
			if (values[i] == this.tolerance)
			{
				index = i;
				break;
			}
			else if (i + 1 < values.length && 
				values[i] < this.tolerance && values[i + 1] > this.tolerance)
			{
				index = i;
				break;
			}
		}
		
		if (index < 0)
			index = values.length;
		
		index += change;
		
		
		if (index < 0)
			index = 0;
		else if (index > values.length - 1)
			index = values.length - 1;
		
		this.tolerance = values[index];
	},
	
	// onmousedown
	onmousedown: function(e)
	{
		if (!this.running)
			return;
		
		this.onevent(e);
		var e = Core.Utility.lastEvent;
		var mode = Mapping.SelectionType.Replace;
		var point = new Mapping.IntegerPoint(this.map.mouseX(), this.map.mouseY());
		
		if (this.map.toolSettings.allowMultipleSelections)
		{
			if (e.ctrlKey)	
				mode = Mapping.SelectionType.AddTo;
			else if (e.shiftKey)
				mode = Mapping.SelectionType.RemoveFrom;
		}
		
		if (this._useTolerance)
			var features = this.map.selectPointFeatures(point, mode, this.tolerance, true);
		else
			var features = this.map.selectPointFeatures(point, mode, true);
		//alert(AjaxPro.toJSON(features));
		if (this.onfeatureselect && features)
			this.onfeatureselect(this.map, features);
		else if (this.onfailedselect && features == null)
			this.onfailedselect(this.map);
		
		Core.Debug.write("Selection: " + point + " - " + (e.ctrlKey ? "add" : (e.shiftKey ? "remove" : "replace")));
	}
});

////////////////////////////////////////////////////////////////////////////////////////////
Tools.InfoTool = Class.inherit(Tools.ToolBase,
{
    initialize: function() {
        this.base("Info");

        this.onselect = null;
        this.tolerance = null; //allow pixel tolerance to be set for info tool. 

        Tools.ToolBox.add(this);
    },

    // start the tool for the specified map
    start: function(map) {
        if (this.running)
            return false;

        this._onmousedown = map.image.onmousedown;
        map.image.onmousedown = this.onmousedown.bindAsEventListener(this);

        Drawing.Window.setCursor("help", map.image);
        map.showInformation("Click on an item to display its details.", this.id);

        return this.activate(map);
    },

    // stop the tool
    stop: function() {
        this.map.hideInformation(this.id);

        Drawing.Window.setCursor("auto", this.map.image);
        this.map.image.onmousedown = this._onmousedown;
        this.deactivate();
    },

    // onmousedown
    onmousedown: function(e) {
        if (!this.running)
            return;

        this.onevent(e);
        var e = Core.Utility.lastEvent;
        var point = new Mapping.IntegerPoint(this.map.mouseX(), this.map.mouseY());
        var features = this.map.searchPoint(point, this.tolerance);

        if (this.onselect != null)
            this.onselect(features);
        else if (features) {
            var feature = features[0];
            var msg = "Layer = " + feature.Layer + "\n";

            for (j = 0; j < feature.Attributes.length; j++)
                msg += feature.Attributes[j].Name + " = " + feature.Attributes[j].Value + "\n";

            alert(msg);
        }
        else
            Core.Debug.write("No features found at (" + point + ")");
    }
});

////////////////////////////////////////////////////////////////////////////////////////////

Tools.CoordinateTool = Class.inherit(Tools.ToolBase, 
{
	initialize: function()
	{
		this.base("Coordinate");
		this.onselect = null;
		
		Tools.ToolBox.add(this);
	},
	
	// start the tool for the specified map
	start: function(map)
	{
		if (this.running)
			return false;
		
		this._onmousedown = map.image.onmousedown;
		map.image.onmousedown = this.onmousedown.bindAsEventListener(this);
		
		Drawing.Window.setCursor("crosshair", map.image);
		map.showInformation("Click on the map to show the coordinates.", this.id);
		
		return this.activate(map);
	},
	
	// stop the tool
	stop: function()
	{
		Drawing.Window.setCursor("auto", this.map.image);
		this.map.hideInformation(this.id);
		
		this.map.image.onmousedown = this._onmousedown;
		this.deactivate();
	},
	
	// onmousedown
	onmousedown: function(e)
	{
		if (!this.running)
			return;
		
		this.onevent(e);
		var e = Core.Utility.lastEvent;
		
		var screenPoint = new Mapping.IntegerPoint(this.map.mouseX(), this.map.mouseY());
		var mapPoint = this.map.convertScreenToMapCoordinates(screenPoint);
		
		if (this.onselect)
			this.onselect(screenPoint, mapPoint);
		else
		{
			Core.Debug.write("Coordinates at (" + screenPoint + ") is (" + mapPoint + ")");
			this.map.showInformation("Coordinate at (" + screenPoint + ") is (" + mapPoint + ")", this.id);
		}
	}
});

////////////////////////////////////////////////////////////////////////////////////////////

Tools.DrawTextTool = Class.inherit(Tools.ToolBase, 
{
	initialize: function()
	{
		this.base("DrawText");
		this._display = null;
		
		Tools.ToolBox.add(this);
	},
	
	// start the tool for the specified map
	start: function(map)
	{
		if (this.running)
			return false;
		
		this.text = "";
		this.startPoint = new Mapping.IntegerPoint();
		
		this._display = new Drawing.Text();
		this._display.redraw = false;
		this._display.nowrap = true;
		
		this._onmousedown = map.image.onmousedown;
		map.image.onmousedown = this.onmousedown.bindAsEventListener(this);
		
		Drawing.Window.setCursor("text", map.image);
		map.showInformation("Click on the map in the location to insert text", this.id);
		
		return this.activate(map);
	},
	
	// stop the tool
	stop: function()
	{
		Drawing.Window.setCursor("auto", this.map.image);
		
		if (this._display)
		{
			this._display.remove();
			this._display = null;
		}
		
		this.capturing = false;
		this.map.hideInformation(this.id);
		
		this.map.image.onmousedown = this._onmousedown;
		this.deactivate();
	},
	
	endCapture: function()
	{
		if (!this.running || !this.capturing)
			return;
		
		if (!this.text || this.text.length == 0)
			Core.Debug.write("DrawText cancelled");
		else
		{
			this.map.drawTextOptions(this.startPoint, this.text, this.map.drawingSettings.font.size, 
				this.map.drawingSettings.color, this.map.drawingSettings.backgroundColor, this.map.drawingSettings.haloColor,
				this.map.drawingSettings.font.name, this.map.drawingSettings.font.bold, this.map.drawingSettings.font.italics, 
				this.map.drawingSettings.font.underline, true);
			
			Core.Debug.write("DrawText: " + this.text + ", " + this.startPoint);
			this.text = "";
		}
		
		this.map.showInformation("Click on the map in the location to insert text", this.id);
		
		this._display.text = this.text;
		this._display.hide();
		this.capturing = false;
		document.onkeyup = this._onkeyup;
	},
	
	// onmousedown
	onmousedown: function(e)
	{
		if (!this.running)
			return;
		
		this.onevent(e);
		
		this._onkeyup = document.onkeyup;
		document.onkeyup = this.onkeyup.bindAsEventListener(this);
		
		this.capturing = true;
		this.startPoint = new Mapping.IntegerPoint(this.map.mouseX(), this.map.mouseY());
		
		this._display.positionAt(this.map.left + this.startPoint.X, this.map.top + this.startPoint.Y);
		
		this._display.font = this.map.drawingSettings.font;
		this._display.color = this.map.drawingSettings.color;
		this._display.backColor = this.map.drawingSettings.backgroundColor;
		this._display.haloColor = this.map.drawingSettings.haloColor;
		
		this._display.update(true);
		
		this.map.showInformation("Enter the text to insert.  You can change the location by clicking the mouse", this.id);
	},
	
	// onkeyup
	onkeyup: function(e)
	{
		if (!this.running || !this.capturing)
			return;
		
		this.onevent(e);
		var e = Core.Utility.lastEvent;
		
		var keyCode = e.which ? e.which : (e.keyCode ? e.keyCode : (e.charCode ? e.charCode : 0));
		
		if (keyCode == 13) // enter
		{
			this.endCapture();
			return;
		}
		else if (keyCode == 27) // escape
		{
			this.text = "";
			this.endCapture();
			return;
		}
		else if ((keyCode == 8 || keyCode == 46) && this.text.length > 0) // backspace / delete
			this.text = this.text.substring(0, this.text.length - 1);
		else
			this.text += Core.Utility.getInputChar();
		
		Core.Debug.write("Captured: " + this.text);
		
		if (this._display)
		{
			this._display.text = this.text;
			this._display.update(true);
		}
	}
});

////////////////////////////////////////////////////////////////////////////////////////////

Tools.DrawSymbolTool = Class.inherit(Tools.ToolBase, 
{
	initialize: function()
	{
		this.base("DrawSymbol");
		this.ondraw = null;
		this.onpredraw = null;
		
		Tools.ToolBox.add(this);
	},
	
	// start the tool for the specified map
	start: function(map)
	{
		if (this.running)
			return false;
		
		this._onmousedown = map.image.onmousedown;
		map.image.onmousedown = this.onmousedown.bindAsEventListener(this);
		
		Drawing.Window.setCursor("crosshair", map.image);
		map.showInformation("Click on the map to insert a new symbol", this.id);
		
		return this.activate(map);
	},
	
	// stop the tool
	stop: function()
	{
		Drawing.Window.setCursor("auto", this.map.image);
		this.map.hideInformation(this.id);
		
		this.map.image.onmousedown = this._onmousedown;
		this.deactivate();
	},
	
	// onmousedown
	onmousedown: function(e)
	{
		if (!this.running)
			return;
		
		this.onevent(e);
		if (this.onpredraw)
		    this.onpredraw();
		var point = new Mapping.IntegerPoint(this.map.mouseX(), this.map.mouseY());
		var id = null;
		if (this.map.drawingSettings.symbol == Mapping.SymbolType.Bitmap)
		{
		    id = this.map.drawBitmapSymbol(point, this.map.drawingSettings.bitmapName, this.map.drawingSettings.size,
		 	    this.map.drawingSettings.color, this.map.drawingSettings.backgroundColor, this.map.drawingSettings.haloColor, true);
   
		}
		else
		{
		    id = this.map.drawSymbol(point, this.map.drawingSettings.symbol,		
			        this.map.drawingSettings.size, this.map.drawingSettings.color, this.map.drawingSettings.backgroundColor, 
			        this.map.drawingSettings.haloColor, true)
		}
		if (this.ondraw)
		    this.ondraw(id, point);
		
		Core.Debug.write("DrawPoint: " + this.map.drawingSettings.symbol + " at " + point);
	}
});




