SIX.Navigator = function (channel, map)
{
	SIX.addRef(this);
	var theNavigator = this;
	this.div = null;
	this.channel = channel;	
	this.map = map;
	this.toolGroup = new SIX.ToolGroup();
	channel.addToolGroup(this.toolGroup);	
	
	map.attach(this, channel);	
	map.addCallback(SIX.eMapCallbacks.ONEXTENTCHANGE, 
					function (theNavigator) {
						if (theNavigator.channel == SIX.App.getCurrentChannel())
							theNavigator.updateZoom();
					}, theNavigator);	
					
	map.addCallback(SIX.eMapCallbacks.ONLOAD, 
					function (theNavigator) {
						if (theNavigator.channel == SIX.App.getCurrentChannel())
						{
							if (this.scale > 2 * theNavigator.dMinScaleDefault)
							{
								//At larger scales, revert to default.
								theNavigator.setZoomScale(theNavigator.dMinScaleDefault, theNavigator.dMaxScale);
							}
							else
							{
								//At smaller scales, adjust minimum scale to best map scale.
								var dBestScale = this.getBestScale();
								if (dBestScale > 0 && dBestScale < theNavigator.dMinScaleDefault)
									theNavigator.setZoomScale(dBestScale, theNavigator.dMaxScale);
							}				
							theNavigator.updateZoom();
						}
					}, theNavigator);							
	
	this.name = "Navigator";
	this.uid = SIX.Uid.getUid("navigator");
	this.mapUid = SIX.Uid.getUid("map");
	this.backgroundUid = SIX.Uid.getUid("background");
	this.foregroundUid = SIX.Uid.getUid("foreground");
	this.move1Uid = SIX.Uid.getUid("move");
	this.move2Uid = SIX.Uid.getUid("move");
	this.sMoveNavigatorToolTip = "Click and drag to move the navigator";
	this.nPixelX = null;
	this.nPixelY = null;
	this.dZoomFactor = 0.0;
	this.dZoomIncrement = 0.025;
	this.dMaxPanPercent = 10;
	this.nPanAreaRadius = 37;
	this.nPanAreaCenterX = 67;
	this.nPanAreaCenterY = 68;
	this.bMouseDownInPanArea = false;
	this.bInPanArea = false;
	this.bMouseDraggedOverZoomAll = false; 
	
	this.zoomAllUid = SIX.Uid.getUid("zoomAll");
	this.zoomAllMapUid = SIX.Uid.getUid("zoomAllMap");
	
	this.dFadeMinOpacity = 0.35;
	this.dFadeInterval = 50;//milliseconds
	this.dFadeIncrement = 1 / 32.0;
	this.tFadeTimeout = null;

	this.panTool = this.toolGroup.addTool(new SIX.Tool.Pan(this.toolGroup, "navigator_pan", "Click and drag the map to pan around"));
	this.panTool.setClass("navigatorPan");
	
	this.zoomBoxTool = this.toolGroup.addTool(new SIX.Tool.ZoomBox(this.toolGroup, "navigator_zoombox", "Click and drag the map to zoom into an area"));
	this.zoomBoxTool.setClass("navigatorZoomBox");
		
	this.imagesTool = this.toolGroup.addTool(new SIX.Tool(this.toolGroup, SIX.eToolTypes.TOGGLE, "navigator_images", "Click to change the image background"));
	this.imagesToolWindow = null;
	var fnImagesToolOnClick = function (map, theNavigator) {
									if (theNavigator.imagesToolWindow)
									{
										if (this.bActive)
										{
											theNavigator.imagesToolWindow.showWin();
											var tool = this;
											var fnOnWindowHide = function() {
												with ({tool : tool})
												{
													tool.onClick();
												}
											}
											theNavigator.imagesToolWindow.setOnHideCallback(fnOnWindowHide);
										}
										else 
										{
											theNavigator.imagesToolWindow.clearOnHideCallback();
											theNavigator.imagesToolWindow.hideWin();
										}
									}
									SIX.App.onWindowResize();
								};
	this.imagesTool.addCallback(SIX.eToolCallbacks.ONACTIVATE, fnImagesToolOnClick, theNavigator);
	this.imagesTool.addCallback(SIX.eToolCallbacks.ONDEACTIVATE, fnImagesToolOnClick, theNavigator);
	
	this.imagesTool.setClass("navigatorImages");		
		
	this.infoTool = this.toolGroup.addTool(new SIX.Tool.Query(this.toolGroup, SIX.eQueryTypes.POINT_OR_RECTANGLE, "navigator_info", 
											"Use the pointer to click on screen (or click and drag) to get more information on  the displayed Property / Topographic information"));
	//this.infoTool.setEnabled(false);
	this.infoTool.setClass("navigatorInfo");
	var infoTool = this.infoTool;

	this.weatherTool = this.toolGroup.addTool(new SIX.Tool(this.toolGroup, SIX.eToolTypes.TOGGLE, "navigator_weather", "Click to display weather and fire hotspot information"));	
	var fnWeatherToolOnClick = function (map, theNavigator) {
									if (!theNavigator.infoTool.bActive)
										theNavigator.panTool.activate();//Set pan tool active if info tool was active when disabled.
								
									var channelCurrent = SIX.App.getCurrentChannel();
									var sUnavailableServices = "";
									for (var i=0; i<theNavigator.aWeatherToolServices.length; i++)
									{
										var service = theNavigator.aWeatherToolServices[i];
										if (service.catalog.channel == channelCurrent)
										{
											service.setVisibleLayersSelectionState(this.bActive);
											if (this.bActive && (!service.loaded || !service.active || (service.nLayersLoadState != SIX.eLayersLoadState.LOADED)))
												sUnavailableServices += (sUnavailableServices != "" ? "\n" : "") + "- " + service.name;					
										}
									}
									if (sUnavailableServices != "")
										alert ("The following web services are unavailable:\n\n" + sUnavailableServices);
								};
	this.weatherTool.addCallback(SIX.eToolCallbacks.ONACTIVATE, fnWeatherToolOnClick, theNavigator); 
	this.weatherTool.addCallback(SIX.eToolCallbacks.ONDEACTIVATE, fnWeatherToolOnClick, theNavigator); 
	this.weatherTool.setClass("navigatorWeather");
	
	this.topoTool = this.toolGroup.addTool(new SIX.Tool(this.toolGroup, SIX.eToolTypes.TOGGLE, "navigator_topo", "Click to display roads, points of interest &amp; localities"));
	var fnTopoToolOnClick = function (map, theNavigator) {
									var infoTool = theNavigator.infoTool;
									var panTool = theNavigator.panTool;
									var bInfoToolActive = infoTool.bActive;
									//infoTool.setEnabled(this.bActive || theNavigator.propertiesTool.bActive);
									if (bInfoToolActive && !infoTool.bEnabled)
										panTool.activate();//Set pan tool active if info tool was active when disabled.
								
									var channelCurrent = SIX.App.getCurrentChannel();
									for (var i=0; i<theNavigator.aTopoToolServices.length; i++)
									{
										var service = theNavigator.aTopoToolServices[i];			
										if (service.catalog.channel == channelCurrent)
											service.setVisibleLayersSelectionState(this.bActive);
									}
								};
	this.topoTool.addCallback(SIX.eToolCallbacks.ONACTIVATE, fnTopoToolOnClick, theNavigator); 
	this.topoTool.addCallback(SIX.eToolCallbacks.ONDEACTIVATE, fnTopoToolOnClick, theNavigator); 
	this.topoTool.setClass("navigatorTopo");
	
	this.propertiesTool = this.toolGroup.addTool(new SIX.Tool(this.toolGroup, SIX.eToolTypes.TOGGLE, "navigator_themes", "Click to display Property addresses, Property Lots, suburbs, Local Govt authority boundaries"));
	var propertiesToolOnClick = function (map, theNavigator) {
									var infoTool = theNavigator.infoTool;
									var topoTool = theNavigator.topoTool;
									var panTool = theNavigator.panTool;
									var bInfoToolActive = infoTool.bActive;
									//infoTool.setEnabled(this.bActive || topoTool.bActive);
									if (bInfoToolActive && !infoTool.bEnabled)
										panTool.activate();//Set pan tool active if info tool was active when disabled.
								
									var channelCurrent = SIX.App.getCurrentChannel();
									for (var i=0; i<theNavigator.aPropertiesToolServices.length; i++)
									{
										var service = theNavigator.aPropertiesToolServices[i];			
										if (service.catalog.channel == channelCurrent)
											service.setVisibleLayersSelectionState(this.bActive);
									}
								};
	this.propertiesTool.addCallback(SIX.eToolCallbacks.ONACTIVATE, propertiesToolOnClick, theNavigator);
	this.propertiesTool.addCallback(SIX.eToolCallbacks.ONDEACTIVATE, propertiesToolOnClick, theNavigator);
	this.propertiesTool.setClass("navigatorProperties");

	this.aImagesToolServices = new Array();
	this.aPropertiesToolServices = new Array();
	this.aTopoToolServices = new Array();
	this.aWeatherToolServices = new Array();

	this.panUid = SIX.Uid.getUid("pan");	
	this.zoomBarMinZoomUid = SIX.Uid.getUid("zoomBarMinZoom"); 
	this.zoomBarMaxZoomUid = SIX.Uid.getUid("zoomBarMaxZoom");
	this.zoomBarScaleUid = SIX.Uid.getUid("zoomBarScale");
	this.zoomBarPointerUid = SIX.Uid.getUid("zoomBarPointer");
	this.zoomPointerStartUid = SIX.Uid.getUid("zoomPointerStart");
	this.aZoomTrackCoords = [[0,0],[6,-10],[17,-20],[26,-28],[46,-32],[54,-32],[62,-31],[74,-27],[84,-23],[91,-15],[103,0]];
	this.dMinScaleDefault = 10000;
	this.dMaxScaleDefault = 8250000;
	this.dMinScale = this.dMinScaleDefault;
	this.dMaxScale = this.dMaxScaleDefault;
	this.dMaxZoomPower = Math.log (this.dMaxScale / this.dMinScale) / Math.LN2;
	this.tZoomBar = null;	
}

