// JavaScript Document

//*************************************************************
// Defime IMap properties
//*************************************************************
function IMap() {
	
	this.service; // IService
	
	this.width = null;		// integer
	this.height = null;	//integer
	this.fullextent = false; // boolean
	this.envelope;	// = IEnvelope;
	this.xDiff;
	this.maxScale = 10000000000;
	
	//HTML Layer Info
	this.div;
	this.container;
	this.layerName = "mapLayer";
	this.layer;
	this.imageName = "mapImage";
	
	//miniMap bool.
	this.isMiniMap = false;
	this.showScaleBar = true;
	this.useMapLoad = true;
	
	//Map Image info (read only)
	this.image;
	this.url;
	
	//spatialSelection
	this.spatialSelection;	 //ISpatialSelection
	this.spatialSelection2;	 //ISpatialSelection
	this.querySelection; 	//IQuerySelection
	this.querySelection2; 	//IQuerySelection
	this.pointSelection; 	//IPointSelection
	this.imageBuffer;
	this.appendXML; 		// string of XML
	this.tempXML; 			// only alive untill the user moves the map again.
	this.addRenderer = addRenderer;
	this.falseAllRendering = falseAllRendering;
	this.renderers = new Array();
	
	this.history = new IHistory();
	this.loadHistoryImage = loadHistoryImage;
	this.manageHistory = manageHistory;
	this.historyManager = historyManager;

	
	//Special properties
	this.scaleFactor;
	this.scaleFraction;
	
	//Methods
	this.getScaleFactor = getScaleFactor;
	this.getMapAXL = getMapAXL;
	this.sendMap = sendMap;
	this.updateImage = updateImage;
	this.getMap = getMap;
	this.applyMap = applyMap;
	
	
	//Nav
	this.zoomInStep = zoomInStep;
	this.zoomOutStep = zoomOutStep;


}

var mapDivz = '';
var mapImage;
var fullEnvelope = new tempEnvelope();
//*************************************************************
// Send the write divisions to the page and send the map
//*************************************************************
function getMap(callBack) {
	
	
	//define the map
	this.container = document.getElementById(this.div);
	
	if (!this.container) { doDebug(null,'Can not find map Layer id="' + this.div + '" on page') }
	
	if (this.width == null || this.height == null) {
		this.width = parseInt(this.container.offsetWidth - 1);
		this.height = parseInt(this.container.offsetHeight);
	}

	if (this.isMiniMap)
	{
		mapDivz = '<div id="'+this.layerName+'"></div>'	
	}
	else {
		mapDivz = '<img src="" id="'+this.imageName+'" name="'+this.imageName+'" style="position:absolute;" />';
		mapDivz += '<div id="'+this.layerName+'" name="'+this.layerName+'"  '
		mapDivz += 'style=" background:#000000; width: '+this.width+'px; height: '+this.height+'px; position: absolute; opacity: 0.0; filter: alpha(opacity=0);"></div>'
		mapDivz += '<div id="rubberBandLayer" class="rubberBandLayerDefault" style="font-size=0; width:0px; height:0px; top:0px; left:-40px; z-index:20"></div>';
	}
	if (!this.isMiniMap) {
		//Check to see if the divs are in place yet.
		if (totalMapRequests == 0)
		{
			this.container.innerHTML = mapDivz;
		}
	} 
	//allows more content to be added to the later (ONLY ON THE TOP)
	else { 
		this.container.innerHTML +=mapDivz; 
	}
	
	this.layer 	= document.getElementById(this.layerName);
	this.image 	= document.getElementById(this.imageName);
	mapImage	= document.getElementById(this.imageName)
	
	//make the invisible layer the same width and height as the map if a new size comes.
	this.layer.style.width = this.width +"px";
	this.layer.style.height = this.height +"px";
	
	
	var mapAXL = this.getMapAXL();	 		// gets the AXL to send
	doDebug(mapAXL,null);

	
	
	
	var mapURL = this.sendMap(mapAXL,this.service,callBack);		//Sends the map using Ajax

	//this.updateImage(mapURL);


}






