﻿var tFunc = null;
var agent=navigator.userAgent.toLowerCase();
if (XMLHttpRequest == null)
{
	var XMLHttpRequest = function()
	{
		try {http_request = new ActiveXObject("Msxml2.XMLHTTP");} 
		catch (e) 
		{
			try {http_request = new ActiveXObject("Microsoft.XMLHTTP");} 
			catch (e) {}
		}
		return http_request;
	}
}
	
function FuncAdapter(pCaller, pFunc)
{
	return function(pEvent)
	{
		pFunc.call(pCaller, pEvent);
	};
}

function AttachEvent(targetObj, actEvent, actFunc, useCapture)
{
	if (targetObj.addEventListener)
	{
	    if (actEvent == "mousewheel") actEvent = "DOMMouseScroll"; // FF ㄡ
		targetObj.addEventListener(actEvent, actFunc, useCapture);		
	}
	else
	{	    
		targetObj.attachEvent("on" + actEvent, actFunc);
		if (useCapture)
			targetObj.setCapture();
	}
}

function DetachEvent(targetObj, actEvent, actFunc, useCapture)
{
	if (targetObj.removeEventListener)
	{
	    if (actEvent == "mousewheel") actEvent = "DOMMouseScroll"; // FF ㄡ
		targetObj.removeEventListener(actEvent, actFunc, useCapture);		
	}
	else
	{	
		targetObj.detachEvent("on" + actEvent, actFunc);
		if (useCapture)
			targetObj.releaseCapture();
	}
}

function MapBase(pNode, locX, locY, locWidth, locHeight, imgWidth, imgHeight)
{
//private
	var m_hPackage;
	var m_hObj;
	var m_hImages;
	
	var m_imgWidth;
	var m_imgHeight;
	var m_imgRatio;
	var m_mapLevel;
	var m_mapFixLevel;
	var m_mapMaxLevel;
	var m_RepeatX;
	var m_RepeatY;
	var m_centerX;
	var m_centerY;
	var m_MapImages;
	var m_MapImages2;
	var m_MapElements;
	var m_pMapEvent;
//constructor
	m_imgWidth = imgWidth;
	m_imgHeight = imgHeight;
	m_mapLevel = 1;
	m_mapFixLevel = true;
	m_mapMaxLevel = 10;
	m_imgRatio = 1;
	var s = Math.pow(2, m_mapLevel);
	var cw = s * m_imgWidth;
	var ch = s * m_imgHeight;
	var m_sName = "";
	
	m_RepeatX = false;
	m_RepeatY = false;
	m_centerX = 0.5;
	m_centerY = 0.5;
	m_MapImages = new Array();
	m_MapElements = new Array();
	m_pMapEvent = null;
	
	m_hPackage = pNode.ownerDocument.createElement("div");
	pNode.appendChild(m_hPackage);
	m_hPackage.style.position = "relative";
	m_hPackage.style.overflow = "hidden";
	m_hPackage.style.left = locX;
	m_hPackage.style.top = locY;
	m_hPackage.style.width = locWidth;
	m_hPackage.style.height = locHeight;
	
	m_hObj = pNode.ownerDocument.createElement("div");
	m_hPackage.appendChild(m_hObj);
	m_hObj.style.position = "relative";
	m_hObj.style.overflow = "hidden";
	m_hObj.style.left = 0;
	m_hObj.style.top = 0;
	m_hObj.style.width = "100%";
	m_hObj.style.height = "100%";
	
	m_hImages = pNode.ownerDocument.createElement("div");
	m_hObj.appendChild(m_hImages);
	m_hImages.style.position = "relative";
	m_hImages.style.overflow = "hidden";
	m_hImages.style.left = 0;
	m_hImages.style.top = 0;
	m_hImages.style.width = "100%";
	m_hImages.style.height = "100%";
	m_hImages.style.background = "lightblue";
	
	var cltWidth = parseInt(m_hImages.clientWidth);
	var cltHeight = parseInt(m_hImages.clientHeight);
	
	this.SelectMapTool = function(pMapEvent)
	{
		if (pMapEvent)
		{
			if (pMapEvent.InitMapEvent)
			{
				if (m_pMapEvent && m_pMapEvent.ExitMapEvent)
					m_pMapEvent.ExitMapEvent();	
				pMapEvent.InitMapEvent(this);
				m_pMapEvent = pMapEvent;
				return true;
			}
		}
		else if (m_pMapEvent && m_pMapEvent.ExitMapEvent)
		{
			m_pMapEvent.ExitMapEvent();	
			m_pMapEvent = null;
		}
		return false;
	}
	
	function ConfirmLevel(mapLevel)
	{
		if (mapLevel > m_mapMaxLevel)
			mapLevel = m_mapMaxLevel;
		else if (mapLevel < 0)
			mapLevel = 0;
		return mapLevel;
	}
	
//public
	this.getHObject = function() {return m_hObj;};
	this.getHPackage = function() {return m_hPackage;};
	this.getName = function() {return m_sName;};
	this.putName = function(sName) {m_sName = sName;};
	this.getClientWidth = function() {return cltWidth;};
	this.getClientHeight = function() {return cltHeight;};
	this.getImageWidth = function() {return m_imgWidth;};
	this.getImageHeight = function() {return m_imgHeight;};
	this.getRepeatX = function() {return m_RepeatX;};
	this.putRepeatX = function(repeatX) {m_RepeatX = repeatX;};
	this.getRepeatY = function() {return m_RepeatY;};
	this.putRepeatY = function(repeatY) {m_RepeatY = repeatY;};
	this.getCenterX = function() {return m_centerX;};
	this.getCenterY = function() {return m_centerY;};
	this.getMapMaxLevel = function() {return m_mapMaxLevel;};
	this.putMapMaxLevel = function(mapLevel) {m_mapMaxLevel = mapLevel;}
	this.getMapFixLevel = function() {return m_mapFixLevel;};
	this.putMapFixLevel = function(mapFixLevel) {m_mapFixLevel = mapFixLevel;}
	this.getMapLevel = function() {return m_mapLevel + Math.log(m_imgRatio) / Math.log(2);};
	this.putMapLevel = function(mapLevel)
	{
		mapLevel = ConfirmLevel(mapLevel);
			
		m_mapLevel = Math.round(mapLevel);
		this.putMapLevel2(m_mapFixLevel?m_mapLevel:mapLevel);
	};
	this.putMapLevel2 = function(mapLevel)
	{
		mapLevel = ConfirmLevel(mapLevel);
			
		m_imgRatio = Math.pow(2, mapLevel - m_mapLevel);
		s = Math.pow(2, m_mapLevel);
		cw = s * m_imgWidth * m_imgRatio;
		ch = s * m_imgHeight * m_imgRatio;
	};
	
	this.AddElement = function(pElem)
	{
		m_MapElements.push(pElem);
	}
	this.RemoveElement = function(pElem)
	{
		var i;
		var cnt = m_MapElements.length;
		for (i=0;i<cnt;i++)
		{
			if (m_MapElements[i] == pElem)
			{
				m_MapElements.splice(i, 1);
				break;
			}
		}
		if (pElem.RemoveSelf)
			pElem.RemoveSelf();
	}
	this.EmptyElements = function() 
	{
		var i;
		var cnt = m_MapElements.length;
		for (i=0;i<cnt;i++)
			if (m_MapElements[i].RemoveSelf)
				m_MapElements[i].RemoveSelf();
		m_MapElements = new Array;
	}
	
	this.getOffset = function()
	{
		var pObj = m_hImages;
		var dX = 0;
		var dY = 0;
		while (pObj)
		{
			if (pObj && pObj.style)
				pos = pObj.style.position;
			if (pos == "relative" || pos == "absolute")
			{
				dX += pObj.offsetLeft;
				dY += pObj.offsetTop;
			}	
			pObj = pObj.parentNode;
		}
		return new MapPoint(dX, dY);
	}
	
	this.MapFromClient = function(dX, dY)
	{
		pt = this.getOffset();
		pt = new MapPoint(dX - pt.X, dY - pt.Y);
		//window.status = os.X + "/" + os.Y + "/" + dX + "/" + dY;
		return this.ToMapPoint(pt.X, pt.Y);
	}
	this.ClientFromMap = function(dX, dY)
	{
		pt = this.FromMapPoint(dX, dY);
		os = this.getOffset();
		return new MapPoint(os.X + pt.X, os.Y + pt.Y);
	}
	this.ToMapPoint = function(dX, dY)
	{
		return new MapPoint((dX - cltWidth/2) / cw + m_centerX, (dY - cltHeight/2) / ch + m_centerY);
	}
	this.FromMapPoint = function(dX, dY)
	{
		return new MapPoint((dX - m_centerX) * cw + cltWidth / 2, (dY - m_centerY) * ch + cltHeight / 2);
	}
	this.ToMapDistX = function(dX) {return dX / cw;}
	this.ToMapDistY = function(dY) {return dY / ch;}
	this.FromMapDistX = function(dX) {return dX * cw;}
	this.FromMapDistY = function(dY) {return dY * ch;}
	
	this.MoveMapTo = function(centerX, centerY)
	{
		m_centerX = centerX;
		m_centerY = centerY;
	};
	
	this.AddMapImage = function(doc, dX, dY, isLoadNew)
	{
		var b = new XYPoint(m_RepeatX, m_RepeatY);
		b.X = dX;
		b.Y = dY;
		srl = b.toSerial(m_mapLevel);
		if (srl==null)
			return;
			
			
		var i;
		for (i=0 ; i<m_MapImages.length ; i++)
			if (m_MapImages[i].isEqual(srl, dX, dY))
				return;
		if (isLoadNew && i==m_MapImages.length)
			m_MapImages.push(new MapImage(m_hImages, srl, dX, dY));
	}
	
	this.RefreshMap = function(isLoadNew, isDeleteNoused)
	{
		if (isLoadNew && isDeleteNoused)
		{
			if (m_RepeatX) m_centerX = m_centerX - Math.floor(m_centerX);
			if (m_RepeatY) m_centerY = m_centerY - Math.floor(m_centerY);
		}
		
		var cnt = m_MapImages.length;
		var i;
		for (i=0;i<cnt;i++) m_MapImages[i].putReloaded(false);
			
		cltWidth = parseInt(m_hImages.clientWidth);
		cltHeight = parseInt(m_hImages.clientHeight);
		var UL = this.ToMapPoint(0, 0);
		var DR = this.ToMapPoint(cltWidth, cltHeight);
		var bX = Math.floor(UL.X * s) / s;
		var bY = Math.floor(UL.Y * s) / s;
		var cltUL = this.FromMapPoint(bX, bY);
		var i;
		var j;
		dy = bY;
		
		if (isLoadNew)
		{
			for (j = cltUL.Y; j < cltHeight ; j+= imgHeight * m_imgRatio)
			{
				dx = bX;
				for (i = cltUL.X; i < cltWidth ; i+= imgWidth * m_imgRatio)
				{
					this.AddMapImage(document, dx, dy, isLoadNew);
					dx += 1/s;
				}
				dy += 1/s;
			}
		}
		cnt = m_MapImages.length;
		for (i=0;i<cnt;i++)
		{
			var srl = m_MapImages[i].getSerialNumber();
			var lvl = srl.length;
			var pt = srl.toXY(lvl);
			var dX = m_MapImages[i].getDX();
			var dY = m_MapImages[i].getDY();
			if (!isDeleteNoused || 
				(dX > UL.X - 1/s && dX < DR.X && dY > UL.Y - 1/s && dY < DR.Y &&
				lvl == m_mapLevel))
			{
				var cltpt = this.FromMapPoint(dX, dY);
				m_MapImages[i].ReloadStatus(cltpt.X, cltpt.Y, m_imgWidth * m_imgRatio, m_imgHeight * m_imgRatio);
			}
		}
			
		if (isDeleteNoused)
		{
			if (m_MapImages2)
				for (i=0;i<m_MapImages2.length;i++)
					m_MapImages2[i].RemoveSelf();
			m_MapImages2 = new Array;
			
			cnt = m_MapImages.length;
			var pArray = new Array;
			for (i=0;i<cnt;i++)
			{
				if (m_MapImages[i].getReloaded())
					pArray.push(m_MapImages[i]);
				else if (m_MapImages[i].RemoveSelf)
					m_MapImages2.push(m_MapImages[i]);
			}
			m_MapImages = pArray;
		}
		
		if (m_MapImages2)
		{
			cnt = m_MapImages2.length;
			for (i=0;i<cnt;i++)
				if (!m_MapImages2[i].getReloaded())
				{
					var srl = m_MapImages2[i].getSerialNumber();
					var cltpt = this.FromMapPoint(m_MapImages2[i].getDX(), m_MapImages2[i].getDY());
					var l = Math.pow(2, m_mapLevel - srl.length);
					m_MapImages2[i].ReloadStatus(cltpt.X, cltpt.Y, m_imgWidth * m_imgRatio * l, m_imgHeight * m_imgRatio * l);
				}
		}
		
		if (m_MapElements && m_MapElements.length>0)
		{
			var i;
			var cnt = m_MapElements.length;
			if (isLoadNew && isDeleteNoused)
			{
				for (i=0;i<cnt;i++)
				{
					if (m_MapElements[i].RebuildElement)
						m_MapElements[i].RebuildElement();
					if (m_MapElements[i].UpdateElement)
						m_MapElements[i].UpdateElement(1);
				}
			}
			else
				for (i=0;i<cnt;i++)
					if (m_MapElements[i].UpdateElement)
						m_MapElements[i].UpdateElement(m_imgRatio);
		}
	}
	this.FinalRelease = function()
	{
		this.EmptyElements();
		if (m_MapImages)
		{
			cnt = m_MapImages.length;
			for (i=0;i<cnt;i++)
				m_MapImages[i].RemoveSelf();
		}
		if (m_MapImages2)
		{
			cnt = m_MapImages2.length;
			for (i=0;i<cnt;i++)
				m_MapImages2[i].RemoveSelf();
		}
	}
	
	var tAnimationFunc = null;
	var tMapPtX = null;
	var tMapPtY = null;
	var tMapSC = null;
	this.MoveToAnimation = function(MapPT, MapSC, pFinalFunc)
	{
		tMapPtX = MapPT.X;
		tMapPtY = MapPT.Y;
		tMapSC = ConfirmLevel(MapSC);
		if(tAnimationFunc!=null) return;
		
		var TimeMove = function()
		{
			var centerX = this.getCenterX();
			var centerY = this.getCenterY();
			var curScale = this.getMapLevel();
			if (this.FromMapDistX(Math.abs(centerX - tMapPtX)) < 5 && 
				this.FromMapDistY(Math.abs(centerY - tMapPtY)) < 5 && 
				Math.abs(curScale - tMapSC) < 0.03125)
			{
				this.putMapLevel(tMapSC);
				this.MoveMapTo(tMapPtX , tMapPtY);
				this.RefreshMap(true, true);
				tAnimationFunc = null;
				if (pFinalFunc) pFinalFunc();
				
				if (centerFlag!=null)  // ㄡ remove ZoonIn's Image and Out's Image
				{
				    document.body.removeChild(centerFlag); 
					centerFlag = null;
					MainRebuild();
				}
			}
			else
			{
				curS = Math.log(2 / ( 1 / Math.pow(2, curScale) + 1 / Math.pow(2, tMapSC))) / Math.log(2);
				this.putMapLevel2(curS);
				this.MoveMapTo((centerX + tMapPtX) / 2 , (centerY + tMapPtY) / 2);
				this.RefreshMap(false, true);
				tAnimationFunc = setTimeout(FuncAdapter(this, TimeMove), 100);
			}

		}
		TimeMove.call(this);
		ReadToZoomFish(); //ㄡ
	};
}