SIX.Navigator.prototype.onClickZoomIn = function ()
{
	this.setZoom(Math.min(1, this.dZoomFactor + this.dZoomIncrement));
}

SIX.Navigator.prototype.onClickZoomOut = function ()
{
	this.setZoom(Math.max(0, this.dZoomFactor - this.dZoomIncrement));
}

SIX.Navigator.prototype.fade = function (dOpacity)
{
	if (this.tFadeTimeout)
		clearTimeout(this.tFadeTimeout);
	
	dOpacity = Math.max(this.dFadeMinOpacity, dOpacity);
	
	if (SIX.App.isIE)
	{
		var elemForeground = document.getElementById(this.foregroundUid);
		if (elemForeground)
			elemForeground.style.visibility = "hidden";

		var elemBackground = document.getElementById(this.backgroundUid);
		if (elemBackground)
			elemBackground.style.visibility = "visible";
	}
	
	var elem = document.getElementById(this.uid);
	if (elem)
	{
		var images = elem.getElementsByTagName("img");
		if (images)
		{
			for (var i=0; i<images.length; i++)
			{
				var elemImg = images[i];
				if (!SIX.App.isIE || (elemForeground && (elemImg != elemForeground)))
				{
					elemImg.style.filter = "alpha(opacity=" + Math.round(dOpacity * 100) + ")";
					elemImg.style.opacity = dOpacity;
					elemImg.style.MozOpacity = dOpacity;
				}
			}
		}
	}
	
	if (dOpacity > this.dFadeMinOpacity)
	{
		dOpacity -= this.dFadeIncrement;
		this.tFadeTimeout = setTimeout(this.myself + ".fade(" + dOpacity + ")", this.dFadeInterval);
	}
}

