/***
MarkupControl.js
library for handling the map markup functions.

Dependencies:
MapLib/map.js
MapLib/mapImage.js
wz_jsgraphics


***/

MarkupControl = function (newId, newMapObject, newMapId)
{
	this.id = newId;
	if(typeof(newId)=="undefined")
		newId='map0MarkupControl';
	this.cid = (this.id=='map0MarkupControl')?'':('_'+this.id);
	this.isCoreControl = (this.id=='map0MarkupControl')?true:false;

	var $_this = this;
	var markupConfig = null;
	var mapObject = newMapObject?newMapObject:document.mapObject;
	var firstinitialize=true;
	var gfxContext = null;
	var gfx = null;
	var gfxXOffset = 0;
	var gfxYOffset = 0;
	var clearThemeInProgress = false;

	if (this.isCoreControl)
		mapObject.markupControl = this;

	this.markupRadioButtonGroup = null;
	this.markupPoints = [];

	this.markupNewPanel = null;
	this.markupExistingPanel = null;

	var markupConfig = [];  // organized by markup type
	var existingMarkup = {};  // organized by theme

	this.activeMarkupType = null;
	this.activeMarkupIdx = null;
	this.activeMarkup = null;

	this.haveMarkup = false;  // default

	this.onadd = null;  // function to call when something is added
	this.onremove = null; // function to call when something is removed
	this.ondrawMarkupExistingPanel = null; // function to call after existing panel html is updated


function initialize(attachMapClickHandlers)
{
	if ($_this.markupNewPanel) drawMarkupNewPanel();
	if ($_this.markupExistingPanel) drawMarkupExistingPanel();
	gfxXOffset = xPageX(mapObject.mapImage.drawPlaneNode);
	if(gfxXOffset == 0) // sometimes the browser just doesn't seem to get it
		gfxXOffset = _MapToolBarWidth;  // best guess
	gfxYOffset = 0;

	if (mapObject.mapImage.measureCanvas)
	{
		gfxContext = mapObject.mapImage.measureCanvas.getContext("2d");
		gfxContext.clearRect(0,0,mapObject.mapImage.width(),mapObject.mapImage.height());
		gfxContext.strokeStyle = '#FF0000';
		gfxContext.lineWidth = 2;
		gfxContext.fillStyle="rgba(255,0,0,0.25)";
	}
	else
	{
		gfxContext = null;
		gfx = new jsGraphics(mapObject.mapImage.drawPlaneNode.id);
		gfx.setColor("#FF0000");
		gfx.setStroke(2);
	}

	if(firstinitialize&&this.isCoreControl){
		mapObject.addCursorEventHandler('click','Markuppoint',processMapClickEvent);
		mapObject.addCursorEventHandler('click','Markupline',processMapClickEvent);
		mapObject.addCursorEventHandler('click','Markuppolygon',processMapClickEvent);
		mapObject.addCursorEventHandler('click','Markuptext',processMapClickEvent);
		mapObject.addEventHandler('initialize',function(){
			$_this.initialize();
			$_this.initUser();
		});
		firstinitialize=false;
	}
};
this.initialize = initialize;

function setConfig(config)
{
	markupConfig = config;
	var total=0;
	for (var i in config) total+=markupConfig[i].length;
	$_this.haveMarkup = (total>0);
};
this.setConfig = setConfig;

this.initUser=function()
{
	freeance_request(function(resp){
		mapObject.setWaiting(false);
		if(resp.XMLRPC_FAULT) alert('Fault '+resp.XMLRPC_FAULT_CODE+': '+resp.XMLRPC_FAULT_MESSAGE);
		var data=resp.data;
		if (data){
			existingMarkup = data;
			setWorkspaceData();
		}
		else{
			existingMarkup = {};
			setWorkspaceData();
		};
		drawMarkupExistingPanel();
	},'WORKSPACE.data.get',mapObject.sessionID,'MarkupControllabelList');
};

setWorkspaceData=function()
{
	freeance_request(function(resp){},'WORKSPACE.data.set',mapObject.sessionID,'MarkupControllabelList',existingMarkup);
};

function setActiveMarkup(mtype,idx)
{
	//var activeButton = document.mapToolbar.mapCursorRadioButtonGroup.setActiveButton(-1);
	// tell mapObject to address me for clicks
	$_this.activeMarkupType = mtype;
	$_this.activeMarkupIdx = idx;
	var activeMarkup = $_this.activeMarkup = markupConfig[mtype][idx];
	if ((mtype == 'line')||(mtype == 'polygon')){
		if (gfxContext){
			try{
				gfxContext.strokeStyle = activeMarkup["color"];
				gfxContext.lineWidth = activeMarkup["thickness"];
				if (activeMarkup["fillColor"])
					gfxContext["fillStyle"] = activeMarkup["fillColor"];
				else
					gfxContext["fillStyle"] = "rgba(255,255,255,0.0)";
			}catch(e){
				gfxContext["strokeStyle"] = "rgba(0,0,0,1.0)";
				gfxContext["lineWidth"] = 2;
				gfxContext["fillStyle"] = "rgba(255,255,255,0.0)"
			}
		}
		else
		{
			gfx.setColor(activeMarkup["color"]);
			gfx.setStroke(activeMarkup["thickness"]);
		}
		if ($_this.markupPoints.length > 0)
			redrawActiveLine();
	}
	mapObject.mapImage.setMouseMode('Markup'+mtype);
};
this.setActiveMarkup = setActiveMarkup;

function buildThemeSelectorPullDown()
{
	var html = ['Markup Layer: <SELECT id="markupActiveThemeSelect">'];
	for(var themeID in document.mapObject.config.themes){
		if(themeID=='toJSONString')continue;
		html.push('<OPTION value="',themeID,'">',escapeHTML(document.mapObject.config.themes[themeID].themeName),'</OPTION>');
	}
	html.push('</SELECT>');
	return(html.join(''));
};

function getThemeNameByThemeID(themeID)
{
	for(var id in document.mapObject.config.themes){
		if(themeID=='toJSONString')continue;
		if (id == themeID)
			return(document.mapObject.config.themes[id].themeName);
	}
	return('');
};

function getActiveMarkupThemeID()
{
	var select = document.getElementById('markupActiveThemeSelect');
	return(select.value);
};

this.assignMarkupNewPanel=function(ele)
{
	this.markupNewPanel = ele;
};
this.assignMarkupExistingPanel=function(ele)
{
	this.markupExistingPanel = ele;
};

function convertPercentToMapCoord(XPercent,YPercent)
{
	return [(XPercent * (mapObject.extent[3]-mapObject.extent[2])) + mapObject.extent[2],(YPercent * (mapObject.extent[1]-mapObject.extent[0])) + mapObject.extent[0]];  // (XP * ExtentWidth + Left),(YP * ExtentHeight + Bottom)
};
this.convertPercentToMapCoord = convertPercentToMapCoord;
function addMarkupPoint(description,themeID,gisStyleSheetName,pointArray,viewExtent)
{
	mapObject.setWaiting(true);
	freeance_request(function(resp){
			if(resp.XMLRPC_FAULT) alert('Fault '+resp.XMLRPC_FAULT_CODE+': '+resp.XMLRPC_FAULT_MESSAGE);
			var data=resp.data;
			mapObject.setWaiting(false);
			if (mapObject.mapImage != null)
			{
				mapObject.mapImage.imageNode.src = mapObject.correctURL(data[0][0][1]);
				mapObject.extent = data[0][0][2];
			};
			if (mapObject.vmapImage != null)
				mapObject.vmapImage.imageNode.src = mapObject.correctURL(data[0][1][1]);
			var handle = data[1];
			addToExistingMarkup(handle,'point',description,themeID,gisStyleSheetName,viewExtent);
			drawMarkupExistingPanel();
			setWorkspaceData();
		},
		'GIS.DrawPlane.add.Point',mapObject.sessionID,0,mapObject.mapImage.width(),mapObject.mapImage.height(),pointArray,true,themeID,gisStyleSheetName);
};
this.addMarkupPoint = addMarkupPoint;

function addMarkupPoint_NoRedraw(description,themeID,gisStyleSheetName,pointArray,viewExtent,callback_func)
{
	mapObject.setWaiting(true);
	freeance_request(function(resp){
			if(resp.XMLRPC_FAULT) alert('Fault '+resp.XMLRPC_FAULT_CODE+': '+resp.XMLRPC_FAULT_MESSAGE);
			var data=resp.data;
			mapObject.setWaiting(false);
			var handle = data[1];
			addToExistingMarkup(handle,'point',description,themeID,gisStyleSheetName,viewExtent);
			drawMarkupExistingPanel();
			setWorkspaceData();
			if(callback_func){
				callback_func();
			}
		},
		'GIS.DrawPlane.add.Point',mapObject.sessionID,0,-1,-1,pointArray,true,themeID,gisStyleSheetName);
};
this.addMarkupPoint_NoRedraw = addMarkupPoint_NoRedraw;

function addMarkupLine(description,themeID,gisStyleSheetName,pointArray,viewExtent)
{
	mapObject.setWaiting(true);
	freeance_request(function(resp){
		if(resp.XMLRPC_FAULT) alert('Fault '+resp.XMLRPC_FAULT_CODE+': '+resp.XMLRPC_FAULT_MESSAGE);
		var data=resp.data;
		clearActiveLine();
		if (mapObject.mapImage != null)
		{
			mapObject.mapImage.imageNode.src = mapObject.correctURL(data[0][0][1]);
			mapObject.extent = data[0][0][2];
		};
		if (mapObject.vmapImage != null)
			mapObject.vmapImage.imageNode.src = mapObject.correctURL(data[0][1][1]);
		var handle = data[1];
		addToExistingMarkup(handle,'line',description,themeID,gisStyleSheetName,viewExtent);
		drawMarkupExistingPanel();
		setWorkspaceData();
	},'GIS.DrawPlane.add.Line',mapObject.sessionID,0,mapObject.mapImage.width(),mapObject.mapImage.height(),pointArray,true,themeID,gisStyleSheetName);
};
this.addMarkupLine = addMarkupLine;

function addMarkupPolygon(description,themeID,gisStyleSheetName,pointArray,viewExtent)
{
	mapObject.setWaiting(true);
	freeance_request(function(resp){
		mapObject.setWaiting(false);
		if(resp.XMLRPC_FAULT) alert('Fault '+resp.XMLRPC_FAULT_CODE+': '+resp.XMLRPC_FAULT_MESSAGE);
		var data=resp.data;
		clearActiveLine();
		if (mapObject.mapImage != null){
			mapObject.mapImage.imageNode.src = mapObject.correctURL(data[0][0][1]);
			mapObject.extent = data[0][0][2];
		};
		if (mapObject.vmapImage != null)
			mapObject.vmapImage.imageNode.src = mapObject.correctURL(data[0][1][1]);
		var handle = data[1];
		addToExistingMarkup(handle,'polygon',description,themeID,gisStyleSheetName,viewExtent);
		drawMarkupExistingPanel();
		setWorkspaceData();
	},'GIS.DrawPlane.add.Polygon',mapObject.sessionID,0,mapObject.mapImage.width(),mapObject.mapImage.height(),pointArray,true,themeID,gisStyleSheetName);
};
this.addMarkupPolygon = addMarkupPolygon;

function addMarkupText(description,themeID,gisStyleSheetName,pointArray,viewExtent,textToPlace)
{
	mapObject.setWaiting(true);
	freeance_request(function(resp){
		mapObject.setWaiting(false);
		if(resp.XMLRPC_FAULT) alert('Fault '+resp.XMLRPC_FAULT_CODE+': '+resp.XMLRPC_FAULT_MESSAGE);
		var data=resp.data;
		if (mapObject.mapImage != null)
		{
			mapObject.mapImage.imageNode.src = mapObject.correctURL(data[0][0][1]);
			mapObject.extent = data[0][0][2];
		};
		if (mapObject.vmapImage != null)
			mapObject.vmapImage.imageNode.src = mapObject.correctURL(data[0][1][1]);
		var handle = data[1];
		addToExistingMarkup(handle,'text',description,themeID,gisStyleSheetName,viewExtent);
		drawMarkupExistingPanel();
		setWorkspaceData();
	},'GIS.DrawPlane.add.Text',mapObject.sessionID,0,mapObject.mapImage.width(),mapObject.mapImage.height(),pointArray,true,themeID,gisStyleSheetName,textToPlace);
};
this.addMarkupText = addMarkupText;

function processMapClickEvent(xPos,yPos,width,height,XPercent,YPercent,clickMode)
{
	var mapObject = document.mapObject;
	var _this = $_this;//mapObject.markupControl;
	var markupPoints = $_this.markupPoints;
	switch(clickMode)
	{
		case 'Markuppoint':
			var description = prompt("Please enter a description for this point.","");
			if (!description) return;
			var themeID = getActiveMarkupThemeID();
			var gisStyleSheet = $_this.activeMarkup.styleSheet;
			var pointArray = [[convertPercentToMapCoord(XPercent,YPercent)]];
			var viewExtent = mapObject.extent;
			addMarkupPoint(description,themeID,gisStyleSheet,pointArray,viewExtent);
			break;
		case 'Markuptext':
			var description = prompt("Please enter the text to place on the map.","");
			if (!description) return;
			var themeID = getActiveMarkupThemeID();
			var gisStyleSheet = $_this.activeMarkup.styleSheet;
			var pointArray = [[convertPercentToMapCoord(XPercent,YPercent)]];
			var viewExtent = mapObject.extent;
			addMarkupText(description,themeID,gisStyleSheet,pointArray,viewExtent,description);
			break;
		case 'Markupline':
		case 'Markuppolygon':
			var coord = convertPercentToMapCoord(XPercent,YPercent);
			var ptObj = {
				mapX: coord[0],
				mapY: coord[1],
				gfxX: mapObject.mapImage.left()+xPos,
				gfxY: mapObject.mapImage.top()+yPos
			};
			markupPoints.push(ptObj);
			if (markupPoints.length > 1)
			{
				var lastPtObj = markupPoints[markupPoints.length-2];
				if (gfxContext)
				{
					gfxContext.clearRect(0,0,mapObject.mapImage.width(),mapObject.mapImage.height());
					gfxContext.beginPath();
					gfxContext.moveTo(markupPoints[0].gfxX-gfxXOffset,markupPoints[0].gfxY-gfxYOffset);
					for (var currentPoint=0;currentPoint<markupPoints.length;currentPoint++)
					{
						gfxContext.lineTo(markupPoints[currentPoint].gfxX-gfxXOffset,markupPoints[currentPoint].gfxY-gfxYOffset);
					};
					gfxContext.stroke();  //note - IE and Safari implicitly close the path here.
					gfxContext.closePath();  //bring firefox into sync

					if (clickMode=='Markuppolygon')
					{
					//draw area
					gfxContext.beginPath();
					gfxContext.moveTo(markupPoints[0].gfxX-gfxXOffset,markupPoints[0].gfxY-gfxYOffset);
					for (var currentPoint=0;currentPoint<markupPoints.length;currentPoint++)
					{
						gfxContext.lineTo(markupPoints[currentPoint].gfxX-gfxXOffset,markupPoints[currentPoint].gfxY-gfxYOffset);
					};
					gfxContext.fill();
					}
				}
				else
				{
					gfx.drawLine(lastPtObj.gfxX-gfxXOffset,lastPtObj.gfxY-gfxYOffset,ptObj.gfxX-gfxXOffset,ptObj.gfxY-gfxYOffset);
					gfx.paint();
				};
			};
			break;
	}
};

function saveActiveLine()
{
	if (($_this.activeMarkupType != 'line')&&($_this.activeMarkupType != 'polygon')) { alert('Please choose a line markup style first.'); return; };
	if ($_this.markupPoints.length <= 1) { alert('Please draw a complete line first.'); return; };
	var description = prompt("Please enter a description for this line.","");
	if (!description) return;
	var themeID = getActiveMarkupThemeID();
	var gisStyleSheet = $_this.activeMarkup.styleSheet;
	var innerPointArray = [];
	for(var lcv=0;lcv < $_this.markupPoints.length;lcv++)
		innerPointArray.push([$_this.markupPoints[lcv].mapX,$_this.markupPoints[lcv].mapY]);
	var pointArray = [innerPointArray];
	var viewExtent = mapObject.extent;
	switch ($_this.activeMarkupType)
	{
		case 'line':
			$_this.addMarkupLine(description,themeID,gisStyleSheet,pointArray,viewExtent);
			break;
		case 'polygon':
			$_this.addMarkupPolygon(description,themeID,gisStyleSheet,pointArray,viewExtent);
			break;
	}
};

function clearActiveLine()
{
	if ($_this.markupPoints.length == 0)
		return;
	while($_this.markupPoints.length > 0)
	{
		var ptObj = $_this.markupPoints.pop();
		delete ptObj;
	};
	if (gfxContext)
		gfxContext.clearRect(0,0,mapObject.mapImage.width(),mapObject.mapImage.height());
	else
		gfx.clear();
};
function redrawActiveLine()
{
	if (gfxContext)
	{
		gfxContext.clearRect(0,0,mapObject.mapImage.width(),mapObject.mapImage.height());
		gfxContext.beginPath();
		gfxContext.moveTo($_this.markupPoints[0].gfxX-gfxXOffset,$_this.markupPoints[0].gfxY-gfxYOffset);
		for (var currentPoint=0;currentPoint<$_this.markupPoints.length;currentPoint++)
		{
			gfxContext.lineTo($_this.markupPoints[currentPoint].gfxX-gfxXOffset,$_this.markupPoints[currentPoint].gfxY-gfxYOffset);
		};
		gfxContext.stroke();  //note - IE and Safari implicitly close the path here.
		gfxContext.closePath();  //bring firefox into sync

		//draw area
		gfxContext.beginPath();
		gfxContext.moveTo($_this.markupPoints[0].gfxX-gfxXOffset,$_this.markupPoints[0].gfxY-gfxYOffset);
		for (var currentPoint=0;currentPoint<$_this.markupPoints.length;currentPoint++)
		{
			gfxContext.lineTo($_this.markupPoints[currentPoint].gfxX-gfxXOffset,$_this.markupPoints[currentPoint].gfxY-gfxYOffset);
		};
		gfxContext.fill();
	}
	else{
		gfx.clear();
		for(var lcv=1;lcv < $_this.markupPoints.length;lcv++)
		{
			var lastPtObj = $_this.markupPoints[lcv-1];
			var ptObj = $_this.markupPoints[lcv];
			gfx.drawLine(lastPtObj.gfxX-gfxXOffset,lastPtObj.gfxY-gfxYOffset,ptObj.gfxX-gfxXOffset,ptObj.gfxY-gfxYOffset);
		};
		gfx.paint();
	}
};

function addToExistingMarkup(handle,mtype,description,themeID,gisStyleSheetName,viewExtent)
{
	var stylesheetid = 0;
	var stylesheets = markupConfig[mtype];
	if(stylesheets){
		for(var i = 0; i < stylesheets.length; i++){
			if(stylesheets[i].styleSheet == gisStyleSheetName){
				stylesheetid = i;
				break;
			}
		}
	}
	var markupEntryObj = {
		type: mtype,
		description: description,
		themeID: themeID,
		gisStyleSheetName: gisStyleSheetName,
		viewExtent: viewExtent,
		drawPlaneHandle: handle,
		styleSheetID: stylesheetid
	};
	if (!existingMarkup[themeID]) existingMarkup[themeID] = [];
	existingMarkup[themeID].push(markupEntryObj);
	if ($_this.onadd) $_this.onadd(themeID,existingMarkup[themeID].length-1,markupEntryObj);
	return(existingMarkup[themeID].length-1);
};
this.addToExistingMarkup = addToExistingMarkup;

function zoomToMarkupExtent(themeID,markupIdx)
{
	mapObject.zoomToExtent(existingMarkup[themeID][markupIdx].viewExtent);
};

function removeExistingMarkup(themeID,markupIdx,requestMap)
{
  if(typeof(existingMarkup[themeID][markupIdx]) == 'undefined')
    return false;
	var requestInfo ={
		mode: 'removeMarkup',
		themeID: themeID,
		markupIdx: markupIdx
	};
	var mapWidth = -1;
	var mapHeight = -1;
	//requestMap = false; // temp fix
	if (requestMap)
	{
		var mapDimensions = mapObject.getMapDimensions();
		mapWidth = mapDimensions[0][0];
		mapHeight = mapDimensions[0][1];
	};
	if ($_this.onremove)
		$_this.onremove(themeID,markupIdx);
	mapObject.setWaiting(true);
	var drawPlaneHandle = existingMarkup[themeID][markupIdx].drawPlaneHandle;
	delete(existingMarkup[themeID][markupIdx]);

	var oldMarkup = cloneObject(existingMarkup[themeID]);
	existingMarkup[themeID] = [];
	//rebuild array; process entire theme as a sanity check
	var newIndex = 0;
	for (var oldIndex=0; oldIndex<oldMarkup.length; oldIndex++)
	{
		if (oldMarkup[oldIndex]!=null)
		{
			existingMarkup[themeID][newIndex] = cloneObject(oldMarkup[oldIndex]);
			newIndex++;
		};
	};
	if (!clearThemeInProgress)
		if (getArrayLength(existingMarkup[themeID]) == 0)
			delete(existingMarkup[themeID]);
	freeance_request(function(resp){
		if(resp.XMLRPC_FAULT) alert('Fault '+resp.XMLRPC_FAULT_CODE+': '+resp.XMLRPC_FAULT_MESSAGE);
		mapObject.setWaiting(false);
		var data=resp.data;
		drawMarkupExistingPanel();
		setWorkspaceData();
		if (requestMap) mapObject.redraw();
	},'GIS.DrawPlane.remove.Shape',mapObject.sessionID,mapObject.mapNumber,themeID,drawPlaneHandle, mapWidth, mapHeight);
};
this.removeExistingMarkup = removeExistingMarkup;

function clearThemeMarkup(themeID)
{
	var requestMap = false;
	mapObject.setWaiting(true);
	clearThemeInProgress = true;
	for(var i = existingMarkup[themeID].length-1; i >= 0; i--){
		if (getArrayLength(existingMarkup[themeID]) == 1)
			requestMap = true;
		removeExistingMarkup(themeID,i,requestMap);
	}
	delete(existingMarkup[themeID]);
	clearThemeInProgress = false;
	mapObject.setWaiting(false);
};

function drawMarkupNewPanel()
{
	if (!$_this.markupNewPanel) return;
	var htmlstr = ['<div class="rightPanelFormHeader">Add New Markup</div>',
	'<table width="100%" cellpadding="0" cellspacing="0"><tr class="rightPanelFormHeader"><td colspan="4">',buildThemeSelectorPullDown(),'</td></tr>'];
	var rowct=0;
	for (var mtype in markupConfig)
	{
		if((mtype=='toJSONString')||(markupConfig[mtype].length==0))
			continue;
		var category=markupConfig[mtype];
		switch(mtype)
		{
			case 'point':
				htmlstr.push('<tr><td colspan="2" class="rightPanelFormHeader2">Point</td></tr>');
				for (var i=0;i<category.length;i++){
					var markup=category[i];
					htmlstr.push('<tr FREEANCE_TYPE="point" FREEANCE_IDX="',i,'">',
						'<td width="15px" class="layerControlLeftColumn" padding-left:  2px;">',
						'<INPUT type="radio" name="mapNewMarkupSelector">',
						'</td><td width="*" style="padding-left: 3px;"><span class="pseudolink">',
						//'<img style="vertical-align: middle;" src="',markup.sampleURL,'" />',
						//(markup.description.strtrim()?markup.description:markup.id),
						escapeHTML((markup.description.strtrim()!='')?(markup.description):(markup.styleSheet)),
						'</span></td></tr>');
				}
				break;
			case 'line':
				if(category.length>0){
					htmlstr.push('<tr><td colspan="2" class="rightPanelFormHeader2">Line</td></tr>');
					for (var i=0;i<category.length;i++){
						var markup=category[i];
						htmlstr.push(
							'<tr FREEANCE_TYPE="line" FREEANCE_IDX="',i,'">',
							'<td width="15px" class="layerControlLeftColumn" padding-left:  2px;">',
							'<INPUT type="radio" name="mapNewMarkupSelector">',
							'</td><td width="*" style="padding-left: 3px;"><span class="pseudolink">',
							//'<img style="vertical-align:middle; background:',markup["color"],';" width="20px" height="',markup["thickness"],'" src="./blank.gif" /> ',
							escapeHTML((markup.description.strtrim()!='')?(markup.description):(markup.styleSheet)),
							'</span></td></tr>'
							);
					}
					htmlstr.push('<tr><td colspan="2" style="text-align: center; border-top: 1px #C0C0C0 solid; border-bottom: 1px #C0C0C0 solid; padding-left:  2px;">',
						'<span class="pseudolink" FREEANCE_TYPE="SAVE_ACTIVE_LINE"">Save Currently Drawn Line</span>',
						'</td></tr><tr><td colspan="2" style="text-align: center; padding-left:  2px;">',
						'<span class="pseudolink" FREEANCE_TYPE="CLEAR_ACTIVE_LINE">',
						'Erase Currently Drawn Line</span></td></tr>');
					}
					break;
			case 'polygon':
				if(category.length>0){
					htmlstr.push('<tr><td colspan="2" class="rightPanelFormHeader2">Polygon</td></tr>');
					for (var i=0;i<category.length;i++){
						var markup=category[i];
						htmlstr.push(
							'<tr FREEANCE_TYPE="polygon" FREEANCE_IDX="',i,'">',
							'<td width="15px" class="layerControlLeftColumn" padding-left:  2px;">',
							'<INPUT type="radio" name="mapNewMarkupSelector">',
							'</td><td width="*" style="padding-left: 3px;"><span class="pseudolink">',
							//'<img style="vertical-align:middle; background:',markup["color"],';" width="20px" height="',markup["thickness"],'" src="./blank.gif" /> ',
							escapeHTML((markup.description.strtrim()!='')?(markup.description):(markup.styleSheet)),
							'</span></td></tr>'
							);
					}
					htmlstr.push('<tr><td colspan="2" style="text-align: center; border-top: 1px #C0C0C0 solid; border-bottom: 1px #C0C0C0 solid; padding-left:  2px;">',
						'<span class="pseudolink" FREEANCE_TYPE="SAVE_ACTIVE_LINE"">Save Currently Drawn Polygon</span>',
						'</td></tr><tr><td colspan="2" style="text-align: center; padding-left:  2px;">',
						'<span class="pseudolink" FREEANCE_TYPE="CLEAR_ACTIVE_LINE">',
						'Erase Currently Drawn Polygon</span></td></tr>');
					}
				break;
			case 'text':
				htmlstr.push('<tr><td colspan="2" class="rightPanelFormHeader2">Text</td></tr>');
				for (var i=0;i<category.length;i++){
					var markup=category[i];
					htmlstr.push(
						'<tr FREEANCE_TYPE="text" FREEANCE_IDX="',i,'">',
						'<td width="15px" class="layerControlLeftColumn" padding-left:  2px;">',
						'<INPUT type="radio" name="mapNewMarkupSelector">',
						'</td><td width="*" style="padding-left: 3px;"><span class="pseudolink">',
						'<span style="',markup.sampleCSS,'">',
						escapeHTML((markup['sampleText'].strtrim()!='')?(markup['sampleText']):(markup['styleSheet'])),'</span>',
						'</span></td></tr>'
					);
				}
				break;
			case 'polygon':
				htmlstr.push('<tr><td colspan="2" class="rightPanelFormHeader2">Polygon</td></tr>');
				for (var i=0;i<category.length;i++){
					var markup=category[i];
					htmlstr.push(
						'<tr FREEANCE_TYPE="polygon" FREEANCE_IDX="',i,'">',
						'<td width="15px" class="layerControlLeftColumn" padding-left:  2px;">',
						'<INPUT type="radio" name="mapNewMarkupSelector">',
						'</td><td width="*" style="padding-left: 3px;"><span class="pseudolink">',
						escapeHTML((markup.description.strtrim()!='')?(markup.description):(markup.styleSheet)),
						'</span></td></tr>'
					);
				}
				htmlstr.push('<tr><td colspan="2" style="text-align: center; border-top: 1px #C0C0C0 solid; border-bottom: 1px #C0C0C0 solid; padding-left:  2px;">',
					'<span class="pseudolink" FREEANCE_TYPE="SAVE_ACTIVE_LINE"">Save Currently Drawn Polygon</span>',
					'</td></tr><tr><td colspan="2" style="text-align: center; padding-left:  2px;">',
					'<span class="pseudolink" FREEANCE_TYPE="CLEAR_ACTIVE_LINE">',
					'Erase Currently Drawn Polygon</span></td></tr>');
				break;
		}
	}
	htmlstr.push('</table>');
	$_this.markupNewPanel.innerHTML = htmlstr.join('');

	var inputTags = $_this.markupNewPanel.getElementsByTagName('INPUT');
	for(var lcv=0;lcv < inputTags.length;lcv++)
		if (inputTags[lcv].type == 'radio')
			inputTags[lcv].buttonIndex = document.mapToolbar.mapCursorRadioButtonGroup.addButton(inputTags[lcv]);

	var rows = $_this.markupNewPanel.getElementsByTagName('TR');
	for (var i=0;i<rows.length;i++){
		var row = rows[i];
		if(row.getAttribute('FREEANCE_TYPE')){
			(function(ele){
				xAddEventListener(ele,'click',function(){
					$_this.setActiveMarkup(ele.getAttribute('FREEANCE_TYPE'),parseInt(ele.getAttribute('FREEANCE_IDX')));
					var inputele = ele.getElementsByTagName('INPUT')[0];
					document.mapToolbar.mapCursorRadioButtonGroup.setActiveButton(inputele.buttonIndex);
					inputele.checked=true;
				})
			})(row);
		}
	}

	var spans = $_this.markupNewPanel.getElementsByTagName('SPAN');
	for (var i=0;i<spans.length;i++){
		var ele=spans[i];
		switch(ele.getAttribute('FREEANCE_TYPE')){
			case 'CLEAR_ACTIVE_LINE':
				xAddEventListener(ele,'click',clearActiveLine);
			break;
			case 'SAVE_ACTIVE_LINE':
				xAddEventListener(ele,'click',saveActiveLine);
				break;
		}
	}
};

function exportMarkup()
{
	var requestData = [];
	//loop through each layer to build request
	for(var themeID in existingMarkup)
	{
		if(themeID=='toJSONString')continue;
		for(var markupIdx in existingMarkup[themeID])
		{
			if(markupIdx=='toJSONString')continue;
			var newIndex = requestData.length;
			requestData[newIndex] = [themeID,markupIdx];
		}
	};
	//send request
	var result = freeance_request(null,'GIS.DrawPlane.get.batch.Shapes',mapObject.sessionID,mapObject.mapNumber,requestData);
	//build csv structure
	var csv_data = [];
	var csv_row = csv_point_row=0;
	var fieldNames = ['MARKUP_ID','DESCRIPTION','TYPE','POINT_NUMBER','X','Y','STYLE','LAYER_ID','LAYER_NAME'];
	for (var i=0;i<requestData.length;i++)
	{
		var current_markup=requestData[i];
		if (result.data[i])
		{
			var layerid=current_markup[0];
			var markupid=current_markup[1];
			for (csv_point_row=0;csv_point_row<result.data[i]['pointGroupArray'][0]['points'].length;csv_point_row++)
			{
				try{
					var current_result = result.data[i];
					var pointrowdata=current_result['pointGroupArray'][0]['points'][csv_point_row];
					csv_data[csv_row]=[
						i,
						existingMarkup[layerid][markupid].description,
						existingMarkup[layerid][markupid].type,
						csv_point_row,
						pointrowdata[0],
						pointrowdata[1],
						current_result['stylesheetName'],
						layerid,
						document.mapObject.config.themes[layerid].themeName
					];
				}
				catch(e)
				{
					console.error('Markup CSV Export Warning:  An error occurred while processing the markup entity with handle "'+requestData[i][1]+'" on layer "'+requestData[i][0]+'" where the active point was "'+csv_point_row+'"');
				};
				csv_row++;
			}
		};
	};
	//send file create request
	var csv_result = freeance_request(null,'Exporter.toCSV',',',csv_data,false,fieldNames);
	if (csv_result.XMLRPC_FAULT)
		alert('An error occurred when exporting markup to a CSV file.\n\nError Code: '+csv_result.XMLRPC_FAULT_CODE+'\nError Message:  '+csv_result.XMLRPC_FAULT_MESSAGE);
	else
	{
		//open file in new window
		if (!window.open(csv_result.data,'csv_data','width=500,height=500,resizable=yes,toolbar=no,menubar=yes'))
			alert('Warning - Unable to open CSV file.\n\nA popup blocker appears to have interrupted the CSV export.\nThe popup blocking software will need reconfigured to allow this site to open the file in a new window.');
	}
};

function drawMarkupExistingPanel()
{
	if(!$_this.markupExistingPanel) return;
	var rowcount = 0;
	var indexHtml=[
		'<div class="rightPanelForm"><div class="rightPanelFormHeader">Map Markup Index</div><table width="100%" cellpadding="0" cellspacing="0">'
		];
	for(var themeID in existingMarkup)
	{
		if(themeID=='toJSONString')continue;
		indexHtml.push('<tr><td class="rightPanelFormHeader2">',getThemeNameByThemeID(themeID),'</td>',
			'<td style="text-align: right;" class="rightPanelFormHeader2">','<span class="pseudolink" FREEANCE_TYPE="DELETE_LAYER" THEMEID="',themeID,'">',
			'<div style="height: 15px; overflow: hidden;"><img style="top: -45px; position: relative;" src="./',GuiWidget.THEME_PATH,'/',GuiWidget.THEME,'/images/icon.png" title="Clear All Markup on this Theme" /></div></span></td></tr>');
		for(var markupIdx in existingMarkup[themeID])
		{
			if(markupIdx=='toJSONString')continue;
			indexHtml.push('<tr class="',(((rowcount++%2)==1)?'tableRowEven':'tableRowOdd'),'"><td><span class="pseudolink" FREEANCE_TYPE="ZOOMTO" THEMEID="',themeID,'" MARKUPIDX="',markupIdx,'">');
			switch(existingMarkup[themeID][markupIdx].type)
			{
				case 'text':
					indexHtml.push('<span style="',markupConfig['text'][existingMarkup[themeID][markupIdx].styleSheetID].sampleCSS,'">',existingMarkup[themeID][markupIdx].description,'</span>');
					break;
				case 'zoomToResults':
					indexHtml.push('<span>',existingMarkup[themeID][markupIdx].description,'</span>');
					break;
				default:
					indexHtml.push(existingMarkup[themeID][markupIdx].description);
					break;
			};
			indexHtml.push('</span></td><td style="text-align:right;" width="*">',
			'<span class="pseudolink" FREEANCE_TYPE="ZOOMTO" THEMEID="',themeID,'" MARKUPIDX="',markupIdx,'"><div style="overflow:hidden;height:15px;"><img style="position:relative;top:-15" src="./',GuiWidget.THEME_PATH,'/',GuiWidget.THEME,'/images/icon.png" title="Zoom To Markup" /></div></span>',
			'<span class="pseudolink" FREEANCE_TYPE="DELETE" THEMEID="',themeID,'" MARKUPIDX="',markupIdx,'"><div style="overflow:hidden;height:15px;"><img src="./',GuiWidget.THEME_PATH,'/',GuiWidget.THEME,'/images/icon.png" title="Erase Markup" /></div></span>',
			'</td></tr>');
		}
	};
	indexHtml.push('</table>');
	if (rowcount == 0)
		indexHtml.push('<div class="rightPanelFormHeader" style="font-weight: normal;">No Markup Present</div>');
	else
		indexHtml.push('<div class="rightPanelFormHeader" style="font-weight: normal;"><span class="pseudolink" FREEANCE_TYPE="EXPORT">Export Markup to CSV</span></div>');
	indexHtml.push('</div>');
	$_this.markupExistingPanel.innerHTML = indexHtml.join('');
	var spans = $_this.markupExistingPanel.getElementsByTagName('span');

	for (var i=0;i<spans.length;i++){
		var ele = spans[i];
		switch(ele.getAttribute('FREEANCE_TYPE')){
		case 'ZOOMTO':
			(function(ele){xAddEventListener(ele,'click',function(){zoomToMarkupExtent(ele.getAttribute('THEMEID'),parseInt(ele.getAttribute('MARKUPIDX')));});})(ele);
			break;
		case 'DELETE':
			(function(ele){xAddEventListener(ele,'click',function(){removeExistingMarkup(ele.getAttribute('THEMEID'),parseInt(ele.getAttribute('MARKUPIDX')),true)});})(ele);
			break;
		case 'DELETE_LAYER':
			(function(ele){xAddEventListener(ele,'click',function(){clearThemeMarkup(ele.getAttribute('THEMEID'))});})(ele);
			break;
		case 'EXPORT':
			(function(ele){xAddEventListener(ele,'click',exportMarkup);})(ele);
			break;
		}
	}
	if ($_this.ondrawMarkupExistingPanel)
		$_this.ondrawMarkupExistingPanel($_this.markupExistingPanel);
};
this.drawMarkupExistingPanel=drawMarkupExistingPanel;
};