//*************************************************************
// Append the Image to the img tag
//*************************************************************
function updateImage(url) {
  
  if (this.isMiniMap)
  {
	  document.getElementById(this.layerName).style.backgroundImage = "url("+ url +")";
  }
  else {
  mapImage.src = url
  }

}




//*************************************************************
// Create the AXL to ask for a map
//*************************************************************
function getMapAXL()
{
	mapAXL = '';
	mapAXL += '<?xml version="1.0" encoding="UTF-8"?>\n';
	mapAXL += '<ARCXML version="1.1">\n';
	mapAXL += '<REQUEST>\n';
	mapAXL += '<GET_IMAGE>\n';
	mapAXL += '<PROPERTIES>\n';
	

	
	//Append an Evelope if one exist (usually will except on start up)
	if (!this.fullextent)
	{

		var env = this.envelope;
		var fullEnv = fullEnvelope;
		//check to see if the user has gone outside of the max extent
		var scaleFactor = this.getScaleFactor();
		var scaleFraction = Math.round(parseFloat(scaleFactor) * 96 * 12);
		if (scaleFraction <= this.maxScale)
		{
			mapAXL += '<ENVELOPE minx="'+ this.envelope.minx +'" miny="'+ this.envelope.miny +'" maxx="'+ this.envelope.maxx +'" maxy="'+ this.envelope.maxy +'" />\n';
		}
	}
	
	
	mapAXL += '<IMAGESIZE  width="'+this.width+'" height="'+this.height+'" />\n';
	


	//INSERT the LAYER DEFINITIONS
	mapAXL += '<LAYERLIST>\n';
	for (var num in RESPONSE.LAYER) 
	{
		mapAXL +='<LAYERDEF id="'+RESPONSE.LAYER[num].id+'" visible="'+RESPONSE.LAYER[num].visible+'">\n';

		for (var ii  in this.renderers)
		{
			if (this.renderers[ii].layerId == 	RESPONSE.LAYER[num].id)
			{
				if (this.renderers[ii].visible)
				{
					mapAXL +=this.renderers[ii].axl;
				}
			}
		
		}
		mapAXL +='</LAYERDEF>';
	}
	mapAXL += '</LAYERLIST>\n'

		
	mapAXL +='</PROPERTIES>\n';
	
	if (this.showScaleBar)
	{
		mapAXL += '<LAYER type="acetate" name="scalebar" visible="true" id="acetate">\n';
		mapAXL += '<OBJECT units="pixel">\n';
		mapAXL += '<SCALEBAR fontcolor="0,0,0" coords="4 10" barcolor="0,0,0" fontsize="10" screenlength="150" scaleunits="feet" barwidth="3" mapunits="feet" antialiasing="true"/>\n';
		mapAXL += '</OBJECT>\n';
		mapAXL += '</LAYER>\n';

	}
	
	//********************************************
	// Draw a polygon around the geometry.
	//********************************************
	if(this.spatialSelection || this.querySelection) 
	{ 
		if (this.spatialSelection) 		{ var ss = this.spatialSelection; 	sName ="Selected Features1"; }
		if (this.querySelection) 		{ var ss = this.querySelection; 	sName ="Selected Features2" }
		
		
		mapAXL += '<LAYER type="featureclass" name="'+sName+'" visible="true">\n';
		mapAXL += '<DATASET fromlayer="'+ss.layerId+'" />\n';
		
		if(this.spatialSelection) {

			mapAXL += '<SPATIALQUERY>\n';
			mapAXL += '<SPATIALFILTER relation="area_intersection" >\n';
			mapAXL += '<ENVELOPE maxy="'+this.spatialSelection.selectionEnvelope.maxy+'" maxx="'+this.spatialSelection.selectionEnvelope.maxx+'" miny="'+this.spatialSelection.selectionEnvelope.miny+'" minx="'+this.spatialSelection.selectionEnvelope.minx+'" />\n';
			mapAXL += '</SPATIALFILTER>\n';
			mapAXL += '</SPATIALQUERY>\n';
		}
		
		if(this.querySelection || this.querySelection2) {
			mapAXL += '<QUERY where="'+ss.where+'" />\n';
		}
		

		
		mapAXL += '<SIMPLERENDERER>\n';
		var sColors = ss.selectionProperties;
		
		
		mapAXL += '<SIMPLEPOLYGONSYMBOL';
		if(sColors.fillcolor != null) {
				mapAXL += ' fillcolor="'+sColors.fillcolor+'"';
		} if(sColors.filltype != null) {
				mapAXL += ' filltype="'+sColors.filltype+'"';
		} if (sColors.usefill) {
				mapAXL += ' filltransparency="'+sColors.filltransparency+'"';
		} else { mapAXL += ' filltransparency="0"';}
		
		 if(sColors.boundarycolor != null) {
				mapAXL += ' boundary ="true"  boundarycolor="'+sColors.boundarycolor+'"';
		} if (sColors.boundarywidth != null) {
				mapAXL += ' boundarywidth="'+sColors.boundarywidth+'"';
		} if (sColors.boundarytype != null) {
				mapAXL += ' boundarytype="'+sColors.boundarytype+'"';
		}
		mapAXL += ' />\n';
			
		mapAXL += '</SIMPLERENDERER>\n';
		
		mapAXL += '</LAYER>\n';
	}


if(this.querySelection2) { 
		
		var ss = this.querySelection2; 	sName ="Selected Feature3"
		
		
		mapAXL += '<LAYER type="featureclass" name="'+sName+'" visible="true">\n';
		mapAXL += '<DATASET fromlayer="'+ss.layerId+'" />\n';
		

		mapAXL += '<QUERY where="'+ss.where+'" />\n';

		mapAXL += '<SIMPLERENDERER>\n';
		var sColors = ss.selectionProperties;
		
		
		mapAXL += '<SIMPLEPOLYGONSYMBOL';
		if(sColors.fillcolor != null) {
				mapAXL += ' fillcolor="'+sColors.fillcolor+'"';
		} if(sColors.filltype != null) {
				mapAXL += ' filltype="'+sColors.filltype+'"';
		} if (sColors.usefill) {
				mapAXL += ' filltransparency="'+sColors.filltransparency+'"';
		} else { mapAXL += ' filltransparency="0"';}
		
		 if(sColors.boundarycolor != null) {
				mapAXL += ' boundary ="true"  boundarycolor="'+sColors.boundarycolor+'"';
		} if (sColors.boundarywidth != null) {
				mapAXL += ' boundarywidth="'+sColors.boundarywidth+'"';
		} if (sColors.boundarytype != null) {
				mapAXL += ' boundarytype="'+sColors.boundarytype+'"';
		}
		mapAXL += ' />\n';
			
		mapAXL += '</SIMPLERENDERER>\n';
		
		mapAXL += '</LAYER>\n';
	}
















	//********************************************
	// Draw a POINT MARKER SYMBOL ON the geometry.
	//********************************************

if (this.pointSelection) {
		var addPoint = this.pointSelection;
		mapAXL += '<LAYER type="featureclass" name="POINT MARKER" visible="true">\n';
		mapAXL += '<DATASET fromlayer="'+addPoint.layerId+'" />\n';
		mapAXL += '<QUERY where="'+addPoint.where+'" />\n';
		mapAXL += '<SIMPLERENDERER>\n';

		var pointProperties = this.pointSelection.selectionProperties;
		mapAXL += '<SIMPLEMARKERSYMBOL ';
		if (pointProperties.transparency != null)	mapAXL += 'transparency="'+pointProperties.transparency+'" ';
		if (pointProperties.color != null) 			mapAXL += 'color="'+pointProperties.color+'" ';
		if (pointProperties.type != null)			mapAXL += 'type="'+pointProperties.type+'" ';
		if (pointProperties.width != null) 			mapAXL += 'width="'+pointProperties.width+'" ';
		if (pointProperties.outline != null) 		mapAXL += 'outline="'+pointProperties.outline+'" ';
		if (pointProperties.antialiasing != null) 	mapAXL += 'antialiasing="'+pointProperties.antialiasing+'" ';
		if (pointProperties.overlap != null) 		mapAXL += 'overlap="'+pointProperties.overlap+'" ';
		
		mapAXL += '/>\n';
		mapAXL += '</SIMPLERENDERER>\n';
		mapAXL += '</LAYER>\n';
}

	
	if (this.imageBuffer != null ) {
		var myBuff = this.imageBuffer;
		//add in a buffer
		mapAXL +='<LAYER type="featureclass" name="theBuffer" visible="true" id="buffer">\n';
		mapAXL +='<DATASET fromlayer="'+myBuff.bufferLayerId+'"/>\n';
		mapAXL +='<SPATIALQUERY where="'+myBuff.where+'">\n';
		mapAXL +='<BUFFER distance="'+myBuff.distance+'" bufferunits="'+myBuff.units+'" />\n';
	
		mapAXL +='</SPATIALQUERY>\n';
		mapAXL +='<SIMPLERENDERER>\n';
		mapAXL +='<SIMPLEPOLYGONSYMBOL fillcolor="'+myBuff.fillcolor+'" filltype="'+myBuff.filltype+'" filltransparency="'+myBuff.filltransparency+'" />\n';
		

		mapAXL +='</SIMPLERENDERER>\n';
		mapAXL +='</LAYER>\n';   
		
	}

	if (this.appendXML != null)
	{	
		mapAXL +=this.appendXML; 	
	}

	//*************************************************************
	//	APPEND  TempXML to the map 
	//	This is only alive until the map is moved (see clear below)
	//*************************************************************
	
	if (this.tempXML != null)
	{
		mapAXL += this.tempXML;
	}
	
	
	mapAXL += '</GET_IMAGE>\n';
	mapAXL += '</REQUEST>\n</ARCXML>';
	

	//remove any old XML from tempXML
	this.tempXML = '';

	return mapAXL;
}