function MapPoint(dX, dY)
{
	this.X = dX;
	this.Y = dY;
	this.Diff = function(pt)
	{
		return new MapPoint(this.X - pt.X, this.Y - pt.Y);
	}
}

function MapImage(pNode, serialNum, dX, dY)
{
//private
	var m_hObj;
	var m_Reloaded;
	var m_SerialNum;
	var m_dX;
	var m_dY;
    var m_Loaded; // FF ㄡ
     
//constructor
	m_Reloaded = true;
	m_SerialNum = serialNum;
	m_dX = dX;
	m_dY = dY;
	m_Loaded = false;// FF ㄡ

	
	str = ("00" + m_SerialNum.length);

	if(!saltile)
	{
		if( Lang != 'ENG')
		mapurl="http://its.taipei.gov.tw/atis_index/MapCache/"+m_SerialNum.length+"/"+ parseInt((FourToTen(m_SerialNum))/1024+1)+"/C"+str.substr(str.length-2)+m_SerialNum+".png";
		//mapurl = "http://its.taipei.gov.tw/ATIS4_beta/ASPX/SuperVision.aspx?serial=" + m_SerialNum;
		else
		mapurl="http://its.taipei.gov.tw/atis_index/MapCache_Eng/"+m_SerialNum.length+"/"+ parseInt((FourToTen(m_SerialNum))/1024+1)+"/C"+str.substr(str.length-2)+m_SerialNum+".png";
		//mapurl = "http://its.taipei.gov.tw/ATIS4_beta/ASPX/SuperVision_Eng.aspx?serial=" + m_SerialNum;
	}
	else 
		mapurl="http://its.taipei.gov.tw/atis_index/MapCache_saltile/"+m_SerialNum.length+"\\"+
		//mapurl="http://its.taipei.gov.tw/ATIS4_beta/MapCache_saltile/"+m_SerialNum.length+"\\"+
		//mapurl="http://60.251.39.227/Atis3/MapCache/"+m_SerialNum.length+"\\"+
		parseInt((FourToTen(m_SerialNum))/1024+1)+"\\C"+str.substr(str.length-2)+m_SerialNum+".png";
			 
			 
	var agent=navigator.userAgent.toLowerCase();
	if(agent.indexOf("msie")!=-1&&document.all)
	{
		m_hObj = pNode.ownerDocument.createElement("img");
		m_hObj.src = mapurl;		
		//m_hObj = pNode.ownerDocument.createElement("div");
		//m_hObj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + mapurl + "', sizingMethod='scale')";
		m_hObj.unselectable = "on";
		m_hObj.galleryImg = false;		
	}
	else if(agent.indexOf("mozilla")!=-1) // FF ㄡ
	{
		m_hObj = pNode.ownerDocument.createElement("img");
		m_hObj.src = mapurl;
		m_hObj.style.MozUserSelect="none";
		m_hObj.onmousedown = function() {return false;}  // FF ㄡ
		//m_hObj = pNode.ownerDocument.createElement("div");
		//m_hObj.style.backgroundImage = "url(" + mapurl + ")";
		
	}
	
	m_hObj.hideFocus = true;
	pNode.appendChild(m_hObj);
	m_hObj.style.width = 0;
	m_hObj.style.height = 0;
	m_hObj.style.position = "absolute";
	
	//m_hObj.onload = function() {m_hObj.onload = null;m_hObj.onerror = null; m_Loaded = true};
    
    //m_hObj.onerror = function() {m_hObj.onload = null;m_hObj.onerror = null; m_Error = true};
    
	


//public
	this.getReloaded = function() {return m_Reloaded;};
	this.putReloaded = function(reloaded) {m_Reloaded = reloaded;};
	this.getHObject = function() {return m_hObj};
	this.getSerialNumber = function() {return m_SerialNum};
	this.getDX = function() {return m_dX;};
	this.getDY = function() {return m_dY;};
    this.getStatus = function() {return m_Error || m_Loaded}; // FF ㄡ
    
	//this.RemoveSelf = function() {if (m_hObj) pNode.removeChild(m_hObj); m_hObj = null;};
	
	this.RemoveSelf = function() {pNode.removeChild(m_hObj);};
	this.ReloadStatus = function(cx, cy, imgWidth, imgHeight)
	{
	  		
		m_hObj.style.left = cx;
		m_hObj.style.top = cy;
		m_hObj.style.width = imgWidth + 1;
		m_hObj.style.height = imgHeight + 1;
		m_Reloaded = true;
	}
	this.isEqual = function(srl, dX, dY)
	{
		return (m_SerialNum == srl && 
				Math.floor(m_dX) == Math.floor(dX) && 
				Math.floor(m_dY) == Math.floor(dY));
	}
}

function XYPoint(isRepeatX, isRepeatY)
{
	this.X = 0;
	this.Y = 0;
	this.toSerial = function(level)
	{
		if (!isRepeatX && (this.X < 0 || this.X >= 1))
			return null;
		if (!isRepeatY && (this.Y < 0 || this.Y >= 1))
			return null;
		if (level<0)
			return null;
		if (level==0)
			return "";
		var a = 0;
		var x = (this.X - Math.floor(this.X)) * 2;
		var y = (this.Y - Math.floor(this.Y)) * 2;
		var l = level;
		while (l > 0)
		{
			a = a * 4 + (Math.floor(x) + Math.floor(y) * 2);
			l -= 1;
			x = (x % 1) * 2;
			y = (y % 1) * 2;
		}
		var strTemp = "";
		var c = (a<0);
		strTemp = Math.abs(a).toString(4);
		var i ;
		for (i=strTemp.length;i<level;i++)
			strTemp = "0" + strTemp;
		return strTemp;
	}
}

