/////		 Last Update @ 2004-09-17			  /////
/////		 Version: 5.0.2.6707				  /////
///////////////////////////////////////////////////////
//////   SuperMap IS WebControl Client JavaScript /////
//////      For NetScape and Mozilla browser      /////
///////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////////////////
// Globals
var color='black';

//Get map image object
function SMISGetMap(mapId)
{
	var _map = document.getElementById(mapId +"_MVIMAGE");
	return _map;
}

// Action
function SMISActionStart(mapID,action)
{
	var _map = SMISGetMap(mapID,action);
	eval(mapID + "_SMISMapActionStart(_map,action)");
}

function SMISMapActionStop(map)
{
	map.onmousedown = null;
	map.onmousemove = null;
	map.onmouseup = null;
	map.onclick = null;
	map.ondblclick = null;
	map.style.cursor = "";
}


//***************************** Drawing ************************************
////////////////////////
// DHTML related methods
function SMISmkDiv(object, x, y, w, h)
{
	x = x - object.left;
	y = y - object.top;
	var divObj = SMISAddElement("DIV", "");
	divObj.style.position = 'absolute';
	divObj.style.left = x + 'px'; 
	divObj.style.top = y + 'px'; 
	divObj.style.width = w + 'px'; 
	divObj.style.height = h + 'px';
	divObj.style.clip = 'rect(0,'+w+'px,'+h+'px,0)';
	divObj.style.overflow = 'hidden';
	divObj.style.backgroundColor = color;
	object.appendChild(divObj);
}

function SMISmkOvQds(object,cx, cy, xl, xr, yt, yb, w, h)
{
	this.SMISmkDiv(object,xr+cx, yt+cy, w, h);
	this.SMISmkDiv(object,xr+cx, yb+cy, w, h);
	this.SMISmkDiv(object,xl+cx, yb+cy, w, h);
	this.SMISmkDiv(object,xl+cx, yt+cy, w, h);
}

function SMISmkLin(object, 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)
			{
				SMISmkDiv(object, ox, y, x-ox, 1);
				y += yIncr;
				p += pru;
				ox = x;
			}
			else p += pr;
		}
		SMISmkDiv(object, 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)
				{
					SMISmkDiv(object, x++, y, 1, oy-y);
					y += yIncr;
					p += pru;
					oy = y;
				}
				else
				{
					y += yIncr;
					p += pr;
				}
			}
			SMISmkDiv(object, x2, y2, 1, oy-y2);
		}
		else
		{
			while ((dy--) > 0)
			{
				y += yIncr;
				if (p > 0)
				{
					SMISmkDiv(object, x++, oy, 1, y-oy);
					p += pru;
					oy = y;
				}
				else p += pr;
			}
			SMISmkDiv(object, x2, oy, 1, y2-oy);
		}
	}
}

function SMISmkRect(object, x, y, w, h)
{
	var stroke = 1;
	SMISmkDiv(object, x, y, w, stroke);
	SMISmkDiv(object, x+w, y, stroke, h);
	SMISmkDiv(object, x, y+h, w+stroke, stroke);
	SMISmkDiv(object, x, y+stroke, stroke, h-stroke);
}

function SMISmkEllipse(object, 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)+0x3);
			tt += (bb<<1)*(++x);
		}
		else if (tt < 0)
		{
			st += bb*((x<<1)+0x3) - (aa<<1)*(y-1);
			tt += (bb<<1)*(++x) - aa*(((y--)<<1)-0x3);
			w = x-ox;
			h = oy-y;
			if (w&0x2 && h&0x2)
			{
				SMISmkOvQds(object,cx, cy, -x+0x2, ox+wod, -oy, oy-1+hod, 1, 1);
				SMISmkOvQds(object,cx, cy, -x+1, x-1+wod, -y-1, y+hod, 1, 1);
			}
			else SMISmkOvQds(object,cx, cy, -x+1, ox+wod, -oy, oy-h+hod, w, h);
			ox = x;
			oy = y;
		}
		else
		{
			tt -= aa*((y<<1)-0x3);
			st -= (aa<<1)*(--y);
		}
	}
	SMISmkDiv(object,cx-a, cy-oy, a-ox+1, (oy<<1)+hod);
	SMISmkDiv(object,cx+ox+wod, cy-oy, a-ox+1, (oy<<1)+hod);
}

function SMISmkPolyline(object, x, y)
{
	var i = x.length-1; 
	while (i >= 0) {
		SMISmkLin(object, x[i], y[i], x[--i], y[i]);
	}
}

function SMISUpdateLine(map, currentPoint)
{
	// Clip the current point based on the size of the image:
	currentPoint.x = Math.max(map.origin.x, Math.min(currentPoint.x, map.origin.x + map.offsetWidth+2));
	currentPoint.y = Math.max(map.origin.y, Math.min(currentPoint.y, map.origin.y + map.offsetHeight+2));
	
	// Set the starting and ending points
	line = document.GetElementById("SMISEntity");
	line.innerHTML = '';
	var startPoint = map.GetPoint(0);
	SMISmkLin(line, startPoint.x, startPoint.y, currentPoint.x, currentPoint.y);
}