SIX.Navigator.prototype.onMouseOut = function ()
{
	if (this.tFadeTimeout)
		clearTimeout(this.tFadeTimeout);
		
	this.fade(1.0 - this.dFadeIncrement);
}

SIX.Navigator.prototype.onMouseOver = function ()
{
	if (this.tFadeTimeout)
		clearTimeout(this.tFadeTimeout);

	if (SIX.App.isIE)
	{
		var elemForeground = document.getElementById(this.foregroundUid);
		if (elemForeground)
			elemForeground.style.visibility = "visible";


		var elemBackground = document.getElementById(this.backgroundUid);
		if (elemBackground)
			elemBackground.style.visibility = "hidden";
	}
	
	var elem = document.getElementById(this.uid);
	if (elem)
	{
		var images = elem.getElementsByTagName("img");
		if (images)
		{
			for (var i=0; i<images.length; i++)
			{
				var elemImg = images[i];
				if (!SIX.App.isIE || (elemForeground && (elemImg != elemForeground)))
				{
					elemImg.style.filter = null;
					elemImg.style.opacity = null;
					elemImg.style.MozOpacity = null;
				}
			}
		}
	}	
}

SIX.Navigator.prototype.init = function ()
{
	if (!this.div)
	{
		var theNav = this;
		this.div = SIX.Util.createElement("div", "navigatorTopRight", this.uid);
		this.div.onmouseover = function () {return theNav.onMouseOver()};
		this.div.onmouseout = function () {return theNav.onMouseOut()};
		this.div.innerHTML = "<div style='position:relative;top:0px;left:0px'>" +	
		(SIX.App.isIE ? "<img id='" + this.backgroundUid + "' class='navigatorBackground' " + SIX.App.imageSrc("images/navigatorBackground") + " border='0' title=''/>" : "") +
		"<img id='" + this.foregroundUid + "' class='navigatorForeground' " + 
		(SIX.App.isIE ? "style='filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"" + encodeURI("images/navigator.png") + "\",sizingMethod=\"scale\",enabled=true)'" : "") + 
		" src='" + (SIX.App.isIE ? "images/transparent.gif" : "images/navigator.png") + "'  border='0' title='Navigator' usemap='#" + this.mapUid + "'/>" + 
		"<map id='" + this.mapUid + "' name='" + this.mapUid + "'>" +
		"<area id='" + this.panUid + "' shape='circle' coords='" + this.nPanAreaCenterX + "," + this.nPanAreaCenterY + "," + this.nPanAreaRadius + "' nohref='nohref' " + 
		" onmousemove='" + this.myself + ".onMouseMovePanArea()'" + 
		" onmouseup='" + this.myself + ".onMouseUpPanArea()'" + 
		" onmousedown='" + this.myself + ".onMouseDownPanArea(event ? event : null)'" + 
		" onmouseover='" + this.myself + ".onMouseOverPanArea()'" + 
		" onmouseout='" + this.myself + ".onMouseOutPanArea()'/>" +	
		"<area id='" + this.zoomBarScaleUid + "' shape='poly' coords='15,4,15,42,30,42,68,26,100,42,123,42,123,4' nohref='nohref' />" +		
		"<area id='" + this.move1Uid + "' style='cursor:move' shape='rect' coords='0,62,30,72' nohref='nohref' title='" + this.sMoveNavigatorToolTip + "' />" +
		"<area id='" + this.move2Uid + "' style='cursor:move' shape='rect' coords='105,62,145,72' nohref='nohref' title='" + this.sMoveNavigatorToolTip + "' />" +	
		"</map>" +
		"<img id='" + this.zoomAllUid + "' class='navigatorZoomAll' " + SIX.App.imageSrc("images/navigator_zoomall") + " border='0' title='Click to zoom to state' usemap='#" + this.zoomAllMapUid + "'/>" +
		"<map id='" + this.zoomAllMapUid + "' name='" + this.zoomAllMapUid + "'>" +
		"<area shape='poly' coords='2,13,13,2,24,13,13,24' nohref='nohref'" +
		" onmousemove='" + this.myself + ".onMouseMoveZoomAll()'" + 
		" onmouseup='" + this.myself + ".onMouseUpZoomAll()'" + 
		" onmousedown='" + this.myself + ".onMouseDownZoomAll()'" + 
		" onmouseover='" + this.myself + ".onMouseOverZoomAll()'" +
		" onmouseout='" + this.myself + ".onMouseOutZoomAll()'/>" +	
		"</map>" +	
		"<div id='" + this.zoomPointerStartUid + "' class='navigatorZoomPointerStart'>" + 
		"<div style='position:absolute;top:0px;left:0px;width:1px;height:1px;overflow:visible'>" + /*Zoom pointer container*/
		"<img style='position:relative;top:-2px;left:-2px;vertical-align:top' id='" + this.zoomBarPointerUid + "' " + SIX.App.imageSrc("images/zoombar_pointer") + " border='0' title='Zoom'/>" + 	
		"</div>" +
		"</div>" +
		"</div>" +
		"<img class='navigatorZoomOut' " + SIX.App.imageSrc("images/navigator_zoomout") + " border='0' title='Zoom out' onclick='" + this.myself + ".onClickZoomOut()' onmouseover='this.src = \"images/navigator_zoomout_on.gif\"' onmouseout='this.src = \"images/navigator_zoomout.gif\"'/>" + 
		"<img class='navigatorZoomIn' " + SIX.App.imageSrc("images/navigator_zoomin") + " border='0' title='Zoom in' onclick='" + this.myself + ".onClickZoomIn()' onmouseover='this.src = \"images/navigator_zoomin_on.gif\"' onmouseout='this.src = \"images/navigator_zoomin.gif\"'/>";
		var divToolGroup = this.toolGroup.init();
		if (divToolGroup)
			this.div.appendChild(divToolGroup);
	}
	
	SIX.App.addMouseAction(this.zoomBarPointerUid,this,0,true);
	SIX.App.addMouseAction(this.zoomBarScaleUid,this,0,true);			
	SIX.App.addMouseAction(this.move1Uid,this,0,true);	
	SIX.App.addMouseAction(this.move2Uid,this,0,true);
	
	return this.div;
}