//*** NEW ****//
var mapSender = new Array();
var myMouse;
//*************************************************************
//send map, parse XML and create Objects when the map is sent back
//*************************************************************
function sendMap(axl,service,callBack) {
	
	showLayer("loadingLayer");
	this.layer = this.container;
    var xml = new JKL.ParseXML(this.service.url,axl);
	var copy = this;
    xml.async(copy.apply = function(data) { copy.applyMap(data,callBack)  } );
    xml.parse();
}

function applyMap(data,callBack)
{
	RESPONSE.IMAGE = data.ARCXML.RESPONSE.IMAGE;
	this.url = RESPONSE.IMAGE.OUTPUT.url
	this.envelope = RESPONSE.IMAGE.ENVELOPE;
	this.layer = this.container;
	this.scaleFactor = this.getScaleFactor();
	this.scaleFraction = scaleFactorDisplay = Math.round(parseFloat(this.scaleFactor) * 96 * 12);
	
	hideLayer("loadingLayer")	
	
	if (this.useMapLoad)
	{
		//Get the Mouse coordinates
		myMouse = new IMouse();
		myMouse.moveMouse(this);
	}
	//Set the full extent object on first Load.
	if(totalMapRequests ==0) {  fullEnvelope = this.envelope; }
	totalMapRequests++;
	
	this.updateImage(this.url);
	this.historyManager(this.getMapAXL(),this.url)
	this.history.envelopes.push(this.envelope);
	
	if (callBack) 
	{
		callBack();
	}
	
	if (this.useMapLoad)
	{
	onMapLoad();
	}
	
	return this.url;
}