String.prototype.toXY = function(level)
{
	pos = new XYPoint;
	var a = parseInt(this,4);
	var e = 1;
	var x = 0;
	var y = 0;
	while (level > 0)
	{
		x += e * (a % 2);
		y += e * parseInt((a % 4) / 2);
		e *= 2;
		a = Math.floor(a/4);
		level -= 1;
	}
	pos.X = x / e;
	pos.Y = y / e;
	return pos;
}

function MapSlider(pMapBase, locX, locY, locWidth, locHeight)
{
	var pNode = pMapBase.getHPackage();
	maxLevel = pMapBase.getMapMaxLevel();
//public
	this.Visible = function(Visib) {if (Visib) this.Show(); else this.Hide();}
	this.IsVisible = function() {return m_hObj.style.visibility != "hidden";}
	this.Hide = function() {m_hObj.style.visibility = "hidden";}
	this.Show = function() {m_hObj.style.visibility = "visible";}
	
	this.RebuildElement = function()
	{
	}
	
	this.UpdateElement = function(imgRatio)
	{
		this.LevelMapTo(pMapBase.getMapLevel());
	}
	
	this.LevelMapTo = function(mapLevel)
	{
		if (mapLevel > maxLevel) mapLevel = maxLevel;
		if (mapLevel < 0) mapLevel = 0;
		m_pTicker.style.top = (m_hObj.clientHeight-m_pTicker.offsetHeight)/maxLevel * (maxLevel - mapLevel);
	}
	this.RemoveSelf = function()
	{
		pNode.removeChild(m_hObj);
	}

//private
	var m_hObj;
	var m_pTicker;
	var MouseCurY;

//constructor
	m_hObj = pNode.ownerDocument.createElement("div");
	pNode.appendChild(m_hObj);
	m_hObj.id="Slider";
	m_hObj.style.position = "absolute";
	m_hObj.style.left = locX;
	m_hObj.style.top = locY;
	m_hObj.style.width = locWidth;
	m_hObj.style.height = locHeight*2;
	m_hObj.style.border = "inset 0px";
	m_hObj.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=80)";
	
	pSliderBar = document.createElement("div");
	m_hObj.appendChild(pSliderBar);
	pSliderBarSeps = document.createElement("div");
	m_hObj.appendChild(pSliderBarSeps);
	
	m_pTicker = document.createElement("input");
	m_pTicker.type = "button";
	m_hObj.appendChild(m_pTicker);
	m_pTicker.style.position = "absolute";
	m_pTicker.style.width = "100%";
	m_pTicker.style.overflow="hidden";
	m_pTicker.style.backgroundColor = "#80C054";
	m_pTicker.style.height = 15;
	
	pSliderBar.style.position = "absolute";
	pSliderBar.style.width = 2;
	pSliderBar.style.height = "100%";
	pSliderBar.style.border = "inset 1px gray";
	pSliderBar.style.height= m_hObj.clientHeight - m_pTicker.offsetHeight;
	pSliderBar.style.left = (m_hObj.clientWidth - pSliderBar.offsetWidth)/2;
	pSliderBar.style.top = (m_hObj.clientHeight - pSliderBar.offsetHeight)/2;
	
	pSliderBarSeps.style.position = "absolute";
	pSliderBarSeps.style.width = "100%";
	pSliderBarSeps.style.height = "100%";
	pSliderBarSeps.style.border = "inset 1px gray";
	pSliderBarSeps.style.height= m_hObj.clientHeight - m_pTicker.offsetHeight;
	pSliderBarSeps.style.top = (m_hObj.clientHeight - pSliderBar.offsetHeight)/2;
	pSliderBarSeps.style.border = 0;
	var i=0;
	for (i=0;i<maxLevel;i++)
	{
		var obj = document.createElement("div");
		pSliderBarSeps.appendChild(obj);
		obj.style.overflow="hidden";
		obj.style.width = "60%";
		obj.style.height = 2;
		obj.style.left = (pSliderBarSeps.clientWidth - obj.offsetWidth)/2;
		obj.style.top = (m_hObj.clientHeight - m_pTicker.offsetHeight)/maxLevel * (maxLevel-i);
		obj.style.position = "absolute";
		obj.style.border = "inset 1px #80C054";
		obj.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=60)";
	}
	this.LevelMapTo(pMapBase.getMapLevel());
		
	var pMouseMove = FuncAdapter(this, 
		function(tEvent)
		{
			var oy = tEvent.screenY - MouseCurY;
			
			var tY = parseInt(m_pTicker.style.top) + oy;
			if (tY>=0 && tY<=(m_hObj.clientHeight - m_pTicker.offsetHeight))
			{
				MouseCurY = tEvent.screenY;
			
				var S = maxLevel - ( tY / (m_hObj.clientHeight - m_pTicker.offsetHeight) * maxLevel);
				if(S == 0)S=1;
				pMapBase.putMapLevel2(S);
				pMapBase.RefreshMap(false, true);
			}
		}
	);
	
	var pMouseUp = FuncAdapter(this, 
		function(tEvent)
		{
			DetachEvent(m_hObj, "mousemove", pMouseMove, true);
			DetachEvent(m_hObj, "mouseup", pMouseUp, false);
			
			var oy = tEvent.screenY - MouseCurY;
			var tY = parseInt(m_pTicker.style.top) + oy;
			
			this.MouseBeginX = 0;
			this.MouseBeginY = 0;
			
			if (tY<0) tY=0;
			if (tY>(m_hObj.clientHeight-m_pTicker.offsetHeight))
				tY = (m_hObj.clientHeight-m_pTicker.offsetHeight);
			
			mapScale = maxLevel - ( tY / (m_hObj.clientHeight-m_pTicker.offsetHeight) * maxLevel);
			pMapBase.putMapLevel(mapScale);
			pMapBase.RefreshMap(true, true);
		}
	);
	
	var pTickFunc = function(tEvent)
	{
		MouseCurY = tEvent.screenY;
		AttachEvent(m_hObj, "mouseup", pMouseUp, false);
		AttachEvent(m_hObj, "mousemove", pMouseMove, true);
	}
	AttachEvent(m_pTicker, "mousedown", pTickFunc, false);
	
	this.RemoveSelf = function()
	{
		DetachEvent(m_pTicker, "mousedown", pTickFunc, false);
		if (m_hObj)
			pNode.removeChild(m_hObj);
		m_hObj = null
	}
}

function MagnifierBase(pMapBase, diffLevel)
{
	var pNode = pMapBase.getHPackage();
//public
	this.Visible = function(Visib) {if (Visib) this.Show(); else this.Hide();}
	this.IsVisible = function() {return m_MainTable.style.visibility != "hidden";}
	this.Hide = function() {m_MainTable.style.visibility = "hidden";}
	this.Show = function() {m_MainTable.style.visibility = "visible";}
	this.getMapBase = function() {return m_MapBase;}
	
	this.ViewAt = function(dX, dY, isDeleteNoused)
	{
		var pt = m_TargetMapBase.FromMapPoint(dX, dY);
		var tX = pt.X - m_CenterOffsetX;
		var tY = pt.Y - m_CenterOffsetY;
		m_MapBase.MoveMapTo(dX, dY);
		m_MapBase.RefreshMap(true, isDeleteNoused);
		m_MainTable.style.left = tX;
		m_MainTable.style.top = tY;
	}
	
	this.RebuildElement = function()
	{
		var tX = parseInt(m_MainTable.style.left);
		var tY = parseInt(m_MainTable.style.top);
		var nX = m_CenterOffsetX + tX;
		var nY = m_CenterOffsetY + tY;
		var pt = m_TargetMapBase.ToMapPoint(nX, nY);
		this.ViewAt(pt.X, pt.Y);
		m_MapBase.MoveMapTo(pt.X, pt.Y);
		m_MapBase.putMapLevel(m_TargetMapBase.getMapLevel() + diffLevel);
		m_MapBase.RefreshMap(true, false);
	}
	
	this.UpdateElement = function(imgRatio)
	{
		if (m_MapMagnifierAsync && this.IsVisible)
		{
			this.RebuildElement();
		}
	}

//private
	var m_MapBase;
	var m_MainTable;
	var m_MapMagnifier;
	var MouseCurX;
	var MouseCurY;
	var m_TargetMapBase;
	var m_CenterOffsetX = 0;
	var m_CenterOffsetY = 0;
	var m_MapMagnifierAsync = false;
	
//constructor
	m_TargetMapBase = pMapBase;
	
	pDoc = pNode.ownerDocument;
	m_MainTable = pDoc.createElement("table");
	pTbl = m_MainTable;
	pTbl.style.position = "absolute";
	pTbl.style.left = 0;
	pTbl.style.top = 0;
	pNode.appendChild(pTbl);
	pTbl.border = 0;
	pTbl.cellPadding = 0;
	pTbl.cellSpacing = 0;
	pTbl.unselectable = "on";
	
	var pCenterCell = null;
	pRow = pTbl.insertRow(pTbl.rows.length);
	if (pRow)
	{
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.innerHTML = "<img src='Images/Side_1.gif' width=10 height=10 border=0>";
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.style.backgroundImage = "url(Images/Side_2.gif)";
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.innerHTML = "<img src='Images/Side_3.gif' width=10 height=10 border=0>";
	}
	
	pRow = pTbl.insertRow(pTbl.rows.length);
	if (pRow)
	{
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.style.backgroundImage = "url(Images/Side_4.gif)";
		pCenterCell = pRow.insertCell(pRow.cells.length);
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.style.backgroundImage = "url(Images/Side_6.gif)";
	}
	
	pRow = pTbl.insertRow(pTbl.rows.length);
	if (pRow)
	{
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.vAlign="bottom";
		pCell.innerHTML = "<img src='Images/Side_7.gif' width=10 height=10 border=0>";
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.style.backgroundImage = "url(Images/Side_8.gif)";
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.vAlign="bottom";
		pCell.innerHTML = "<img src='Images/Side_9.gif' width=10 height=10 border=0>";
	}

	pTbl = pDoc.createElement("table");
	pCenterCell.appendChild(pTbl);
	pTbl.border = 0;
	pTbl.cellPadding = 0;
	pTbl.cellSpacing = 0;
	pTbl.unselectable = "on";
	
	pImg = pDoc.createElement("img");
	pImg.src = "Images/Magnifier.gif";
	pImg.border=0;
	pImg.width=25;
	pImg.height=25;
		
	pRow = pTbl.insertRow(pTbl.rows.length);
	if (pRow)
	{
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.style.border = "inset 1px gray"
		pCell.colSpan=2;
		
		var s = Math.pow(2, diffLevel);
		m_MapBase = new MapBase(pCell, 0, 0, pImg.width * s, pImg.height * s, 256, 256);
		m_MapBase.putRepeatX(false);
	}
	
	pRow = pTbl.insertRow(pTbl.rows.length);
	if (pRow)
	{
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.style.border = "inset 1px gray"
		pCell.align="center";
		pCell.appendChild(pImg);

		var pCell2 = pRow.insertCell(pRow.cells.length);
		pCell2.style.backgroundImage = "url(Images/Side_5.gif)";
		pCell2.width = pCenterCell.clientWidth - pImg.width - 2;
		m_CenterOffsetX = pCenterCell.offsetLeft + pCell.offsetLeft + (pImg.width+1) /2 + 1;
		m_CenterOffsetY = pCenterCell.offsetTop + pCell.offsetTop + (pImg.height+1) / 2 + 1;
	}
	m_MapBase.putMapMaxLevel(m_TargetMapBase.getMapMaxLevel());
	m_MapBase.putMapLevel(m_TargetMapBase.getMapLevel() + diffLevel);
	this.ViewAt(m_TargetMapBase.getCenterX(), m_TargetMapBase.getCenterY(), true);
	
	var pMouseMove = FuncAdapter(this, 
		function(tEvent)
		{
			var ox = tEvent.screenX - MouseCurX;
			var oy = tEvent.screenY - MouseCurY;
			
			MouseCurX = tEvent.screenX;
			MouseCurY = tEvent.screenY;
			
			var tX = parseInt(m_MainTable.style.left) + ox;
			var tY = parseInt(m_MainTable.style.top) + oy;
			m_MainTable.style.left = tX;
			m_MainTable.style.top = tY;
			this.RebuildElement();
		}
	);
		
	AttachEvent(m_MainTable, "mousedown", 
		FuncAdapter(this, 
			function(tEvent)
			{
				MouseCurX = tEvent.screenX;
				MouseCurY = tEvent.screenY;
				AttachEvent(m_MainTable, "mousemove", pMouseMove, true);
			}
		),
	false);
	AttachEvent(m_MainTable, "mouseup", 
		FuncAdapter(this, 
			function(tEvent)
			{
				m_MapBase.RefreshMap(true, true);
				DetachEvent(m_MainTable, "mousemove", pMouseMove, true);
			}
		),
	false);
}