SIX.Navigator.prototype.action = function (action, moving, x, y) 
{
	if (SIX.App.mouseCurrentAction.uid == this.zoomBarPointerUid || 
		SIX.App.mouseCurrentAction.uid == this.zoomBarScaleUid)
		this.setZoom(this.getZoom(x,y));
	else if ((SIX.App.mouseCurrentAction.uid == this.move1Uid) ||
			(SIX.App.mouseCurrentAction.uid == this.move2Uid))
		this.move(moving, x, y);
}

SIX.Navigator.prototype.move = function (moving, nPixelX, nPixelY) 
{
	var elemNavigator = document.getElementById(this.uid);
	if (elemNavigator)
	{
		if (moving)
		{
			var nNavRight = parseInt(SIX.Util.getStyle(elemNavigator, "right"));
			var nNavTop = parseInt(SIX.Util.getStyle(elemNavigator, "top"));
			var nNavLeft = parseInt(SIX.Util.getStyle(elemNavigator, "left"));
			var nNavBottom = parseInt(SIX.Util.getStyle(elemNavigator, "bottom"));
			var nNavWidth = elemNavigator.offsetWidth;
			var nNavHeight = elemNavigator.offsetHeight;
			var nMapWidth = this.map.width;
			var nMapHeight = this.map.height;
			
			var eHorizontalAlign = {LEFT : 0, RIGHT : 1};
			var eVerticalAlign = {TOP : 0, BOTTOM : 1};
			
			var nHorizontalAlign = (elemNavigator.className.indexOf("Left") != -1 ? eHorizontalAlign.LEFT : eHorizontalAlign.RIGHT);
			var nVerticalAlign = (elemNavigator.className.indexOf("Top") != -1 ? eVerticalAlign.TOP : eVerticalAlign.BOTTOM);
					
			if (nHorizontalAlign == eHorizontalAlign.RIGHT)	
			{
				var nRight = (this.nPixelX != null ? this.nPixelX - nPixelX + nNavRight : nNavRight);
				if (nRight < 0)
					nRight = 0;
				else if (nRight + nNavWidth > nMapWidth) 
					nRight = nMapWidth - nNavWidth;
				
				if ((nRight + nNavWidth / 2) > nMapWidth / 2)
				{
					nHorizontalAlign = eHorizontalAlign.LEFT;
					elemNavigator.style.right = ""; 
					nNavLeft = nMapWidth - nRight - nNavWidth;	
				}
				else 
				{
					nHorizontalAlign = eHorizontalAlign.RIGHT;
					elemNavigator.style.left = "";
					nNavRight = nRight;	
				}					
			}			
			else if (nHorizontalAlign == eHorizontalAlign.LEFT)
			{
				var nLeft = (this.nPixelX != null ? nPixelX - this.nPixelX + nNavLeft : nNavLeft);
				if (nLeft < 0)
					nLeft = 0;	
				else if (nLeft + nNavWidth > nMapWidth)		
					nLeft = nMapWidth - nNavWidth;
					
				if ((nLeft + nNavWidth / 2) > nMapWidth / 2)
				{		
					nHorizontalAlign = eHorizontalAlign.RIGHT;
					elemNavigator.style.left = "";		
					nNavRight = nMapWidth - nLeft - nNavWidth;		
				}
				else 
				{
					nHorizontalAlign = eHorizontalAlign.LEFT;
					elemNavigator.style.right = "";	
					nNavLeft = nLeft;			
				}					
			}
	
			if (nVerticalAlign == eVerticalAlign.TOP)
			{
				var nTop = (this.nPixelY != null ? nPixelY - this.nPixelY + nNavTop : nNavTop);	
				if (nTop < 0)
					nTop = 0;	
				else if (nTop + nNavHeight > nMapHeight)		
					nTop = nMapHeight - nNavHeight;		
					
				if ((nTop + nNavHeight / 2) > nMapHeight / 2)
				{	
					nVerticalAlign = eVerticalAlign.BOTTOM;
					elemNavigator.style.top = "";						
					nNavBottom = nMapHeight - nTop - nNavHeight;			
				}
				else
				{
					nVerticalAlign = eVerticalAlign.TOP;
					elemNavigator.style.bottom = "";
					nNavTop = nTop;				
				}
			}
			else if (nVerticalAlign == eVerticalAlign.BOTTOM)
			{
				var nBottom = (this.nPixelY != null ? this.nPixelY - nPixelY + nNavBottom : nNavBottom);		
				if (nBottom < 0)
					nBottom = 0;	
				else if (nBottom + nNavHeight > nMapHeight)		
					nBottom = nMapHeight - nNavHeight;	
					
				if ((nBottom + nNavHeight / 2) > nMapHeight / 2)
				{
					nVerticalAlign = eVerticalAlign.TOP;
					elemNavigator.style.bottom = "";	
					nNavTop = nMapHeight - nBottom - nNavHeight;				
				}
				else 
				{	
					nVerticalAlign = eVerticalAlign.BOTTOM;
					elemNavigator.style.top = "";				
					nNavBottom = nBottom;
				}									
			} 
			
			if (nHorizontalAlign == eHorizontalAlign.LEFT && nVerticalAlign == eVerticalAlign.TOP)
			{
				elemNavigator.setAttribute("class", "navigatorTopLeft");
				elemNavigator.setAttribute("className", "navigatorTopLeft");
				elemNavigator.style.top = nNavTop + "px";
				elemNavigator.style.left = nNavLeft + "px";
			}
			else if (nHorizontalAlign == eHorizontalAlign.RIGHT && nVerticalAlign == eVerticalAlign.TOP)
			{
				elemNavigator.setAttribute("class", "navigatorTopRight");
				elemNavigator.setAttribute("className", "navigatorTopRight");
				elemNavigator.style.top = nNavTop + "px";
				elemNavigator.style.right = nNavRight + "px";				
			}	
			else if (nHorizontalAlign == eHorizontalAlign.RIGHT && nVerticalAlign == eVerticalAlign.BOTTOM)
			{
				elemNavigator.setAttribute("class", "navigatorBottomRight");
				elemNavigator.setAttribute("className", "navigatorBottomRight");
				elemNavigator.style.bottom = nNavBottom + "px";
				elemNavigator.style.right = nNavRight + "px";				
			}			
			else
			{
				elemNavigator.setAttribute("class", "navigatorBottomLeft");
				elemNavigator.setAttribute("className", "navigatorBottomLeft");
				elemNavigator.style.bottom = nNavBottom + "px";
				elemNavigator.style.left = nNavLeft + "px";				
			}
		}
		this.nPixelX = nPixelX;
		this.nPixelY = nPixelY;	
	}
}