function SMISUpdateRectangle(map, startPoint, currentPoint)
{
	var rect = document.getElementById("SMISEntity");
	if(!rect)
	{	
		// TODO Should we expose line styles at the tool level???
		var rect = SMISAddElement("DIV", "RubberRect");
		rect.style.position = 'absolute';
		rect.style.visibility = 'visible';
		rect.id = "SMISEntity";
		
		
		// Set the rect style to the map parent's z-index:
		rect.style.zIndex = map.parentNode.style.zIndex + 200;
		
		// Add the rect to the document body:
		document.body.appendChild(rect);
		rect.style.left = rect.left = startPoint.x;
		rect.style.top = rect.top = startPoint.y;
		
		// Add event handlers for the element
		rect.onmousedown = SMISRectOnMouseDown;
		rect.onmousemove = SMISRectOnMouseMove;
		rect.onmouseup = SMISOnMouseUp;

		rect.map = map;
	}
	
	// Convert the start and current points (which are offset by the map) to absolute
	// positions:
	rect.innerHTML = '';
	//startPoint.x += map.origin.x;
	//startPoint.y += map.origin.y;
	//currentPoint.x += map.origin.x;
	//currentPoint.y += map.origin.y;
	

	// Clip the current point based on the size of the image:
	currentPoint.x = Math.max(map.origin.x, Math.min(currentPoint.x, map.origin.x + map.offsetWidth+2));
	currentPoint.y = Math.max(map.origin.y, Math.min(currentPoint.y, map.origin.y + map.offsetHeight+2));
	
	// Set the rect position based on the adjusted start and current points:
	SMISmkRect(rect, Math.min(startPoint.x, currentPoint.x), Math.min(startPoint.y, currentPoint.y),
					 Math.abs(currentPoint.x - startPoint.x), Math.abs(currentPoint.y - startPoint.y));
}

function SMISRemoveRectangle(map)
{
	var rect = document.getElementById("SMISEntity");
	if(rect)
	{
		document.body.removeChild(rect);
	}
}

function SMISUpdateCircle(map, startPoint, currentPoint)
{
	// TODO Try/catch

	// If a circle VML hasn't been created:
	var circle = document.getElementById("SMISEntity");
	if(!circle)
	{	
		// TODO Should we expose line styles at the tool level???
		// Create a vml circle with absolute positioning:
		circle = SMISAddElement("DIV", "RubberCir");
		circle.style.position = "absolute";
		circle.style.visibility = 'visible';
		circle.id = "SMISEntity";
		
		// Set the rect style to the map parent's z-index:
		circle.style.zIndex = map.parentNode.style.zIndex + 200;
		
		// Add the rect to the document body:
		document.body.appendChild(circle);
		
		// Add event handlers for the element
		circle.onmousedown = SMISOnMouseDown;
		circle.onmousemove = SMISCircleOnMouseMove;
		circle.onmouseup = SMISCircleOnMouseUp;
		document.onmousemove = SMISCircleOnMouseMove;
		document.onmouseup = SMISCircleOnMouseUp;
		
		circle.map = map;
		document.map = map;
	}

	circle.innerHTML = '';

	// Clip the current point based on the size of the image:
	//currentPoint.x = Math.max(map.origin.x, Math.min(currentPoint.x, map.origin.x + map.offsetWidth+2));
	//currentPoint.y = Math.max(map.origin.y, Math.min(currentPoint.y, map.origin.y + map.offsetHeight+2));

	// Radius is the distance between the center and the current point
	var radius = Math.sqrt(Math.pow((currentPoint.x - startPoint.x), 2) + Math.pow((currentPoint.y - startPoint.y), 2))

	// The left and top are the center minus the radius
	circle.style.left = circle.left = startPoint.x - radius;
	circle.style.top = circle.top = startPoint.y - radius;
	
	// The width and height are the same as the diameter
	circle.style.width = 2*radius;
	circle.style.height =  circle.style.width;
	
	// Check to see if circle goes out of bounds, and if so, set the clipping 
	// parameters
	
	var clipTop, clipRight, clipBottom, clipLeft;
	currentLeft = parseInt(circle.style.left);
	currentTop = parseInt(circle.style.top);
	currentRight = currentLeft + parseInt(circle.style.width);
	currentBottom = currentTop + parseInt(circle.style.height);
		
	if ( currentTop > map.origin.y )
		clipTop = 0;
	else
		clipTop = map.origin.y - currentTop;
			
	if (currentRight > (map.origin.x + map.width)) 
		clipRight = (map.origin.x + map.width) - currentLeft;
	else 
		clipRight = currentRight;
		
	if (currentBottom > (map.origin.y + map.height)) 
		clipBottom = (map.origin.y + map.height) - currentTop;
	else 
		clipBottom = currentBottom;
			
	if (currentLeft > map.origin.x) 
		clipLeft = 0;
	else 
		clipLeft = map.origin.x - currentLeft;
	
	circle.style.clip = 'rect(' + clipTop + ' ' +  clipRight + ' ' + clipBottom + ' ' + clipLeft +')';
	SMISmkEllipse(circle, startPoint.x - radius, startPoint.y - radius, radius*2, radius*2);
}