FreeanceXMLParser.prototype.parseLabelConfig = function (mapconfigNode)
{
	var labelConfigNode = null;
	var labelConfig = {
		point:[],
		line:[],
		polygon:[],
		text:[]
	};
	var newLabel = null;
	var mapChildren = mapconfigNode.childNodes;
	for (var i=0;(i<mapChildren.length)&&(!labelConfigNode);i++){
		if(mapChildren[i].nodeName=='labelConfig')
			labelConfigNode=mapChildren[i];
	}
	if(!labelConfigNode){
		return labelConfig;
	}
	var labelChildren=labelConfigNode.childNodes;
	for (var i=0;(i<labelChildren.length);i++){
		if(labelChildren[i].nodeType!=1)continue;
		var labelNode = labelChildren[i];
		var styleSheet=labelNode.getElementsByTagName("styleSheet")[0];
		var sampleURL=labelNode.getElementsByTagName("sampleURL")[0];
		var description=labelNode.getElementsByTagName("description")[0];
		var hidden=labelNode.getElementsByTagName("hidden")[0];
		var sampleCSS=labelNode.getElementsByTagName("sampleCSS")[0];
		var sampleText=labelNode.getElementsByTagName("sampleText")[0];
		var color=labelNode.getElementsByTagName("color")[0];
		var thickness=labelNode.getElementsByTagName("thickness")[0];
		var fillColor=labelNode.getElementsByTagName("fillColor")[0];
		switch(labelNode.nodeName){
			case 'pointLabel':
				newLabel = {
					styleSheet: (styleSheet?this.decodeSTRING(styleSheet):''),
					sampleURL: (sampleURL?this.decodeSTRING(sampleURL):''),
					description: (description?this.decodeSTRING(description):''),
					hidden: (hidden?(this.decodeSTRING(hidden)=='true'):false)
				};
				labelConfig['point'].push(newLabel);
				break;
			case 'polyLabel':
				newLabel = {
					styleSheet: (styleSheet?this.decodeSTRING(styleSheet):''),
					color: (color?this.decodeSTRING(color):''),
					thickness: (thickness?this.decodeSTRING(thickness):''),
					fillColor: (fillColor?this.decodeSTRING(fillColor):''),
					description: (description?this.decodeSTRING(description):''),
					hidden: (hidden?(this.decodeSTRING(hidden)=='true'):false)
				};
				labelConfig['polygon'].push(newLabel);
				break;
			case 'lineLabel':
				newLabel = {
					styleSheet: (styleSheet?this.decodeSTRING(styleSheet):''),
					color: (color?this.decodeSTRING(color):''),
					thickness: (thickness?this.decodeSTRING(thickness):''),
					description: (description?this.decodeSTRING(description):''),
					hidden: (hidden?(this.decodeSTRING(hidden)=='true'):false)
				};
				labelConfig['line'].push(newLabel);
				break;
			case 'textLabel':
				newLabel={
					styleSheet: (styleSheet?this.decodeSTRING(styleSheet):''),
					sampleCSS: (sampleCSS?this.decodeSTRING(sampleCSS):''),
					sampleText: (sampleText?this.decodeSTRING(sampleText):''),
					hidden: (hidden?(this.decodeSTRING(hidden)=='true'):false)
				};
				labelConfig['text'].push(newLabel);
				break;
		};
	}
	return labelConfig;
};