function historyManager(axl,imageUrl)
{
	
	if (axl && imageUrl)
	{
	if (this.history.imageUrls.length >=this.history.maxHistory) 
	{
		this.history.AXL.shift();
		this.history.imageUrls.shift();
	}
	else 
	{
		
		this.history.currentIndex +=1;	
		
	}
		this.history.AXL.push(axl);
		this.history.imageUrls.push(imageUrl);
		
		//alert(this.history.imageUrls.length);
	}	
}



function manageHistory(isBack)
{		

	var newIndex;
	//alert(isBack +" " + parseInt(this.history.currentIndex))
	if (isBack && parseInt(this.history.currentIndex) != 0)
	{
		//alert(this.history.currentIndex);
		newIndex = this.history.currentIndex -1;
		this.loadHistoryImage(newIndex);
		
	}
	
	if (!isBack && parseInt(this.history.currentIndex) != this.history.imageUrls.length-1)
	{
		 newIndex= this.history.currentIndex +1;
		 this.loadHistoryImage(newIndex);
		
	}
	
}



function loadHistoryImage(index)
{
	//d.innerHTML = this.history.AXL[index];
	this.history.currentIndex =index;
	var imageUrl = this.history.imageUrls[index];
	getImage(imageUrl)
	this.envelope = this.history.envelopes[index];
	myMouse.moveMouse(this);
	onMapLoad()
	
	
	for (var i=0; i < parseInt(this.history.imageUrls.length) - index; i++)
	{

		this.history.AXL.pop();
		this.history.imageUrls.pop();
		this.history.envelopes.pop();
	}
	
	
}