function SMISUpdatePolygon(map, currentPoint, doPolygon)
{
	// Clip the current point based on the size of the image:
	currentPoint.x = Math.max(map.origin.x, Math.min(currentPoint.x, map.origin.x + map.offsetWidth+2));
	currentPoint.y = Math.max(map.origin.y, Math.min(currentPoint.y, map.origin.y + map.offsetHeight+2));

	// Now set the polylines points collection so that it draws the segments
	// it contains all the previously clicked points + current point (which is moving)
	// + the first point to complete the polygon
	var line = document.getElementById("SMISEntity");

	var tempX = new Array();
	var tempY = new Array();
	for (i=0; i<map.PointsParam.Points.length; i++) {
		var pt = map.PointsParam.GetPoint(i);
		tempX[i] = pt.x;
		tempY[i] = pt.y;
	}
	
	tempX[tempX.length]  = currentPoint.x;
	tempY[tempY.length]  = currentPoint.y;
	if (doPolygon) {
		var firstPoint = map.PointsParam.GetPoint(0);
		tempX[tempX.length]  = firstPoint.x;
		tempY[tempY.length]  = firstPoint.y;
	}	
	
	line.innerHTML = '';
	SMISmkPolyline(line, tempX, tempY);
}

// Method to pan the image and clip if goes out of bounds
function SMISPanImage (map, startPoint, currentPoint)
{
	var clipTop, clipRight, clipBottom, clipLeft;
	var currentLeft, currentTop, currentRight, currentBottom;
	
	// Calculate absolute current coordinates of the image
	currentLeft = map.origin.x + (currentPoint.x - startPoint.x);
	currentTop = map.origin.y + (currentPoint.y - startPoint.y);
	currentRight = currentLeft + map.width;
	currentBottom = currentTop + map.height;
		
	// Check to see if image goes out of bounds, and if so, set the clipping 
	// parameters
	if ( currentTop > map.origin.y )
		clipTop = 0;
	else
		clipTop = map.origin.y - currentTop;
			
	if (currentRight > (map.origin.x + map.width)) 
		clipRight = (map.origin.x + map.width) - currentLeft - map.BorderWidth;
	else 
		clipRight = currentRight - currentLeft - map.BorderWidth;
		
	if (currentBottom > (map.origin.y + map.height)) 
		clipBottom = (map.origin.y + map.height) - currentTop - map.BorderWidth;
	else 
		clipBottom = currentBottom - currentTop - map.BorderWidth;
			
	if (currentLeft > map.origin.x) 
		clipLeft = 0;
	else 
		clipLeft = map.origin.x - currentLeft;

	// Set the map image's style parameters to actually move the image	
	map.style.position = "absolute";
	map.style.left = currentLeft - map.origin.x; 
	map.style.top = currentTop - map.origin.y;	
	map.style.clip = 'rect(' + clipTop + ' ' +  clipRight + ' ' + clipBottom + ' ' + clipLeft +')';
}

//////////////////////////////////////////////////////////////////////////////////////////
// Common methods:

function SMISGetMapInternal(object)
{
	var map = null;
	if (object.map) {
		map = object.map;
	} else {
		map = object;
	}
	
	return map;
}

//////////////////////////////////////////////////////////////////////////////////////////
// Point Data object methods

// Append the point to points collection
function SMISAddPoint(x, y)
{
	this.Points[this.Points.length] = new SMISPoint(x,y);
}

// Get point from points collection
function SMISGetPoint(indx)
{
	if (this.Points[indx] != null) {
		return new SMISPoint(this.Points[indx].x, this.Points[indx].y);
	} else {
		return null;
	}
}

// Return the string representation of point collection, The format is "numpts,x y,x y,x y...,x y"
function SMISGetPointsString(offset)
{
	var pointString = "" + this.Points.length + ",";
	for (i = 0; i < this.Points.length; i++) {
		if (i>0)
		{
			pointString += ","
		}
		if (this.Points[i].y != -99999) {
			pointString += (this.Points[i].x - offset.x) + " " + (this.Points[i].y - offset.y);	
		} else {
			pointString += (this.Points[i].x) + " " + (this.Points[i].y);	
		}
	}
	return pointString;
}