function MapTools(pNode, locX, locY, padding)
{
//public
	this.AddTool = function(pMapBase, pTool, imgPath, altString)
	{
		var hObj = pNode.ownerDocument.createElement("img");
		m_hObj.appendChild(hObj);
		hObj.src = imgPath;
		hObj.style.border = "outset 2px";
		hObj.style.margin = padding + "px " + padding + "px " + padding + "px 0px";
		hObj.style.background = "lightgreen";
		hObj.alt = altString;
		if (pTool && pTool.InitialMapBase)
			pTool.InitialMapBase(pMapBase);
		
		var pClick = function(tEvent) 
		{
			var i;
			var cnt = m_Tools.length;
			for (i=0;i<cnt;i++)
			{
				m_Tools[i].style.border = "outset 2px";
				m_Tools[i].style.background = "lightgreen";
			}

			if (m_CurrentTool == hObj)
			{
				pMapBase.SelectMapTool(null);
				m_CurrentTool = null;
			}
			else
			{
				if (pTool)
				{
					if (pMapBase.SelectMapTool(pTool))
						m_CurrentTool = hObj;
					else if (pTool.MapCommand)
						pTool.MapCommand(tEvent, pMapBase, hObj);
				}	
				if (m_CurrentTool)
				{
					m_CurrentTool.style.border = "inset 2px";
					m_CurrentTool.style.background = "green";
				}
			}
		}
		var pMouseUp = function(tEvent)
		{
			hObj.style.border = "outset 2px";
			hObj.style.background = "lightgreen";
			DetachEvent(hObj, "mouseup", pMouseUp, true);
		}
		var pMouseDown = function(tEvent) 
		{
			hObj.style.border = "inset 2px";
			hObj.style.background = "green";
			AttachEvent(hObj, "mouseup", pMouseUp, true);
		}
		hObj.pClickFunc = pClick;
		hObj.pMouseDownFunc = pMouseDown;
		AttachEvent(hObj, "click", pClick, false);
		AttachEvent(hObj, "mousedown", pMouseDown, false);

		m_Tools.push(hObj);
	}
	this.FinalRelease = function()
	{
		cnt = m_Tools.length;
		for (i=0;i<cnt;i++)
		{
			var hObj = m_Tools[i]
			DetachEvent(hObj, "click", hObj.pClickFunc, false);
			DetachEvent(hObj, "mousedown", hObj.pMouseDownFunc, false);
			m_hObj.removeChild(hObj);
		}
		pNode.removeChild(m_hObj);
		m_Tools = new Array;
	}
	this.selectTool = function(Index)
	{
		m_Tools[Index].pClickFunc();
	}
//private
	var m_hObj;
	var m_Tools = new Array;
	var m_CurrentTool = null;

	m_hObj = pNode.ownerDocument.createElement("span");
	pNode.appendChild(m_hObj);
	m_hObj.style.position = "relative";
	m_hObj.style.left = locX;
	m_hObj.style.top = locY;
}
var centerFlag = null; // ㄡ var of ZoonIn's Image and Out's Image 
function MapMove()
{
	return new MapMoveEx(true, true);
}
function MapMoveEx(bAllowDblClick, bAllowWheel)
{
	var MouseCurX;
	var MouseCurY;
	var m_bMapAction = false;
	var tWheelTimer = null
	this.ExitMapEvent = null;
	
	this.IsMapAction = function() {return m_bMapAction;};
	this.InitMapEvent = function(pMapBase)
	{
		var hObj = pMapBase.getHObject();
		
		var pMouseMove = function(tEvent)
		{
		    
			var ox = tEvent.screenX - MouseCurX;
			var oy = tEvent.screenY - MouseCurY;
			var pxs = parseInt(tx);
			var pys = parseInt(ty);
			
			MouseCurX = tEvent.screenX;
			MouseCurY = tEvent.screenY;
			
			MainMouseMove(tEvent,ox,oy,pxs,pys);
			
			pMapBase.MoveMapTo(pMapBase.getCenterX() - pMapBase.ToMapDistX(ox), pMapBase.getCenterY() - pMapBase.ToMapDistY(oy));
			pMapBase.RefreshMap(true, false);
		}
		
		var pMouseUp = function(tEvent)
		{
			DetachEvent(hObj, "mousemove", pMouseMove, true);
			DetachEvent(hObj, "mouseup", pMouseUp, false);

			pMapBase.RefreshMap(true, true);
			
			MainMouseUp();
			//回收資源
			CollectGarbage();
			m_bMapAction = false;
		}
		
		var pMouseDown = function(tEvent) 
		{   
			m_bMapAction = true;
			MouseCurX = tEvent.screenX;
			MouseCurY = tEvent.screenY;
			//tx=event.clientX;			
			//ty=event.clientY;	
		    tx=tEvent.clientX;	// FF ㄡ	
			ty=tEvent.clientY;	// FF ㄡ
			
			AttachEvent(hObj, "mouseup", pMouseUp, false);
			AttachEvent(hObj, "mousemove", pMouseMove, true);
		}
		
		var pDblClick = function(tEvent)
		{
			if (!bAllowDblClick)
				return;
				
			m_bMapAction = true;
			var OffsetPt = pMapBase.getOffset();
			var cpt = pMapBase.ToMapPoint(tEvent.clientX - OffsetPt.X, tEvent.clientY - OffsetPt.Y);
			pMapBase.MoveToAnimation(cpt, gMapBase.getMapLevel()+1, function() {m_bMapAction = false;});			
		}
		
		var pWheelFunc = function(tEvent)
		{		    
			if (!bAllowWheel)
				return;

			m_bMapAction = true;
			centerFlag = null;
			
			// ㄡ append Zoonin and Zoonout Image
			this.wheelImage = function(inout)
            {
                centerFlag = document.createElement("img");
			    centerFlag.style.position = "absolute";
                switch(inout)
                {
                    case 0:
                        centerFlag.src = 'images/out.gif';	
                    break;
                    case 1:
                        centerFlag.src = 'images/in.gif';	
                    break;
                }
                
			    centerFlag.style.left = tEvent.clientX - (80 / 2); 
			    centerFlag.style.top = tEvent.clientY - (60 / 2);	
			    document.body.appendChild(centerFlag); 
            };
			
			var OffsetPt = pMapBase.getOffset();
			var cpt = pMapBase.ToMapPoint(tEvent.clientX - OffsetPt.X, tEvent.clientY - OffsetPt.Y);
			
			var FinalLevel = Math.floor(pMapBase.getMapLevel());
			
			var nDelta = tEvent.wheelDelta; // FF ㄡ
            if (nDelta == null) // FF
            {
                nDelta = -tEvent.detail;        // FF ㄡ
                if (nDelta > 0)//往前滾
                {
				    FinalLevel += 1;
				    cpt = new MapPoint((pMapBase.getCenterX() + cpt.X)/2, (pMapBase.getCenterY() + cpt.Y)/2);
				    this.wheelImage(0);
			    }
			    else if (nDelta < 0) //往後滾
                {
                    if(FinalLevel>1)
				    {
				        FinalLevel -= 1;
				        cpt = new MapPoint(2 * pMapBase.getCenterX() - cpt.X, 2 * pMapBase.getCenterY() - cpt.Y);
				        this.wheelImage(1);				        
				    }
                }
            }
            else // IE
            {
			    if (event.wheelDelta >= 120)//往前滾
			    {
				    FinalLevel += 1;
				    cpt = new MapPoint((pMapBase.getCenterX() + cpt.X)/2, (pMapBase.getCenterY() + cpt.Y)/2);
				    this.wheelImage(0);
			    }
			    else if (event.wheelDelta <= -120) //往後滾
			    {
				    if(FinalLevel>1)
				    {
				        FinalLevel -= 1;
				        cpt = new MapPoint(2 * pMapBase.getCenterX() - cpt.X, 2 * pMapBase.getCenterY() - cpt.Y);
				        this.wheelImage(1);
				    }
			    }
			}
			pMapBase.MoveToAnimation(cpt, FinalLevel, function() {m_bMapAction = false;});
			
		}
        
		this.ExitMapEvent = function()
		{
			DetachEvent(hObj, "mousedown", pMouseDown, false);
			if (bAllowDblClick)
				DetachEvent(hObj, "dblclick", pDblClick, false);
			if (bAllowWheel)
				DetachEvent(hObj, "mousewheel", pWheelFunc, false);
		}

		AttachEvent(hObj, "mousedown", pMouseDown, false);
		if (bAllowDblClick)
			AttachEvent(hObj, "dblclick", pDblClick, false);
		if (bAllowWheel) //滑鼠滾輪事件
			AttachEvent(hObj, "mousewheel", pWheelFunc, false);
	}
}