SIX.Navigator.prototype.infoToolActive = function ()
{
	return (this.infoTool.bActive);
}

SIX.Navigator.prototype.addInfoToolService = function (service)
{
	this.infoTool.attachService(service);
}

SIX.Navigator.prototype.addImagesToolService = function (service)
{
	this.aImagesToolServices[this.aImagesToolServices.length] = service;
}

SIX.Navigator.prototype.attachImagesToolWindow = function (win)
{
	this.imagesToolWindow = win;
}

SIX.Navigator.prototype.addPropertiesToolService = function (service)
{
	this.aPropertiesToolServices[this.aPropertiesToolServices.length] = service;
}

SIX.Navigator.prototype.addTopoToolService = function (service)
{
	this.aTopoToolServices[this.aTopoToolServices.length] = service;
}

SIX.Navigator.prototype.addWeatherToolService = function (service)
{
	this.aWeatherToolServices[this.aWeatherToolServices.length] = service;
}

SIX.Navigator.prototype.setZoomScale = function (dMinScale, dMaxScale)
{
	this.dMinScale = dMinScale;
	this.dMaxScale = dMaxScale;
	this.dMaxZoomPower = Math.log (this.dMaxScale / this.dMinScale) / Math.LN2;
}

SIX.Navigator.prototype.getZoom = function (nPixelX, nPixelY) 
{
	var dZoomFactor = 0.0;
	var elemZoomBarPointer = document.getElementById(this.zoomBarPointerUid);
	var elemDiv = getParent(elemZoomBarPointer, "div");
	if (elemDiv)
	{
		var elemDivZoomBarPointerTrack = document.getElementById(this.zoomPointerStartUid);
		var nPosX = SIX.Util.findPosX(elemDivZoomBarPointerTrack);
		var nPointerX = Math.round(nPixelX) - nPosX;
		var nPointerTrackWidth = this.aZoomTrackCoords[this.aZoomTrackCoords.length - 1][0];
		if (nPointerX > nPointerTrackWidth)
			nPointerX = nPointerTrackWidth;
		else if (nPointerX < 0)
			nPointerX = 0;
		dZoomFactor = nPointerX / nPointerTrackWidth;
	}
	return dZoomFactor;
}