// Return the string representation of point collection, The format is "x,y x,y x,y ... x,y"
function SMISGetPointsValue(offset)
{
	var pointString = "";
	for (i = 0; i < this.Points.length; i++) {
		if (i>0)
		{
			pointString += " "
		}
		pointString += (this.Points[i].x - offset.x) + "," + (this.Points[i].y - offset.y);		
	}
	return pointString;
}

// Create hidden field containing the string representation of points collection
function SMISCreatePointsField(id)
{
	var theform = document.forms[0];
	var map = document.getElementById(id);
	var pointstring = this.GetPointsString(map.origin);
	SMISCreateHiddenField(theform, id+"_PointsParam", id+"_PointsParam", pointstring);
}

// Point data handling object
function SMISPointsParam()
{
	this.Points = new Array();
	this.AddPoint = SMISAddPoint;
	this.GetPoint = SMISGetPoint;
	this.GetPointsString = SMISGetPointsString;
	this.GetPointsValue = SMISGetPointsValue;
	this.CreatePointsField = SMISCreatePointsField;
}

//////////////////////////////////////////////////////////////////////////////////////////
// Point methods:

function SMISPoint(x, y)
{
	this.x = parseInt(x);
	this.y = parseInt(y);
}

//////////////////////////////////////////////////////////////////////////////////////////
// Tool related objects

// Tool object
function SMISMapTool()
{
	this.Name = "";
	this.Start = "";
	this.Stop = "";
}

// Tools collection belonging to map
function SMISMapTools()
{
}

//////////////////////////////////////////////////////////////////////////////////////////
// ToolControl methods:

// Toggle the activation of the tool
function SMISActivateTool(map, toolName, tool)
{
	// If we clicked on the same tool control which was active then deactivate it and set current tool to invalid one
	// Otherwise, deactivate the current tool control, and activate the other one. And set the current tool to that one.
	// and create hidden field containing the current toolname
	if (map.activeToolControl != null && map.activeToolControl.id == tool.id && map.activeToolControl.active) {
		map.activeToolControl.Deactivate(map.activeToolControl);
		SMISSetCurrentTool(map.id, "None");
		var _map = SMISGetMap(map.id);
		_map.style.cursor = null;
	} else {
		if (map.activeToolControl != null) map.activeToolControl.Deactivate(map.activeToolControl);
		map.activeToolControl = tool;
		if(map.activeToolControl != null)	{
			map.activeToolControl.Activate(tool);
		}
		
		// Create hidden field when tool is activated, to handle multiple maps and tool controls on the same page
		SMISSetCurrentTool(map.id, toolName);
		var _map =SMISGetMap(map.id);
		var theform = document.forms[0];
		SMISCreateHiddenField(theform, _map.id + "_CurrentToolName", _map.id + "_CurrentToolName", _map.MapTools.CurrentTool.Name);
		SMISCreateHiddenField(theform, _map.id + "_ToolControlParent", _map.id + "_ToolControlParent", tool.parentControl);
	} 
}

// Activate the tool by setting the image source to active image
function SMISToolActivate(tool)
{
	tool.src = tool.activeSrc;
	tool.active = true;
}

// Deactivate the tool by setting the image source to inactive image
function SMISToolDeactivate(tool)
{
	tool.src = this.inactiveSrc;
	tool.active = false;
}

function SMISOnMouseDown(evt)
{
	map = SMISGetMapInternal(this);
	map.PointsParam.AddPoint(evt.clientX+document.body.scrollLeft, evt.clientY+document.body.scrollTop);
	return false;
}

function SMISOnMouseUp(evt)
{
	
	var map = SMISGetMapInternal(this);
	map.onmousemove = null;
	if (this.map != null) this.onmousemove = null;

	var theform = document.forms[0];
	
	// Get the current point
	map.PointsParam.AddPoint(evt.clientX+document.body.scrollLeft, evt.clientY+document.body.scrollTop);
	
	// Create hidden field for current tool
	// SMISCreateHiddenField(theform, map.id + "_CurrentToolName", map.id + "_CurrentToolName", map.MapTools.CurrentTool.Name);
	
	// Create hidden field for points data
	map.PointsParam.CreatePointsField(map.id);

	SMISCreateHiddenField(theform, map.id + "_Action", map.id + "_Action", map.action);

	// Create hidden field that will store selectable layers
	// SMISCreateSelectableLayerField(map.parentNode.id);

	// Do the postback
	map.DoPostBack();
}

//////////////////////////////////////////////////////////////////////////////////////////
// ZoomInTool, RectangleSelect methods:

function SMISRectangleStart(map)
{
	if(!this.started)
	{
		// Set up the point data object
		map.PointsParam = new SMISPointsParam();
		
		// Get the absolute map position:
		map.origin = SMISGetAbsolutePosition(map);
		
		map.onmousedown = SMISRectOnMouseDown;
		map.onmouseup = SMISOnMouseUp;

		this.started = true;
		return false;
	}
}