function MapZoom(ZoomType)
{
	var MouseCurX;
	var MouseCurY;
	var MouseDownX;
	var MouseDownY;
	var m_hObj;
	
	this.ExitMapEvent = null;
	this.InitMapEvent = function(pMapBase)
	{
		var hObj = pMapBase.getHObject();
		var OffsetPt = pMapBase.getOffset();
		
		var pMouseMove = function(tEvent)
		{
			var ox = tEvent.screenX - MouseCurX;
			var oy = tEvent.screenY - MouseCurY;
			
			m_hObj.style.left = MouseDownX + (ox<0?ox:0);
			m_hObj.style.width = Math.max(Math.abs(ox),1);
			
			m_hObj.style.top = MouseDownY + (oy<0?oy:0);
			m_hObj.style.height = Math.max(Math.abs(oy),1);
		}
		
		var pMouseUp = function(tEvent)
		{
			DetachEvent(hObj, "mousemove", pMouseMove, true);
			DetachEvent(hObj, "mouseup", pMouseUp, false);
			
			hObj.removeChild(m_hObj);
			m_hObj = null;

			var ox = Math.abs(tEvent.screenX - MouseCurX);
			var oy = Math.abs(tEvent.screenY - MouseCurY);
			
			var cpt = pMapBase.ToMapPoint(
				(MouseDownX + tEvent.clientX - OffsetPt.X) / 2, 
				(MouseDownY + tEvent.clientY - OffsetPt.Y) / 2);
			
			pMapBase.MoveMapTo(cpt.X, cpt.Y);
			
			var s;
			if (ox<5 && oy<5)
				s = 1;
			else
			{
				var sw = pMapBase.getClientWidth() / ox;
				var sh = pMapBase.getClientHeight() / oy;
				s = Math.log(Math.min(sw,sh))/Math.log(2);
			}
			
			pMapBase.putMapLevel(pMapBase.getMapLevel() + ((ZoomType==0)?s:-s));
			pMapBase.RefreshMap(true, true);
			MainRebuild();
		}
		
		var pMouseDown = function(tEvent) 
		{		    
			MouseCurX = tEvent.screenX;
			MouseCurY = tEvent.screenY;
			
			MouseDownX = tEvent.clientX - OffsetPt.X;
			MouseDownY = tEvent.clientY - OffsetPt.Y;
			
			m_hObj = hObj.ownerDocument.createElement("div");
			hObj.appendChild(m_hObj);
			m_hObj.style.position = "absolute";
			m_hObj.style.overflow = "hidden";
			m_hObj.style.left = MouseDownX;
			m_hObj.style.top = MouseDownY;
			m_hObj.style.width = 0;
			m_hObj.style.height = 0;
			m_hObj.style.border = "inset 2px red";
			
			AttachEvent(hObj, "mouseup", pMouseUp, false);
			AttachEvent(hObj, "mousemove", pMouseMove, true);
		}
		
		this.ExitMapEvent = function() {DetachEvent(hObj, "mousedown", pMouseDown, false);}
	
		AttachEvent(hObj, "mousedown", pMouseDown,false);
		
	}
}

function MapFullExtent()
{
	this.MapCommand = function(tEvent, pMapBase, hObj)
	{
		pMapBase.MoveMapTo(0.5, 0.5);
		var sw = Math.abs(pMapBase.getClientWidth() / pMapBase.getImageWidth());
		var sh = Math.abs(pMapBase.getClientHeight() / pMapBase.getImageHeight());
		pMapBase.putMapLevel(Math.log(Math.min(sw,sh))/Math.log(2));
		gMapBase.RefreshMap(true, true);
	}
}

function MapLocate(dX, dY, dLevel)
{
	this.X = dX;
	this.Y = dY;
	this.Level = dLevel;
}

function MapZoomLast()
{
	this.RemoveSelf = null;
	this.RebuildElement = null;
	
	var m_MapLocates = new Array;
	this.RebuildElement = null;
	this.MapCommand = null;
	
	this.InitialMapBase = function(pTargetMapBase)
	{
		this.RebuildElement = function()
		{
			m_MapLocates.push(new MapLocate(pTargetMapBase.getCenterX(), pTargetMapBase.getCenterY(), pTargetMapBase.getMapLevel()));
		}
		this.MapCommand = function(tEvent, pMapBase, hObj)
		{
			if (m_MapLocates.length>1)
			{
				pLocate = m_MapLocates.pop();
				if (pLocate)
				{
					pLocate = m_MapLocates.pop();
					if (pLocate)
					{
						pTargetMapBase.MoveMapTo(pLocate.X, pLocate.Y);
						pTargetMapBase.putMapLevel(pLocate.Level);
						pTargetMapBase.RefreshMap(true, true);
					}
				}
			}
		}
		this.RebuildElement();
		pTargetMapBase.AddElement(this);
	}
}

function MapSliderAdmin()
{
	var m_pSlider;
	this.MapCommand = function(tEvent, pMapBase, hObj)
	{
		if (m_pSlider==null)
			pMapBase.AddElement(m_pSlider = new MapSlider(pMapBase, 10, 10, 30, 150, 8));
		else if (m_pSlider.IsVisible())
			m_pSlider.Hide();
		else
			m_pSlider.Show();
	}
}

function MapMagniAdmin(levelDiff)
{
	var m_pMagni;
	this.MapCommand = function(tEvent, pMapBase, hObj)
	{
		if (m_pMagni==null)
			pMapBase.AddElement(m_pMagni = new MagnifierBase(pMapBase, levelDiff));
		else if (m_pMagni.IsVisible())
			m_pMagni.Hide();
		else
			m_pMagni.Show();
	}
}

function MapQuery(thematicLayer, thematicLayerField)
{
	var m_hObj = null;
	var m_inputFilter = null;
	var m_pQuery = null;
	this.MapCommand = function(tEvent, pMapBase, hObj)
	{
		var pNode = document.body;
		
		var pQueryFunc = function(tEvent) 
		{
			if (m_pQuery)
				pMapBase.RemoveElement(m_pQuery);
			m_pQuery = null;
			if (m_inputFilter.value != "")
			{
				m_pQuery = new MapSelectResult(pMapBase, 500, 300);
				m_pQuery.ExecuteFilter(thematicLayer, m_inputFilter.value);
				pMapBase.AddElement(m_pQuery);
			}
			m_hObj.style.visibility = "hidden";
		}
		
		var pClearFunc = function()
		{
			if (m_pQuery)
				pMapBase.RemoveElement(m_pQuery);
			m_pQuery = null;
			
			if (m_hObj)
				pNode.removeChild(m_hObj);
			m_hObj=null;
		}
		
		if (m_hObj)
		{
			m_hObj.style.visibility = "visible";
		}
		else
		{
			m_hObj = pNode.ownerDocument.createElement("div");
			pNode.appendChild(m_hObj);
			m_hObj.style.background = "lightgreen";
			m_hObj.style.position = "absolute";
			m_hObj.style.border = "solid 1px green"
			m_hObj.style.padding = "2px 2px 2px 2px";
			
			var inp;
			
			pTbl = pNode.ownerDocument.createElement("table");
			m_hObj.appendChild(pTbl);
			pTbl.border = 0;
			pTbl.cellPadding = 0;
			pTbl.cellSpacing = 0;
			pTbl.unselectable = "on";
			
			pRow = pTbl.insertRow(pTbl.rows.length);
			if (pRow)
			{
				pCell = pRow.insertCell(pRow.cells.length);
				pCell.align = "center";
				
				var field = pNode.ownerDocument.createElement("select");
				var i;
				for (i=0;i<thematicLayerField.length;i++)
					field.options[i] = new Option(thematicLayerField[i], thematicLayerField[i]);
					
				pCell.appendChild(field);
				
				var oper = pNode.ownerDocument.createElement("select");
				oper.options[0] = new Option("=", " = ");
				oper.options[1] = new Option("<", " < ");
				oper.options[2] = new Option(">", " > ");
				oper.options[3] = new Option("<=", " <= ");
				oper.options[4] = new Option(">=", " >= ");
				oper.options[5] = new Option("!=", " != ");
				oper.options[6] = new Option("Like", " LIKE ");
				pCell.appendChild(oper);
				
				var fieldvalue = pNode.ownerDocument.createElement("input");
				fieldvalue.value = "";
				pCell.appendChild(fieldvalue);
			}
			
			pRow = pTbl.insertRow(pTbl.rows.length);
			if (pRow)
			{
				pCell = pRow.insertCell(pRow.cells.length);
				pCell.align = "center";
				
				var inp = pNode.ownerDocument.createElement("input");
				inp.type = "button";
				inp.value="And";
				AttachEvent(inp, "click", function() {m_inputFilter.value += " AND";}, false);
				pCell.appendChild(inp);
				
				inp = pNode.ownerDocument.createElement("input");
				inp.type = "button";
				inp.value="Or";
				AttachEvent(inp, "click", function() {m_inputFilter.value += " OR ";}, false);
				pCell.appendChild(inp);
				
				inp = pNode.ownerDocument.createElement("input");
				inp.type = "button";
				inp.value="Not";
				AttachEvent(inp, "click", function() {m_inputFilter.value += " NOT ";}, false);
				pCell.appendChild(inp);
				
				inp = pNode.ownerDocument.createElement("input");
				inp.type = "button";
				inp.value="(";
				AttachEvent(inp, "click", function() {m_inputFilter.value += " ( ";}, false);
				pCell.appendChild(inp);
				
				inp = pNode.ownerDocument.createElement("input");
				inp.type = "button";
				inp.value=")";
				AttachEvent(inp, "click", function() {m_inputFilter.value += " ) ";}, false);
				pCell.appendChild(inp);
				
				inp = pNode.ownerDocument.createElement("input");
				inp.type = "button";
				inp.value="Append";
				AttachEvent(inp, "click", 
					function() 
					{
						m_inputFilter.value += field.options[field.selectedIndex].value + 
								oper.options[oper.selectedIndex].value + 
								"'" + fieldvalue.value + "'";
					}, false);
				pCell.appendChild(inp);
			}
			
			pRow = pTbl.insertRow(pTbl.rows.length);
			if (pRow)
			{
				pCell = pRow.insertCell(pRow.cells.length);
				pCell.align = "center";
				
				m_inputFilter = pNode.ownerDocument.createElement("input");
				pCell.appendChild(m_inputFilter);
				m_inputFilter.size = 50;
				
				var inp;
				inp = pNode.ownerDocument.createElement("input")
				inp.type = "button";
				inp.value="Query";
				AttachEvent(inp, "click", pQueryFunc, false);
				pCell.appendChild(inp);
				
				inp = pNode.ownerDocument.createElement("input");
				inp.type = "button";
				inp.value="Clear";
				AttachEvent(inp, "click", pClearFunc, false);
				pCell.appendChild(inp);
				
				inp = pNode.ownerDocument.createElement("input");
				inp.type = "button";
				inp.value="Close";
				AttachEvent(inp, "click", function(tEvent) {m_hObj.style.visibility = "hidden";}, false);
				pCell.appendChild(inp);
			}
		}
		
		m_hObj.style.left = tEvent.clientX;
		m_hObj.style.top = tEvent.clientY;
	}
}