SIX.Navigator.prototype.setZoom = function (dZoomFactor) 
{
	if (dZoomFactor < 0) dZoomFactor = 0;
	if (dZoomFactor > 1) dZoomFactor = 1;
	this.dZoomFactor = dZoomFactor;
	this.updateZoomPointer();
		
	if (!this.tZoomBar)
		this.tZoomBar = setTimeout(this.myself + ".updateMapZoom()", 100);
}

SIX.Navigator.prototype.updateZoomPointer = function () 
{
	var elemZoomBarPointer = document.getElementById(this.zoomBarPointerUid);
	if (elemZoomBarPointer && elemZoomBarPointer.parentNode)
	{
		var elemDiv = elemZoomBarPointer.parentNode;
		var elemDivZoomBarPointerTrack = document.getElementById(this.zoomPointerStartUid);
		var nPointerX = Math.round(this.dZoomFactor * this.aZoomTrackCoords[this.aZoomTrackCoords.length - 1][0]);
		elemDiv.style.left = nPointerX + "px";
		
		var nPointerY = this.calcZoomPointerY(nPointerX);
		elemDiv.style.top = parseInt(nPointerY) + "px";
		this.setZoomBarBackground(nPointerX);
	}
}

SIX.Navigator.prototype.calcZoomPointerY = function (nPointerX)
{
	var nPointerY = 0;
	for (var i=0; i<this.aZoomTrackCoords.length-1; i++)
	{
		var aCoord = this.aZoomTrackCoords[i];
		var aCoordNext =  this.aZoomTrackCoords[i+1];
		if (nPointerX >= aCoord[0] && nPointerX <= aCoordNext[0])
		{
			nPointerY = Math.round(aCoord[1] + (aCoordNext[1] - aCoord[1]) * (nPointerX - aCoord[0]) / (aCoordNext[0] - aCoord[0]));
			break;
		}
	}
	return nPointerY;
}