function SMISRectOnMouseDown(evt)
{
	var map = SMISGetMapInternal(this);
	map.PointsParam = new SMISPointsParam();
	map.PointsParam.AddPoint(evt.clientX+document.body.scrollLeft, evt.clientY+document.body.scrollTop);
	map.onmousemove = SMISRectOnMouseMove;
	return false;
}

function SMISRectangleStop(map)
{
	if(this.started)
	{
		map.onmousedown = null;
		map.onmousemove = null;
		map.onmouseup = null;
		this.started = false;
	}
}

function SMISRectOnMouseMove(evt)
{
	var map = SMISGetMapInternal(this);
	var startPoint = map.PointsParam.GetPoint(0);
	if(startPoint != null)
	{
		SMISUpdateRectangle(map, startPoint, new SMISPoint(evt.clientX+document.body.scrollLeft, evt.clientY+document.body.scrollTop));
		return false;
	}
}

//////////////////////////////////////////////////////////////////////////////////////////
// ZoomOutTool, InfoTool methods:

function SMISPointStart(map)
{
	if(!this.started)
	{
		map.PointsParam = new SMISPointsParam();
		// Get the absolute map position:
		map.origin = SMISGetAbsolutePosition(map);
		
		map.onmouseup = SMISOnMouseUp;
		this.started = true;
	}
}


function SMISPointStop(map)
{
	if(this.started)
	{
		map.onmouseup = null;
		this.started = false;
	}
}

//////////////////////////////////////////////////////////////////////////////////////////
// PanTool methods:


function SMISPanStart(map)
{
	if(!this.started)
	{
		map.PointsParam = new SMISPointsParam();

		// Get the absolute map position:
		map.origin = SMISGetAbsolutePosition(map);
		
		map.onmousedown = SMISPanOnMouseDown;
		map.onmousemove = SMISPanOnMouseMove;
		map.onmouseup = SMISOnMouseUp;
		this.started = true;
	}
}

function SMISPanStop(map)
{
	if(this.started)
	{
		map.onmousedown = null;
		map.onmousemove = null;
		map.onmouseup = null;
		this.started = false;
	}
}

function SMISPanOnMouseDown(evt)
{
	map = SMISGetMapInternal(this);
	map.parentNode.style.position = 'absolute';
	map.PointsParam.AddPoint(evt.clientX+document.body.scrollLeft, evt.clientY+document.body.scrollTop);
	return false;
}

function SMISPanOnMouseMove(evt)
{
	var map = SMISGetMapInternal(this);
	if ( map.PointsParam != null )
	{
		var startPoint = map.PointsParam.GetPoint(0);
		if(startPoint != null)
		{
			SMISPanImage(map, startPoint, new SMISPoint(evt.clientX+document.body.scrollLeft, evt.clientY+document.body.scrollTop));
			return false;
		}
	}
}

//////////////////////////////////////////////////////////////////////////////////////////
// RadiusTool methods:

function SMISCircleStart(map)
{
	if (!this.started)
	{
		// Set up the point data object
		map.PointsParam = new SMISPointsParam();
		
		// Get the absolute map position:
		map.origin = SMISGetAbsolutePosition(map);
		
		map.onmousedown = SMISOnMouseDown;
		map.onmousemove = SMISCircleOnMouseMove;
		map.onmouseup = SMISCircleOnMouseUp;
	
		this.started = true;
	}
}

function SMISCircleStop(map)
{
	if(this.started)
	{
		map.onmousedown = null;
		map.onmousemove = null;
		map.onmouseup = null;
		this.started = false;
	}
}

function SMISCircleOnMouseMove(evt)
{
	var map = SMISGetMapInternal(this);
	var startPoint = map.PointsParam.GetPoint(0);
	if(startPoint != null)
	{
		SMISUpdateCircle(map, startPoint, new SMISPoint(evt.clientX+document.body.scrollLeft, evt.clientY+document.body.scrollTop));
		return false;
	}
}

function SMISCircleOnMouseUp(evt)
{
	var theform = document.forms[0];
	var map = SMISGetMapInternal(this);

	map.onmousemove = null;
	if (this.map != null) this.onmousemove = null;

	var endPoint = new SMISPoint(evt.clientX+document.body.scrollLeft, evt.clientY+document.body.scrollTop);
	// Get the current point
	map.PointsParam.AddPoint(endPoint.x, endPoint.y);
	
	var startPoint = map.PointsParam.GetPoint(0);

	// The startpoint is the center and radius is the distance
	// between the start point and the end point
	
	var radius = Math.sqrt(Math.pow((endPoint.x - startPoint.x), 2) +
							 Math.pow((endPoint.y - startPoint.y), 2));

	// Add radius to pointData object.  x value of xy pair will contain radius value.  y value will be set to 0;
	map.PointsParam.AddPoint(radius, -99999);

	// Create hidden field for current tool
	//SMISCreateHiddenField(theform, map.id + "_CurrentToolName", map.id + "_CurrentToolName", map.MapTools.CurrentTool.Name);
	
	// Create hidden field for points data
	map.PointsParam.CreatePointsField(map.id);
	
	// Create hidden field that will store selectable layers
	//SMISCreateSelectableLayerField(map.parentNode.id);

	// Do the postback
	map.DoPostBack();
}