if (Freeance_Extension_Manager)
Freeance_Extension_Manager.register('markup',function(){
	if(document.mapObject.configDocNode)
		document.mapObject.config.labelConfig = document.freeance_config_parser.parseLabelConfig(document.mapObject.configDocNode);
	var control = document.markupControl = new MarkupControl('map0MarkupControl', document.mapObject, null);
	control.setConfig(document.mapObject.config.labelConfig);
  control.assignMarkupExistingPanel($('markupExistingContainer'));
	if (document.markupControl.haveMarkup)
	{
		control.assignMarkupNewPanel($('markupNewContainer'));
		control.initialize();
	};
	RightPanel_State_Manager.addLabel('markup_label','markup_new','Markup Tools');
	RightPanel_State_Manager.addPanel('markup_new','markupPanelOuterContainer',
		function(state,panelEle)
		{
			if(state)
			{
				$('markupNewContainer').style.display = 'block';
				$('markupExistingContainer').style.display='none';
			};
			$('markupPanelOuterContainer').style.display = (state)?'block':'none';
		});

	RightPanel_State_Manager.addPanel('markup_existing','markupPanelOuterContainer',
		function(state,panelEle)
		{
			if(state)
			{
				$('markupNewContainer').style.display = 'none';
				$('markupExistingContainer').style.display='block';
			};
			$('markupPanelOuterContainer').style.display = (state)?'block':'none';
		});
	if(document.applicationConfig.customOptions.markupControlLabel){
		$('markup_label').innerHTML = '<div class="controlPanelButtonText">'+document.applicationConfig.customOptions.markupControlLabel+'</div>';
	}
	return true;
});