//static
MapSelectResult.Results = new Array();
function MapSelectResult(pMapBase, tblWidth, tblHeight)
{
	var pNode = pMapBase.getHPackage();
	MapSelectResult.Results.push(this);
	
//private
	var m_MainTable;
	var m_MainDiv;
	var m_pGraps = new Array;
	
//public
	this.Visible = function(Visib) {if (Visib) this.Show(); else this.Hide();}
	this.IsVisible = function() {return m_MainTable.style.visibility != "hidden";}
	this.Hide = function() {m_MainTable.style.visibility = "hidden";}
	this.Show = function() {m_MainTable.style.visibility = "visible";}
	this.SetZIndex = function(zIdx) {m_MainTable.style.zIndex = zIdx;}
	this.GetZIndex = function() {return m_MainTable.style.zIndex;}
	this.EnsureZIndex = function(zIdx) 
	{
		var z = parseInt(m_MainTable.style.zIndex);
		if (z > zIdx)
		{
			m_MainTable.style.zIndex = z-1;
			return z;
		}
		return 0;
	}
	this.RemoveSelf = function()
	{
		var i;
		for (i=0;i<m_pGraps.length;i++)
			pMapBase.RemoveElement(m_pGraps[i]);
		m_pGraps = new Array;
		
		for (i=0;i<MapSelectResult.Results.length;i++)
		{
			if (MapSelectResult.Results[i] == this)
			{
				MapSelectResult.Results.splice(i, 1);
				break;
			}
		}
		
		if (m_MainTable)
			pNode.removeChild(m_MainTable);
		m_MainTable = null
	}

	this.RebuildElement = null;
	this.UpdateElement = null;

//constructor
	pDoc = pNode.ownerDocument;
	m_MainTable = pDoc.createElement("table");
	m_MainTable.style.zIndex = MapSelectResult.Results.length;
	pTbl = m_MainTable;
	pNode.appendChild(pTbl);
	pTbl.style.position = "absolute";
	pTbl.style.left = 0;
	pTbl.style.top = 0;
	pTbl.border = 0;
	pTbl.cellPadding = 0;
	pTbl.cellSpacing = 0;
	pTbl.unselectable = "on";
	
	var pCenterCell = null;
	var pTitleCell = null;
	pRow = pTbl.insertRow(pTbl.rows.length);
	if (pRow)
	{
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.innerHTML = "<img src='Images/Side_1.gif' width=10 height=10 border=0>";
		pTitleCell = pRow.insertCell(pRow.cells.length);
		pTitleCell.style.backgroundImage = "url(Images/Side_2.gif)";
		var pImg = pDoc.createElement("img");
		pImg.src = "Images/Close.gif";
		pImg.border = 0;
		pImg.width = 9;
		pImg.height = 9;
		
		AttachEvent(pImg, "click", 
			FuncAdapter(this, function(tEvent){pMapBase.RemoveElement(this);}),
		false);
	
		pTitleCell.appendChild(pImg);
		pTitleCell.align = "right";
		pTitleCell.vAlign = "bottom";
			
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.innerHTML = "<img src='Images/Side_3.gif' width=10 height=10 border=0>";
	}
	
	pRow = pTbl.insertRow(pTbl.rows.length);
	if (pRow)
	{
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.style.backgroundImage = "url(Images/Side_4.gif)";
		pCenterCell = pRow.insertCell(pRow.cells.length);
		pCenterCell.style.backgroundImage = "url(Images/Side_5.gif)";
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.style.backgroundImage = "url(Images/Side_6.gif)";
	}
	
	pRow = pTbl.insertRow(pTbl.rows.length);
	if (pRow)
	{
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.vAlign="bottom";
		pCell.innerHTML = "<img src='Images/Side_7.gif' width=10 height=10 border=0>";
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.style.backgroundImage = "url(Images/Side_8.gif)";
		pCell = pRow.insertCell(pRow.cells.length);
		pCell.vAlign="bottom";
		pCell.innerHTML = "<img src='Images/Side_9.gif' width=10 height=10 border=0>";
	}
		
	var InsertFeatures = function(pNodes)
	{
		pCenterCell.innerHTML="";
		pDiv = pDoc.createElement("div");
		pCenterCell.appendChild(pDiv);
		pDiv.style.border = "inset 1px gray"
		
		if (pNodes.length>0)
		{
			var pNodes2 = pNodes.item(0).getElementsByTagName("Values").item(0).childNodes;
			pTbl = pDoc.createElement("table");
			pDiv.appendChild(pTbl);
			pTbl.border = 0;
			pTbl.cellPadding = 0;
			pTbl.cellSpacing = 1;
			pTbl.unselectable = "on";
			pTbl.bgColor = "black";
			pRow = pTbl.insertRow(pTbl.rows.length);
			if (pRow)
			{
				var j;
				pCell = pRow.insertCell(pRow.cells.length);
				pCell.bgColor = "lightblue";
				pCell.innerHTML = "NO";
				for (j=0;j<pNodes2.length;j++)
				{
					pCell = pRow.insertCell(pRow.cells.length);
					pCell.bgColor = "lightgreen";
					pCell.innerHTML = pNodes2.item(j).tagName;
				}
			}
			var cnt = pNodes.length;
			if (cnt>100) cnt = 100;
			var i;
			for (i=0;i<cnt;i++)
			{
				var pValues = pNodes.item(i).getElementsByTagName("Values");
				if (pValues == null)
					continue;
				var pNodes2 = pValues.item(0).childNodes;
	
				pRow = pTbl.insertRow(pTbl.rows.length);
				if (pRow)
				{
					pCell = pRow.insertCell(pRow.cells.length);
					pCell.bgColor = "lightblue";
					pCell.innerHTML = i;
					var j;
					for (j=0;j<pNodes2.length;j++)
					{
						pCell = pRow.insertCell(pRow.cells.length);
						pCell.bgColor = "lightgreen";
						if (pNodes2.item(j).firstChild)
							pCell.innerHTML = pNodes2.item(j).firstChild.nodeValue;
					}
				}
	
				var pGrap = new MapGraphic(pMapBase, true);
				pMapBase.AddElement(pGrap);
				
				var pNodes2 = pNodes.item(i).getElementsByTagName("Geometry")[0].getElementsByTagName("Part");
				var j;
				for (j=0;j<pNodes2.length;j++)
				{
					var pPart = pGrap.AddPart();
					var strPts = pNodes2.item(j).firstChild.nodeValue;
					var ss = strPts.split(",");
					var k;
					for (k=0;k<ss.length;k++)
					{
						var sss = ss[k].split(" ");
						pPart.AddPoint(parseFloat(sss[0]), parseFloat(sss[1]));
					}
				}
				pGrap.UpdateElement(1);
				m_pGraps.push(pGrap);
			}
			
			var a = pTbl.offsetWidth > tblWidth;
			var b = pTbl.offsetHeight > tblHeight;
			if (a || b)
			{
				pDiv.style.height = (b?tblHeight:"");
				pDiv.style.width = (a?tblWidth:"");
				pDiv.style.overflow = "scroll";
			}
		}
	}
	
	this.ExecuteQuery = function(postData)
	{
		pCenterCell.innerHTML = "Querying...";
		var hr = new XMLHttpRequest;
		hr.onreadystatechange = function()
		{
			if (hr.readyState == 4)
			{
				if (hr.status == 200)
				{
					var pDoc = hr.responseXML;
					var pNodes = pDoc.documentElement.getElementsByTagName("Feature");
					if (pNodes.length > 0)
						InsertFeatures(pNodes);
					else
						pCenterCell.innerHTML = "No data found";
				}
				else
					pCenterCell.innerHTML = "Query failed";
			}
		}
		hr.open('POST', "Select.aspx", true);
		hr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		hr.send(postData);
	}
	
	this.ExecuteFilter = function(thematicLayer, expr)
	{
		this.ExecuteQuery("layer=" + thematicLayer + "&EXPR=" + escape(expr));
	}
	
	this.ExecuteGeom = function(thematicLayer, geom)
	{
		this.ExecuteQuery("layer=" + thematicLayer + "&GEOM=" + escape(geom));
	}
	
	var pMouseMove = FuncAdapter(this, 
		function(tEvent)
		{
			var ox = tEvent.screenX - MouseCurX;
			var oy = tEvent.screenY - MouseCurY;
			
			MouseCurX = tEvent.screenX;
			MouseCurY = tEvent.screenY;
			
			var tX = parseInt(m_MainTable.style.left) + ox;
			var tY = parseInt(m_MainTable.style.top) + oy;
			m_MainTable.style.left = tX;
			m_MainTable.style.top = tY;
		}
	);
	
	var pMouseUp = FuncAdapter(this, 
		function(tEvent)
		{
			DetachEvent(pTitleCell, "mouseup", pMouseUp, false);
			DetachEvent(pTitleCell, "mousemove", pMouseMove, true);
		}
	);
		
	AttachEvent(pTitleCell, "mousedown", 
		FuncAdapter(this, 
			function(tEvent)
			{
				MouseCurX = tEvent.screenX;
				MouseCurY = tEvent.screenY;
				
				var zI = parseInt(m_MainTable.style.zIndex);
				var maxz = zI;
				for (i=0;i<MapSelectResult.Results.length;i++)
				{
					var z = MapSelectResult.Results[i].EnsureZIndex(zI);
					if (z>maxz)
						maxz = z;
				}
				m_MainTable.style.zIndex = maxz;
				window.status = maxz + ",";
				for (i=0;i<MapSelectResult.Results.length;i++)
				{
					window.status += MapSelectResult.Results[i].GetZIndex() + ",";
				}
		
				AttachEvent(pTitleCell, "mouseup", pMouseUp, false);
				AttachEvent(pTitleCell, "mousemove", pMouseMove, true);
			}
		),
	false);
}