//////////////////////////////////////////////////////////////////////////////////////////
// DistanceTool methods:

function SMISDistanceStart(map)
{
	if(!this.started)
	{
		map.PointsParam = new SMISPointsParam();

		// Get the absolute map position:
		map.origin = SMISGetAbsolutePosition(map);
		map.doPolygon = false;

		// Add event handlers to map		
		map.onmousemove = SMISPolygonOnMouseMove;
		map.onclick = SMISPolygonOnMouseClick;
		map.ondblclick = SMISPolygonOnDblClick;
		this.started = true;

	}
}

//////////////////////////////////////////////////////////////////////////////////////////
// PolygonSelectionTool methods:

function SMISPolygonStart(map)
{
	if(!this.started)
	{
		map.PointsParam = new SMISPointsParam();

		// Get the absolute map position:
		map.origin = SMISGetAbsolutePosition(map);
		map.doPolygon = true;

		// Add event handlers to map		
		map.onmousemove = SMISPolygonOnMouseMove;
		map.onclick = SMISPolygonOnMouseClick;
		map.ondblclick = SMISPolygonOnDblClick;
		this.started = true;

	}
}

function SMISPolygonStop(map)
{
	if(this.started)
	{
		map.onmousemove = null;
		map.onclick = null;
		map.ondblclick = null;
		this.started = false;
	}
}

function SMISPolygonOnMouseClick(evt)
{
	var theform = document.forms[0];
	var map = SMISGetMapInternal(this);
	
	// create the vml polyline element
	var line = document.getElementById("SMISEntity");
	if(!line)
	{	
		// TODO Should we expose line styles at the tool level???
		line = SMISAddElement("DIV", "RubberPolygon");
		line.style.position = "absolute";
		line.style.visibility = 'visible';
		line.id = "SMISEntity";
		
		// Set the style to the map parent's z-index:
		line.style.zIndex = map.parentNode.style.zIndex + 200;
		
		// Add to the document body:
		document.body.appendChild(line);
		
		line.activeTool = map.activeTool;
		line.map = map;
		
		// Now set the event handlers for click and dblclick for the div element
		line.onclick = SMISPolygonOnMouseClick;
		line.onmousemove = SMISPolygonOnMouseMove;
		line.ondblclick = SMISPolygonOnDblClick;
		line.map = map;
		
		line.style.left = line.left = evt.clientX+document.body.scrollLeft;
		line.style.top = line.top = evt.clientX+document.body.scrollLeft;
	}
	
	map.PointsParam.AddPoint(evt.clientX+document.body.scrollLeft, evt.clientY+document.body.scrollTop);

	return false;
}

function SMISPolygonOnMouseMove(evt)
{
	var map = SMISGetMapInternal(this);
	var line = document.getElementById("SMISEntity");
	if(line)
	{
		SMISUpdatePolygon(map, new SMISPoint(evt.clientX+document.body.scrollLeft, evt.clientY+document.body.scrollTop), map.doPolygon);
	}

	return false;

}

function SMISPolygonOnDblClick(evt)
{
	var map = SMISGetMapInternal(this);
	map.onmousemove = null;
	if (this.map != null) this.onmousemove = null;
	
	var theform = document.forms[0];

	// Create hidden field for current tool
	//SMISCreateHiddenField(theform, map.id + "_CurrentToolName", map.id + "_CurrentToolName", map.MapTools.CurrentTool.Name);
	
	// Create hidden field for points data
	map.PointsParam.CreatePointsField(map.id);
	
	// Create hidden field that will store selectable layers
	//SMISCreateSelectableLayerField(map.parentNode.id);
	
	// Do the postback
	map.DoPostBack();
}


//END DRAWING

function hideBusyFlag(mapControlID)
{
	if(mapControlID == null || typeof(mapControlID) == "undefined")
	{
		return;
	}

	var divLoading = document.getElementById(mapControlID+"_divLoading");
	if( divLoading != null && divLoading.style != null)
	{
		divLoading.style.visibility = "hidden";
		divLoading.style.zIndex = "-1";
	}
}

function showBusyFlag(mapControlID)
{
	if(mapControlID == null || typeof(mapControlID) == "undefined")
	{
		return;
	}

	var divLoading = document.getElementById(mapControlID+"_divLoading");
	if( divLoading != null && divLoading.style != null)
	{
		divLoading.style.zIndex = "999";
		divLoading.style.visibility = "visible";
	}
}