SIX.Navigator.prototype.setZoomBarBackground = function (nPointerX)
{
	var elemDivZoomBarPointerTrack = document.getElementById(this.zoomPointerStartUid);
	var elemDivZoomBarMinZoom = document.getElementById(this.zoomBarMinZoomUid);
	if (elemDivZoomBarPointerTrack && elemDivZoomBarMinZoom)
	{
		var nPointerTrackWidth = this.aZoomTrackCoords[this.aZoomTrackCoords.length - 1][0];
		var nZoomBarWidth = elemDivZoomBarMinZoom.offsetWidth;
		var nPointerTrackPosX = SIX.Util.findPosX(elemDivZoomBarPointerTrack);
		var nZoomBarPosX = SIX.Util.findPosX(elemDivZoomBarMinZoom);
		var nOffsetLeft = nPointerTrackPosX - nZoomBarPosX;
		if (nOffsetLeft < 0) nOffsetLeft = 0;
		var nOffsetRight = nZoomBarWidth - nOffsetLeft - nPointerTrackWidth;
		if (nOffsetRight < 0) nOffsetRight = 0; 
		
		var nPixelClipX = 0;
		if (nPointerX > 0 && nPointerX < nPointerTrackWidth)
			nPixelClipX = nOffsetLeft + nPointerX;
		else if (nPointerX == nPointerTrackWidth)
			nPixelClipX = nOffsetLeft + nPointerX + nOffsetRight;
		elemDivZoomBarMinZoom.style.clip = "rect(auto auto auto " + nPixelClipX + "px)";
	}
}

SIX.Navigator.prototype.calcTransparency = function ()
{
	var dTransparency = 0.0;
	var elemPointer = document.getElementById(this.transparencyPointerUid);
	if (elemPointer)
	{
		var elemDiv = getParent(elemPointer, "div");
		if (elemDiv)
		{
			var elemDivZoomBarPointerTrack = document.getElementById(this.zoomPointerStartUid);
			var nPointerTrackWidth = this.aZoomTrackCoords[this.aZoomTrackCoords.length - 1][0];
			var nPointerX = parseInt(elemDiv.style.left);
		
			dTransparency = 100 * nPointerX / nPointerTrackWidth;		
		}
	}
	return dTransparency;
}

SIX.Navigator.prototype.calcZoomScale = function ()
{
	var dScale = this.dMinScale * Math.pow(2, (1 - this.dZoomFactor) * this.dMaxZoomPower);
	return dScale;
}