function MapSelectPoint(thematicLayer)
{	
	var m_pQuery = null;
	this.ExitMapEvent = null;
	this.InitMapEvent = function(pMapBase)
	{
		var hObj = pMapBase.getHObject();
		
		var pClick = function(tEvent)
		{
			var OffsetPt = pMapBase.getOffset();
			var cpt = pMapBase.ToMapPoint(tEvent.clientX - OffsetPt.X, tEvent.clientY - OffsetPt.Y);
			
			if (m_pQuery)
				pMapBase.RemoveElement(m_pQuery);
			m_pQuery = new MapSelectResult(pMapBase, 500, 300);
			m_pQuery.ExecuteGeom(thematicLayer, "PT( " + cpt.X + " " + cpt.Y + " )");
			pMapBase.AddElement(m_pQuery);
		}
		
		this.ExitMapEvent = function() 
		{
			DetachEvent(hObj, "click", pClick, false);
		}
		AttachEvent(hObj, "click", pClick,false);
	}
}

function MapRectangle(thematicLayer)
{
	var m_pQuery;
	var MouseCurX;
	var MouseCurY;
	var MouseDownX;
	var MouseDownY;
	var m_hObj;
	
	this.ExitMapEvent = null;
	this.InitMapEvent = function(pMapBase)
	{
		var hObj = pMapBase.getHObject();
		var OffsetPt = pMapBase.getOffset();
		
		var pMouseMove = function(tEvent)
		{
			var ox = tEvent.screenX - MouseCurX;
			var oy = tEvent.screenY - MouseCurY;
			
			m_hObj.style.left = MouseDownX + (ox<0?ox:0);
			m_hObj.style.width = Math.max(Math.abs(ox),1);
			
			m_hObj.style.top = MouseDownY + (oy<0?oy:0);
			m_hObj.style.height = Math.max(Math.abs(oy),1);
		}
		
		var pMouseUp = function(tEvent)
		{
			DetachEvent(hObj, "mousemove", pMouseMove, true);
			DetachEvent(hObj, "mouseup", pMouseUp, false);
			
			hObj.removeChild(m_hObj);
			m_hObj = null;
			
			var cpt1 = pMapBase.ToMapPoint(MouseDownX, MouseDownY);
			var cpt2 = pMapBase.ToMapPoint(tEvent.clientX - OffsetPt.X, tEvent.clientY - OffsetPt.Y);
			
			if (m_pQuery)
				pMapBase.RemoveElement(m_pQuery);
			m_pQuery = new MapSelectResult(pMapBase, 500, 300);
			m_pQuery.ExecuteGeom(thematicLayer, "RC( " + cpt1.X + " " + cpt1.Y + "," + cpt2.X + " " + cpt2.Y + " )");
			pMapBase.AddElement(m_pQuery);
		}
		
		var pMouseDown = function(tEvent) 
		{
			MouseCurX = tEvent.screenX;
			MouseCurY = tEvent.screenY;
			
			MouseDownX = tEvent.clientX - OffsetPt.X;
			MouseDownY = tEvent.clientY - OffsetPt.Y;
			
			m_hObj = hObj.ownerDocument.createElement("div");
			hObj.appendChild(m_hObj);
			m_hObj.style.position = "absolute";
			m_hObj.style.overflow = "hidden";
			m_hObj.style.left = MouseDownX;
			m_hObj.style.top = MouseDownY;
			m_hObj.style.width = 0;
			m_hObj.style.height = 0;
			m_hObj.style.border = "inset 2px red";
			
			AttachEvent(hObj, "mouseup", pMouseUp, false);
			AttachEvent(hObj, "mousemove", pMouseMove, true);
		}
		
		this.ExitMapEvent = function() {DetachEvent(hObj, "mousedown", pMouseDown, false);}
	
		AttachEvent(hObj, "mousedown", pMouseDown,false);
	}
}

function MapLineString(thematicLayer, isClose)
{
	var m_pQuery;
	var m_pGrap;
	var m_pPart;
	
	this.ExitMapEvent = null;
	this.InitMapEvent = function(pMapBase)
	{
		var hObj = pMapBase.getHObject();
		var OffsetPt = pMapBase.getOffset();

		var pDblClick = function(tEvent)
		{
			if (pMouseMove)
				DetachEvent(hObj, "mousemove", pMouseMove, false);
			DetachEvent(hObj, "dblclick", pDblClick, false);

			if (m_pQuery)
				pMapBase.RemoveElement(m_pQuery);
			m_pQuery = new MapSelectResult(pMapBase, 500, 300);
			if (isClose)
				m_pQuery.ExecuteGeom(thematicLayer, "PG( " + m_pPart.BuildGeom(0) + " )");
			else
				m_pQuery.ExecuteGeom(thematicLayer, "LS( " + m_pPart.BuildGeom(0) + " )");
			pMapBase.AddElement(m_pQuery);
			
			pMapBase.RemoveElement(m_pGrap);
			m_pGrap = null;
		}

		var pMouseMove = null;

		var agent=navigator.userAgent.toLowerCase();
		if(agent.indexOf("msie")!=-1 && document.all)
		{
			pMouseMove = function(tEvent)
			{
				var MouseDownX = tEvent.clientX - OffsetPt.X;
				var MouseDownY = tEvent.clientY - OffsetPt.Y;
				var pt = pMapBase.ToMapPoint(MouseDownX, MouseDownY);
				m_pPart.ModifyLast(pt.X, pt.Y);
				m_pGrap.UpdateElement(1);
			}
		}

		var pMouseDown = function(tEvent) 
		{
			var MouseDownX = tEvent.clientX - OffsetPt.X;
			var MouseDownY = tEvent.clientY - OffsetPt.Y;
			
			var pt = pMapBase.ToMapPoint(MouseDownX, MouseDownY);
			if (m_pGrap==null)
			{
				m_pGrap = new MapGraphic(pMapBase, isClose);
				m_pPart = m_pGrap.AddPart();
				m_pPart.AddPoint(pt.X, pt.Y);
				pMapBase.AddElement(m_pGrap);
				
				AttachEvent(hObj, "dblclick", pDblClick, false);
				if (pMouseMove)
					AttachEvent(hObj, "mousemove", pMouseMove, false);
			}
			m_pPart.AddPoint(pt.X, pt.Y);
			m_pGrap.UpdateElement(1);
		}

		this.ExitMapEvent = function() {DetachEvent(hObj, "mousedown", pMouseDown, false);}
		AttachEvent(hObj, "mousedown", pMouseDown,false);
	}
}

function MapMeasure()
{
	var m_pGrap = null;
	var m_Active = false;
	var m_pPart = null;
	
	this.ExitMapEvent = null;
	this.InitMapEvent = function(pMapBase)
	{
		var hObj = pMapBase.getHObject();
		var OffsetPt = pMapBase.getOffset();
		
		var m_hObj = hObj.ownerDocument.createElement("div");
		hObj.appendChild(m_hObj);
		m_hObj.style.position = "absolute";
		m_hObj.style.border = "outset 1px green"
		m_hObj.style.padding = "2px 2px 2px 2px";
		m_hObj.style.width = 50;
		m_hObj.style.height = 20;
		m_hObj.style.zIndex = 1;

		var pDblClick = function(tEvent)
		{
			DetachEvent(hObj, "mousemove", pMouseMove, false);
			DetachEvent(hObj, "dblclick", pDblClick, false);
			m_Active = false;
		}

		var pUpdateTab = function(tEvent)
		{
			var dX = tEvent.clientX - OffsetPt.X
			var dY = tEvent.clientY - OffsetPt.Y;
			m_hObj.style.left = dX;
			m_hObj.style.top = dY - m_hObj.offsetHeight;
			if (m_pPart)
				m_hObj.innerHTML = m_pPart.ShapeLength() * fullWidth;
				
			var pt = pMapBase.ToMapPoint(dX, dY);
			m_pPart.ModifyLast(pt.X, pt.Y);
		}
		var pMouseMove = null;
		var agent=navigator.userAgent.toLowerCase();
		if(agent.indexOf("msie")!=-1 && document.all)
		{
			pMouseMove = function(tEvent)
			{
				pUpdateTab(tEvent);
				if (m_pGrap) m_pGrap.UpdateElement(1);
			}
		}
		else
		{
			pMouseMove = pUpdateTab;
		}

		var pMouseDown = function(tEvent) 
		{
			var MouseDownX = tEvent.clientX - OffsetPt.X;
			var MouseDownY = tEvent.clientY - OffsetPt.Y;
			
			var pt = pMapBase.ToMapPoint(MouseDownX, MouseDownY);
			if (m_Active == false)
			{
				if (m_pGrap) pMapBase.RemoveElement(m_pGrap);
				m_pGrap = new MapGraphic(pMapBase, false);
				m_pPart = m_pGrap.AddPart();
				m_pPart.AddPoint(pt.X, pt.Y);
				pMapBase.AddElement(m_pGrap);
				AttachEvent(hObj, "dblclick", pDblClick, false);
				AttachEvent(hObj, "mousemove", pMouseMove, false);
				pUpdateTab(tEvent);
				m_Active = true;
			}
			m_pPart.AddPoint(pt.X, pt.Y);
			m_pGrap.UpdateElement(1);
		}

		this.ExitMapEvent = function() 
		{
			DetachEvent(hObj, "mousedown", pMouseDown, false);
			
			if (m_pGrap)
				pMapBase.RemoveElement(m_pGrap);
			m_pGrap = null
			if (m_hObj)
				hObj.removeChild(m_hObj);
			m_hObj = null
			
			if (m_Active)
			{
				DetachEvent(hObj, "mousemove", pMouseMove, false);
				DetachEvent(hObj, "dblclick", pDblClick, false);
				m_Active = false;
			}
		}
		AttachEvent(hObj, "mousedown", pMouseDown,false);
	}
}

function GPoint(dX, dY)
{
	this.X = dX;
	this.Y = dY;
}