function getImage(image)
{
	var previousImage = new Image();
	previousImage.src = image;
	//previousImage.onload = function()
	//{	
		imageLoad(image);
	//}
	//previousImage.onerror = imageError;
	
}


function imageLoad(img)
{
	var oldImageURL = img;
	document.getElementById(myMap.imageName).src = oldImageURL;
	//myMap.updateImage(this.src)
}

function imageError()
{

}






//function to add a render to the map
function addRenderer(valueRenderer)
{
	this.renderers.push(valueRenderer);
}


function falseAllRendering(id,clearAnyway)
{
	
	for (var ii  in this.renderers)
	{
		//alert(this.renderers[ii].id);
		if (this.renderers[ii].layerId == id)
		{
			
		this.renderers[ii].visible = false;
		}
		if (clearAnyway)
		{
			this.renderers[ii].visible = false;
		}	

	}

}




//*************************************************************
// Calculate the scale factor of the map.
//*************************************************************
function getScaleFactor() {

	this.xDiff= Math.abs(parseFloat(this.envelope.maxx)-parseFloat(this.envelope.minx));
	sFactor = this.xDiff / (this.width)	
	return sFactor;
	
}







//Nav functions
function zoomInStep() {
	var value = 0.50;
	var dx = parseFloat(this.envelope.maxx) - parseFloat(this.envelope.minx);
	var dy = parseFloat(this.envelope.maxy) - parseFloat(this.envelope.miny);

	var cx = (parseFloat(this.envelope.maxx) + parseFloat(this.envelope.minx))/2.0;
	var cy = (parseFloat(this.envelope.maxy) + parseFloat(this.envelope.miny))/2.0;

	var dx1 = 0.5 * value * dx;
	var dy1 = 0.5 * value * dy;

	this.fullextent = false;
	this.envelope.minx = cx - dx1;
	this.envelope.miny = cy - dy1;
	this.envelope.maxx = cx + dx1;
	this.envelope.maxy = cy + dy1;
	this.getMap();
}


//Nav functions
function zoomOutStep() {
	var value = 2;
	var dx = parseFloat(this.envelope.maxx) - parseFloat(this.envelope.minx);
	var dy = parseFloat(this.envelope.maxy) - parseFloat(this.envelope.miny);

	var cx = (parseFloat(this.envelope.maxx) + parseFloat(this.envelope.minx))/2.0;
	var cy = (parseFloat(this.envelope.maxy) + parseFloat(this.envelope.miny))/2.0;

	var dx1 = 0.5 * value * dx;
	var dy1 = 0.5 * value * dy;

	this.fullextent = false;
	this.envelope.minx = cx - dx1;
	this.envelope.miny = cy - dy1;
	this.envelope.maxx = cx + dx1;
	this.envelope.maxy = cy + dy1;
	this.getMap();
}