SIX.Navigator.prototype.updateZoom = function ()
{
	if (this.map.scale > 0)
	{
		var dZoomFactor = 1 - Math.log(this.map.scale / this.dMinScale) / (Math.LN2 * this.dMaxZoomPower);
		if (dZoomFactor < 0) dZoomFactor = 0;
		if (dZoomFactor > 1) dZoomFactor = 1;
		this.dZoomFactor = dZoomFactor;
		this.updateZoomPointer();
	}
}

SIX.Navigator.prototype.updateMapZoom = function ()
{		
	if (this.tZoomBar)
	{
		clearTimeout(this.tZoomBar);
		this.tZoomBar = null;
	}
	this.map.zoom(this.calcZoomScale());
}

SIX.Navigator.prototype.onMouseUpPanArea = function () 
{
	this.bMouseDownInPanArea = false;
	this.bInPanArea = false;
	this.cancelPan();
}

SIX.Navigator.prototype.onMouseOverPanArea = function () 
{
	if (!this.bMouseDraggedOverZoomAll)
	{
		this.bMouseDownInPanArea = false;
		this.bInPanArea = false;
		this.cancelPan();
	}
	this.bMouseDraggedOverZoomAll = false;
}

SIX.Navigator.prototype.onMouseOutPanArea = function () 
{
	this.bMouseDraggedOverZoomAll = false;
	this.bInPanArea = false;
	this.cancelPan();
}

SIX.Navigator.prototype.onMouseDownPanArea = function (evt) 
{
	if (evt && evt.preventDefault)
		evt.preventDefault();
		
	var nMouseX = SIX.App.getMouseX();
	var nMouseY = SIX.App.getMouseY();
	
	this.bMouseDownInPanArea = true;
	this.bInPanArea = true;
	this.setPan(nMouseX, nMouseY);
}

SIX.Navigator.prototype.onMouseMovePanArea = function () 
{
	if (this.bMouseDownInPanArea && this.bInPanArea)
		this.setPan(SIX.App.getMouseX(), SIX.App.getMouseY());
}

SIX.Navigator.prototype.onMouseUpZoomAll = function () 
{
	this.onMouseUpPanArea();
}

SIX.Navigator.prototype.onMouseOverZoomAll = function () 
{
	if (this.bMouseDownInPanArea)
	{
		this.bInPanArea = true;
		this.bMouseDraggedOverZoomAll = true;
	}
	else
	{
		var elemZoomAll = document.getElementById(this.zoomAllUid);
		if (elemZoomAll)
			elemZoomAll.src = SIX.App.imageUrl("images/navigator_zoomall_on");
	}	
}

SIX.Navigator.prototype.onMouseOutZoomAll = function () 
{
	var elemZoomAll = document.getElementById(this.zoomAllUid);
	if (elemZoomAll)
		elemZoomAll.src = SIX.App.imageUrl("images/navigator_zoomall");
}

SIX.Navigator.prototype.onMouseDownZoomAll = function () 
{
	if (this.channel.layerSetExtentsAll)
		this.channel.layerSetExtentsAll.setSelected(true);
	this.map.setExtentsAll();
}

SIX.Navigator.prototype.onMouseMoveZoomAll = function () 
{
	this.onMouseMovePanArea();
}

SIX.Navigator.prototype.cancelPan = function () 
{
	if (this.tPan)
	{
		clearTimeout(this.tPan);
		this.tPan = null;
	}		
}

SIX.Navigator.prototype.pan = function (dPercentX, dPercentY)
{
	this.map.pan(dPercentX, dPercentY);
	this.cancelPan();
	this.tPan = setTimeout(this.myself + ".pan(" + dPercentX + "," + dPercentY + ")", 20);			
}

SIX.Navigator.prototype.setPan = function (x, y)
{
	var elemNavigator = document.getElementById(this.uid);
	var nNavPosX = SIX.Util.findPosX(elemNavigator);
	var nNavPosY = SIX.Util.findPosY(elemNavigator);
	
	var nDeltaX = (x - nNavPosX - this.nPanAreaCenterX);
	var nDeltaY = (nNavPosY + this.nPanAreaCenterY - y);
	var nRadius = this.nPanAreaRadius;
	
	if (Math.abs(nDeltaX) > nRadius) 
		nDeltaX = nDeltaX > 0 ? nRadius : -nRadius;
	
	if (Math.abs(nDeltaY) > nRadius) 
		nDeltaY = nDeltaY > 0 ? nRadius : -nRadius;
	
	var dPercentX = this.dMaxPanPercent * nDeltaX / nRadius;
	var dPercentY = this.dMaxPanPercent * nDeltaY / nRadius;
	
	this.pan(dPercentX, dPercentY);
}