function MapGraphicPart(pMapBase, isClose)
{
	var m_Points = new Array;
	var m_MinX = 0;
	var m_MaxX = 0;
	var m_MinY = 0;
	var m_MaxY = 0;
	var m_Modified = false;
	
	this.IsModify = function() {return m_Modified;}
	this.SetModify = function(modify) {m_Modified = modify;}
	this.PointCount = function() {return m_Points.length;}
	this.AddPoint = function(dX, dY)
	{
		if (m_Points.length == 0)
		{
			m_MinX = dX;
			m_MaxX = dX;
			m_MinY = dY;
			m_MaxY = dY;
		}
		else
		{
			if (m_MinX > dX) m_MinX = dX;
			if (m_MaxX < dX) m_MaxX = dX;
			if (m_MinY > dY) m_MinY = dY;
			if (m_MaxY < dY) m_MaxY = dY;
		}
		m_Points.push(new GPoint(dX, dY));
		m_Modified = true;
	}
	this.ModifyLast = function(dX, dY) 
	{
		if (m_Points.length>0)
		{
			m_Points[m_Points.length-1] = new GPoint(dX, dY);
			m_Modified = true;
		}
	}
	this.Empty = function() {m_Points = new Array;m_Modified = true;}
	this.GetMinCoord = function() {return pMapBase.FromMapPoint(m_MinX, m_MinY);}
	this.GetMaxCoord = function() {return pMapBase.FromMapPoint(m_MaxX, m_MaxY);}
	
	this.ShapeLength = function()
	{
		var len = 0;
		var cnt = m_Points.length;
		if (cnt>0)
		{
			var i;
			var oldpt = m_Points[0];
			for (i=1;i<cnt;i++)
			{
				var pt = m_Points[i];
				len += Math.sqrt((pt.X - oldpt.X) * (pt.X - oldpt.X) + (pt.Y - oldpt.Y) * (pt.Y - oldpt.Y))
				oldpt = pt;
			}
		}
		return len;
	}
	
	this.BuildShape = function(isVML, oX, oY, tol)
	{
		var c = false;
		var strShape = "";
		var cnt = m_Points.length;
		if (cnt>0)
		{
			var firstpt = pMapBase.FromMapPoint(m_Points[0].X, m_Points[0].Y);
			strShape = Math.round(firstpt.X-oX) + " " + Math.round(firstpt.Y-oY);
			if (isVML) strShape = "m" + strShape + "l" + strShape;
			var oldpt = firstpt;
			var i;
			for (i=1;i<cnt;i++)
			{
				var pt = pMapBase.FromMapPoint(m_Points[i].X, m_Points[i].Y);
				if (Math.abs(oldpt.X - pt.X) > tol || Math.abs(oldpt.Y - pt.Y) > tol)
				{
					strShape += "," + Math.round(pt.X-oX) + " " + Math.round(pt.Y-oY);
					oldpt = pt;
					c = true;
				}
			}
			
			if (isClose && c && (oldpt.X != firstpt.X || oldpt.Y != firstpt.Y))
				strShape += "," + Math.round(firstpt.X-oX) + " " + Math.round(firstpt.Y-oY);
				
			var firstpt = pMapBase.FromMapPoint(m_Points[0].X, m_Points[0].Y);
			strShape = Math.round(firstpt.X-oX) + " " + Math.round(firstpt.Y-oY);
			if (isVML) strShape = "m" + strShape + "l" + strShape;
			var oldpt = firstpt;
			var oldvec = null;
			var pt = null;
			var lastpt = firstpt;
			var i;
			for (i=1;i<cnt;i++)
			{
				pt = pMapBase.FromMapPoint(m_Points[i].X, m_Points[i].Y);
				if (Math.abs(oldpt.X - pt.X) > tol || Math.abs(oldpt.Y - pt.Y) > tol)
				{
					var vec = pt.Diff(oldpt);
					if((oldvec!=null) && (vec.X * oldvec.Y != vec.Y * oldvec.X))
					{
						strShape += "," + Math.round(oldpt.X-oX) + " " + Math.round(oldpt.Y-oY);
						c = true;
						lastpt = oldpt;
					}
					oldvec = vec;
					oldpt = pt;
				}
			}
				
			if (lastpt.X != oldpt.X || lastpt.Y != oldpt.Y)
			{
				strShape += "," + Math.round(oldpt.X-oX) + " " + Math.round(oldpt.Y-oY);
				lastpt = oldpt;
				c = true;
			}
			
			if (isClose && c && (lastpt.X != firstpt.X || lastpt.Y != firstpt.Y))
				strShape += "," + Math.round(firstpt.X-oX) + " " + Math.round(firstpt.Y-oY);
		}
		if (c)
			return strShape;
		return "";
	}
	
	this.BuildGeom = function(tol)
	{
		var c = false;
		var strShape = "";
		var cnt = m_Points.length;
		if (cnt>0)
		{
			strShape = m_Points[0].X + " " + m_Points[0].Y;
			var oldpt = m_Points[0];
			var c = false;
			var i;
			for (i=1;i<cnt;i++)
			{
				var pt = m_Points[i];
				if (Math.abs(oldpt.X - pt.X) > tol || Math.abs(oldpt.Y - pt.Y) > tol)
				{
					strShape += "," + pt.X + " " + pt.Y;
					oldpt = pt;
					c = true;
				}
			}
			
			if (isClose && c && (oldpt.X != m_Points[0].X || oldpt.Y != m_Points[0].Y))
				strShape += "," + m_Points[0].X + " " + m_Points[0].Y;
		}
		if (c)
			return strShape;
		return "";
	}
}

function MapGraphic(pMapBase, isClose)
{
	var pNode = pMapBase.getHObject();
//public
	this.RemoveSelf = function()
	{
		if (m_hObj)
			pNode.removeChild(m_hObj);
		m_hObj = null;
	}
	
	function IsModify()
	{
		var i;
		for (i=0 ; i<m_Parts.length ; i++)
			if (m_Parts[i].IsModify())
				return true;
		return false;
	}
	function SetModify(modify)
	{
		var i;
		for (i=0 ; i<m_Parts.length ; i++)
			m_Parts[i].SetModify(modify);
	}
	
	this.RebuildElement = null;
	this.UpdateElement = function(imgRatio)
	{
		if (m_Parts.length == 0)
			return;
		this.RebuildElement();
		var minpt = this.GetMinCoord();
		var maxpt = this.GetMaxCoord();
		if (minpt == null || maxpt == null)
			return;
		var rx = 0;
		var ry = 0;
		if (m_CurWidth!=0 && m_CurHeight!=0)
		{
			rx = (maxpt.X - minpt.X) / m_CurWidth;
			ry = (maxpt.Y - minpt.Y) / m_CurHeight;
		}
		
		m_hObj.style.left = Math.round(minpt.X) - 5 * rx;
		m_hObj.style.top = Math.round(minpt.Y) - 5 * ry;
		m_hObj.style.width = maxpt.X - minpt.X + 10 * rx;
		m_hObj.style.height = maxpt.Y - minpt.Y + 10 * ry;
	}

	this.AddPart = function()
	{
		var pPart = new MapGraphicPart(pMapBase, isClose);
		m_Parts.push(pPart);
		return pPart;
	}
	this.GetPart = function(nIndex)
	{
		return m_Parts[nIndex];
	}
	this.GetMinCoord = function()
	{
		var i;
		var minpt = null;
		if (m_Parts.length>0)
		{
			minpt = m_Parts[0].GetMinCoord();
			for (i=1 ; i<m_Parts.length ; i++)
			{	
				var pt = m_Parts[i].GetMinCoord()
				if (minpt.X > pt.X) minpt.X = pt.X;
				if (minpt.Y > pt.Y) minpt.Y = pt.Y;
			}
		}
		return minpt;
	}
	this.GetMaxCoord = function() 
	{
		var i;
		var maxpt = null;
		if (m_Parts.length>0)
		{
			maxpt = m_Parts[0].GetMaxCoord();
			for (i=1 ; i<m_Parts.length ; i++)
			{	
				var pt = m_Parts[i].GetMaxCoord()
				if (maxpt.X < pt.X) maxpt.X = pt.X;
				if (maxpt.Y < pt.Y) maxpt.Y = pt.Y;
			}
		}
		return maxpt;
	}
	
//private
	var m_hObj;
	var m_Parts = new Array;
	var m_CurWidth;
	var m_CurHeight;

//constructor
	var agent=navigator.userAgent.toLowerCase();
	if(agent.indexOf("msie")!=-1&&document.all)
	{
		m_hObj = pNode.ownerDocument.createElement("vml:shape");
		m_hObj.style.position = "absolute";
		m_hObj.style.overflow = "hidden";
		m_hObj.coordorigin = "-5 -5";
		m_hObj.coordsize = "1 1";
		m_hObj.fill = false;
		m_hObj.filled = false;
		m_hObj.StrokeColor = "#FFFF80";
		m_hObj.StrokeWeight = 3;
		/*
		var o=document.createElement("v:stroke");
		o.joinstyle="round";
		o.endcap="round";
		o.opacity=1;
		o.color="#FFFF80";
		o.weight=3;
		m_hObj.appendChild(o);
		*/
		this.RebuildElement = function()
		{
			if (m_Parts.length == 0)
				return;
				
			var minpt = this.GetMinCoord();
			var maxpt = this.GetMaxCoord();
			if (minpt == null || maxpt == null)
				return;
			m_CurWidth = maxpt.X - minpt.X;
			m_CurHeight = maxpt.Y - minpt.Y;
			m_hObj.coordsize = (m_CurWidth + 10) + " " + (m_CurHeight + 10);
			var i;
			var strPath = "";
			for (i=0;i<m_Parts.length;i++)
				strPath += m_Parts[i].BuildShape(true, minpt.X, minpt.Y, 4);
				
			m_hObj.path = strPath + "e";
			SetModify(false);
		}
	}
	else if(agent.indexOf("mozilla")!=-1)
	{
		m_hObj = pNode.ownerDocument.createElement("img");
		m_hObj.style.position = "absolute";
		m_hObj.style.MozUserSelect="none";
		this.RebuildElement = function() 
		{
			if (m_Parts.length == 0)
				return;
				
			var minpt = this.GetMinCoord();
			var maxpt = this.GetMaxCoord();
			if (minpt == null || maxpt == null)
				return;
			m_CurWidth = maxpt.X - minpt.X;
			m_CurHeight = maxpt.Y - minpt.Y;
			var strPath = "";
			if (m_Parts.length>0)
			{
				var i=0;
				strPath += "(" + m_Parts[i].BuildShape(false, minpt.X, minpt.Y, 4) + ")";
				for (i=1;i<m_Parts.length;i++)
					strPath += ",(" + m_Parts[i].BuildShape(false, minpt.X, minpt.Y, 4) + ")";
			}
			var hr = new XMLHttpRequest;
			hr.onreadystatechange = function()
			{
				if (hr.readyState == 4)
				{
					m_hObj.src = "GImg.aspx";
				}
			}
			hr.open('POST', "GImg.aspx", true);
			hr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			hr.send("Geometry=POLYGON(" + escape(strPath) + ")");
			
			SetModify(false);
		}
	}
	m_hObj.style.left = 0;
	m_hObj.style.top = 0;
	m_hObj.style.width = 100;
	m_hObj.style.height = 100;
	
	pNode.appendChild(m_hObj);
}
function FourToTen(sn)
{
	var ar = new Array();
	for(i = 0; i < sn.length; i++)
	{
		ar[i] = sn.substring(i,i + 1);	
		
	}
	ar.reverse();
	var result = 0;
	for(i = ar.length -1; i >= 0; i--)
	{
		result += parseInt(ar[i]) * Math.pow(4,i);
	}
	ar = null;
	return result;
}