function SetMapAbsPosition(mapID)
{
	// offset 为内部元素定位所需要的相对偏移量 //
	// (EN) offset is the relative offset for locating inner element. //
	// (CH) origin 为绝对坐标 //
	// (EN) origin is absolut coordinates. //
	// origin 为绝对座标 //
	var mapControl = document.getElementById(mapID.replace("_MVIMAGE",""));
	var map = document.getElementById(mapID);

	map.origin = SMISGetAbsolutePosition(map);
	if(mapControl.style.position.toLowerCase() != "absolute")
	{
		map.offset = map.origin; 
	}
	else
	{
		map.offset = new SMISPoint(0, 0);	}
}

// for layerControl 
function CheckVisibleAll(layerControlID)
{
	//LayerControl1:LayerCount
	//LayerControl1:V0
	var layerCount = eval(document.getElementById(layerControlID + ":LayerCount").value);
	for(var i=0; i<layerCount; i++)
	{
		document.getElementById(layerControlID + ":V" + i).checked = event.srcElement.checked;
	}
}

function CheckQueryableAll(layerControlID)
{
	//LayerControl1:LayerCount
	//LayerControl1:Q0
	var layerCount = eval(document.getElementById(layerControlID + ":LayerCount").value);
	for(var i=0; i<layerCount; i++)
	{
		document.getElementById(layerControlID + ":Q" + i).checked = event.srcElement.checked;
	}
}


function SMISPrintMap(mapControlClientID, mapControlPage, printControlPage, mapUrl, imageHandlerEnabled)
{
	if( typeof(mapControlClientID)=="undefined" || mapControlClientID=="" || typeof(mapControlPage)=="undefined" || mapControlPage=="" || typeof(printControlPage)=="undefined" || printControlPage=="")
	{
		return false;
	}
	
	var printWin;
	
	if ( typeof(mapUrl)=="undefined" || mapUrl=="" )
	{
		mapUrl = document.getElementById(mapControlClientID+"_MVIMAGE").src;
	}
	var addr = document.getElementById(mapControlClientID+"_MapServer_Addr").value;
	var port = document.getElementById(mapControlClientID+"_MapServer_Port").value;

	printUrl = printControlPage + "?Addr=" + addr + "&Port=" + port + "&MapControlClientID=" + mapControlClientID + "&MapControlPage=" + mapControlPage + "&ImageHandlerEnabled=" + imageHandlerEnabled;
	printWin = window.open(printUrl, "", "resizable,toolbar,menubar,scrollbars,status" );
}


function SMISAdjustCustomDivPosition(customDivID, alignStyle)
{
//	window.status += customDivID + "," + alignStyle;
	var customDiv = document.getElementById(customDivID);
	var offsetX, offsetY;
	if(typeof(customDiv) != "undefined")
	{
		switch(alignStyle)
		{
			case "LeftTop":	
				offsetX = 0;
				offsetY = 0;
				break;
			case "LeftMiddle":
				offsetX = 0;
				offsetY = customDiv.offsetHeight / 2;
				break;
			case "LeftBottom":
				offsetX = 0;
				offsetY = customDiv.offsetHeight;
				break;
			case "CenterTop":	
				offsetX = customDiv.offsetWidth / 2;
				offsetY = 0;
				break;
			case "CenterMiddle":
				offsetX = customDiv.offsetWidth / 2;
				offsetY = customDiv.offsetHeight / 2;
				break;
			case "CenterBottom":
				offsetX = customDiv.offsetWidth / 2;
				offsetY = customDiv.offsetHeight;
				break;
			case "RightTop":	
				offsetX = customDiv.offsetWidth;
				offsetY = 0;
				break;
			case "RightMiddle":
				offsetX = customDiv.offsetWidth;
				offsetY = customDiv.offsetHeight / 2;
				break;
			case "RightBottom":
				offsetX = customDiv.offsetWidth;
				offsetY = customDiv.offsetHeight;
				break;
			default:
				offsetX = 0;
				offsetY = 0;
				break;
		}
		customDiv.style.left = SMISGetNumFromPixel(customDiv.style.left) - offsetX;
		customDiv.style.top = SMISGetNumFromPixel(customDiv.style.top) - offsetY; 
//		window.status = offsetX + "," + offsetY;
//		window.status += "customDiv.offsetWidth:" + customDiv.offsetWidth;
//		window.status += "customDiv.style.left:" + customDiv.style.left;
	}
}

function SMISRegisterToolControl(toolControlID, mapControlID)
{
	var input = document.getElementById(mapControlID + "_ToolControls");
	if(typeof(input) != "undefined" && input.value.indexOf(toolControlID+",") < 0)	// 防止重复注册。 (English -- Prevent registering repeatedly ) //
	{
		input.value += toolControlID + ",";
	}
//	window.status = input.value;
}

function SMISSwitchCurrentTool(map,action)
{
	var toolControl;
	var toolControlsID = map.id.replace("_MVIMAGE","") + "_ToolControls";
	var toolControls = document.getElementById(toolControlsID);
//	window.status += toolControls.value;
	
	if(typeof(toolControls) != "undefined" && toolControls != null)
	{
		var arrToolControls = toolControls.value.split(",");
		for(var i=0; i<arrToolControls.length; i++)
		{
			if(arrToolControls[i] == "")
			{
				continue;
			}
			
			toolControl = document.getElementById(arrToolControls[i]);
//			window.status += ";" + typeof(toolControl);
//			alert(show_props(toolControl, "ToolControl"));
//			window.status += ";" + typeof(toolControl) + "," + toolControl.Action + ", action:" + action;
			if(typeof(toolControl) == "object" && toolControl.ActiveSrc != null && toolControl.InactiveSrc != null)
			{
				if(toolControl.ActionName == action)
				{
					toolControl.src = toolControl.ActiveSrc;
//					window.status += toolControl.src + "; ";
				}
				else
				{
					toolControl.src = toolControl.InactiveSrc;
				}
			}
//			window.status += arrToolControls[i];
		}
	}
}

function show_props(obj, objName) {
   var result = "";
   for (var i in obj) {
      result += objName + "." + i + " = " + obj[i] + "\n";
   }
   return result;
} 

function SMISGetAbsolutePosition(element, tagName, pos)
{
	var _i=0, _j=0;
	var __DEBUG	= false;
	if(typeof(pos) == "undefined" || pos == null)
	{
		pos = new SMISPoint(0, 0);
	}
	
	while ( ! (element == null || element.tagName == "BODY" || element.tagName.toLowerCase() == tagName) ) //*/
	{
		_i+=1;
		
		pos.x += eval(element.offsetLeft);
		pos.y += eval(element.offsetTop);	

		var bFlag = typeof(element.style.borderLeftWidth) != "unknown";
		if(bFlag && element.style.borderLeftWidth != null && element.style.borderLeftWidth != "")
		{
			pos.x += SMISGetNumFromPixel(element.style.borderLeftWidth);
			pos.y += SMISGetNumFromPixel(element.style.borderTopWidth);

			if(__DEBUG) alert( "bFlag true & borderLeftWidth is not null. \n pos.Y = " + pos.y);
		}
				
		if(__DEBUG)	alert("current element id = " + element.id + "\n current element tagName = " + element.tagName);
		if(__DEBUG)	alert(element.offsetParent.tagName + "," + element.offsetLeft);

		element = element.offsetParent;
	}
//	if(__DEBUG)	alert("i="+_i+", j="+_j);
//	if(__DEBUG)	alert("FINAL pos.X="+pos.X);
//	if(__DEBUG)	alert("FINAL pos.Y="+pos.Y);
	return pos;
}

//The point object
function SMISPoint(x,y)
{
	this.x = parseInt(x);
	this.y = parseInt(y);
}

//Get Current Mouse Absolute Position
function SMISGetMouseAbsolutePosition()
{

	var x = event.clientX + document.body.scrollLeft;
	var y = event.clientY + document.body.scrollTop;
	return new SMISPoint(x,y);
}

//Get Current Mouse Map Relative Position
function SMISGetMouseMapRelativePosition(map)
{
	var x = event.clientX + document.body.scrollLeft - map.origin.x;
	var y = event.clientY + document.body.scrollTop - map.origin.y;
	return new SMISPoint(x,y);
}


function SMISGetNumFromPixel(str)
{
	if(typeof(str) == "undefined" || str == null || str == "")
		return 0;

	var strResult;
	strResult = str.toString();
	try{
	strResult = strResult.replace("px", "");
	strResult = strResult.replace("pt", "");
	strResult = eval(strResult);
	}catch(e){alert(e);}

	return strResult;
}


function SMISGetInnerMap(object)
{
	var _map = null;
	if (object.map) {
		_map = object.map;
	} else {
		_map = object;
	}
	return _map;
}

//Create input hidden field
function old_SMISCreateHiddenField(theform, id, name, value)
{
	var _elem = document.getElementById(id);
	if(_elem == null)
	{
		_elem = document.createElement("<input />");
		_elem.type = "hidden";
		_elem.id = id;
		_elem.name = name;
		_elem.value = value;
		theform.appendChild(_elem);
	}
	return _elem;
}

function SMISCreateHiddenField(theform, elemID, elemName, elemValue)
{
	var ua = navigator.userAgent.toLowerCase();
	var isIE = ( ua.indexOf("msie") != -1 );

	var elem = document.getElementById(elemID);
	if(elem == null)
	{
		if (isIE)
		{
			elem = document.createElement("<input />");
		} else {
			elem = SMISAddElement("INPUT", elemID);
		}
		elem.type = "hidden";
		elem.id = elemID;
		elem.name = elemName;
		theform.appendChild(elem);
	}
	elem.value = elemValue;
	return elem;
}

function SMISAddElement(element, id)
{
	var obj = document.createElement(element);
	obj.id = id;
	return(obj);
}

