/***
MarkupControl.js
library for handling the map markup functions.

Dependencies:
MapLib/map.js
MapLib/mapImage.js
wz_jsgraphics


***/

MarkupControl = function (newId, newMapObject, newMapId)
{
  if (arguments.length > 0)
    this.init(newId, newMapObject, newMapId);
};

MarkupControl.prototype = new Object();
MarkupControl.constructor = MarkupControl;

MarkupControl.prototype.init = function (newId, newMapObject, newMapId)
{
  this.id = newId;
  this.cid = (this.id=='map0MarkupControl')?'':('_'+this.id);
  this.isCoreControl = (this.id=='map0MarkupControl')?true:false;
  if (newMapId!=null)
  {
    this.mapObject = OBJECT_MANAGER.getControl(newMapId);
    this.mapId = newMapId;
  }
  else
  {
    this.mapObject = newMapObject;
    this.mapId = newMapObject.id;
  }
  if (this.isCoreControl)
    this.mapObject.markupControl = this;
  this.markupRadioButtonGroup = null;
  this.markupPoints = new Array();
  this.markupNewPanel = null;
  this.markupExistingPanel = null;
  this.newMarkup = new Array();  // organized by markup type
  this.existingMarkup = new Object();  // organized by theme
  this.activeMarkupType = null;
  this.activeMarkupID = null;
  this.gfxXOffset = 0;
  this.gfxYOffset = 0;
  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
};

MarkupControl.prototype.initialize = function(attachMapClickHandlers)
{
  if (this.markupNewPanel)
    this.drawMarkupNewPanel();
  if (this.markupExistingPanel)
    this.drawMarkupExistingPanel();
  this.gfxXOffset = xPageX(this.mapObject.mapImage.drawPlaneNode.id);
  if(this.gfxXOffset == 0) // sometimes the browser just doesn't seem to get it
    this.gfxXOffset = _MapToolBarWidth;  // best guess
  this.gfxYOffset = 0; //xPageY(this.mapObject.mapImage.drawPlaneNode.id); // 0 seems to be just fine for this for some odd reason
  this.gfx = new jsGraphics(this.mapObject.mapImage.drawPlaneNode.id);
  this.gfx.setColor("#FF0000");
  this.gfx.setStroke(2);
  if (((typeof(attachMapClickHandlers)=='undefined') || (attachMapClickHandlers==true)) && (this.isCoreControl))
  {
    this.mapObject.extensionMapClickHandlers.Markuppoint = this.processMapClickEvent;
    this.mapObject.extensionMapClickHandlers.Markupline = this.processMapClickEvent;
    this.mapObject.extensionMapClickHandlers.Markuptext = this.processMapClickEvent;
  }
};

MarkupControl.prototype.initUser = function()
{
  var requestInfo = new Object;
  requestInfo.mode = 'initialize';
  makeASyncPostRequest(this, requestInfo, XMLRPC_URL,'WORKSPACE.data.get',this.mapObject.sessionID,this.id+'labelList');
};

MarkupControl.prototype.setWorkspaceData = function()
{
  var requestInfo = new Object;
  requestInfo.mode = 'setWorkspaceData';
  makeASyncPostRequest(this, requestInfo, XMLRPC_URL,'WORKSPACE.data.set',this.mapObject.sessionID,this.id+'labelList',this.existingMarkup);          
};


MarkupControl.prototype.setConfig = function(config)
{
  this.config = config;
  for(var mtype in this.config)
  {
    this.haveMarkup = true;
    switch(mtype)
    {
      case 'pointLabels':
          this.newMarkup['point'] = this.config.pointLabels;
          break;
      case 'lineLabels':
          this.newMarkup['line'] = this.config.lineLabels;
          break;
      case 'textLabels':
          this.newMarkup['text'] = this.config.textLabels;
          break;
    }
  }
};

MarkupControl.prototype.setActiveMarkup = function(mtype,ID)
{
  //var activeButton = mapCursorRadioButtonGroup.setActiveButton(-1);
  // tell mapObject to address me for clicks
  this.activeMarkupType = mtype;
  this.activeMarkupID = ID;
  if (this.activeMarkupType == 'line')
  {
    this.gfx.setColor(this.newMarkup['line'][this.activeMarkupID].color);
    this.gfx.setStroke(this.newMarkup['line'][this.activeMarkupID].thickness);
    if (this.markupPoints.length > 0)
      this.redrawActiveLine();
  }
  this.mapObject.mapImage.setMouseMode('Markup'+mtype);
  this.mapObject.mapImage.setCursor('Select');
};

MarkupControl.prototype.buildThemeSelectorPullDown = function()
{
  var html = 'Markup Layer'+': <SELECT id="markupActiveThemeSelect">';
  for(var themeID in document.mapObject.config.themes)
    html += '<OPTION value="'+themeID+'">'+document.mapObject.config.themes[themeID].themeName+'</OPTION>';
  html += '</SELECT>';
  return(html);
};

MarkupControl.prototype.getThemeNameByThemeID = function(themeID)
{
  for(var id in document.mapObject.config.themes)
    if (id == themeID)
      return(document.mapObject.config.themes[id].themeName);
  return('');
};

MarkupControl.prototype.getActiveMarkupThemeID = function()
{
  var select = document.getElementById('markupActiveThemeSelect');
  return(select.value);
};

MarkupControl.prototype.assignMarkupNewPanel = function(elem)
{
  this.markupNewPanel = elem;
};
MarkupControl.prototype.assignMarkupExistingPanel = function(elem)
{
  this.markupExistingPanel = elem;
};

MarkupControl.prototype.convertPercentToMapCoord = function(XPercent,YPercent)
{
  var mapX = (XPercent * (this.mapObject.extent[3]-this.mapObject.extent[2])) + this.mapObject.extent[2];  // XP * ExtentWidth + Left
  var mapY = (YPercent * (this.mapObject.extent[1]-this.mapObject.extent[0])) + this.mapObject.extent[0];  // YP * ExtentHeight + Bottom
  return(new Array(mapX,mapY));
};

MarkupControl.prototype.addMarkupPoint = function(description,themeID,markupID,gisStyleSheetName,pointArray,viewExtent)
{
  var requestInfo = new Object();
  requestInfo.mode = 'addMarkupPoint';
  requestInfo.description = description;
  requestInfo.themeID = themeID;
  requestInfo.markupID = markupID;
  requestInfo.gisStyleSheetName = gisStyleSheetName;
  requestInfo.viewExtent = viewExtent;
  this.mapObject.setWaiting(true);
  var doc = makeASyncPostRequest(this,requestInfo,XMLRPC_URL,'GIS.DrawPlane.add.Point',this.mapObject.sessionID,0,this.mapObject.mapImage.width(),this.mapObject.mapImage.height(),pointArray,true,themeID,gisStyleSheetName);
};

MarkupControl.prototype.addMarkupLine = function(description,themeID,markupID,gisStyleSheetName,pointArray,viewExtent)
{
  var requestInfo = new Object();
  requestInfo.mode = 'addMarkupLine';
  requestInfo.description = description;
  requestInfo.themeID = themeID;
  requestInfo.markupID = markupID;
  requestInfo.gisStyleSheetName = gisStyleSheetName;
  requestInfo.viewExtent = viewExtent;
  this.mapObject.setWaiting(true);
  var doc = makeASyncPostRequest(this,requestInfo,XMLRPC_URL,'GIS.DrawPlane.add.Line',this.mapObject.sessionID,0,this.mapObject.mapImage.width(),this.mapObject.mapImage.height(),pointArray,true,themeID,gisStyleSheetName);
};

MarkupControl.prototype.addMarkupText = function(description,themeID,markupID,gisStyleSheetName,pointArray,viewExtent,textToPlace)
{
  var requestInfo = new Object();
  requestInfo.mode = 'addMarkupText';
  requestInfo.description = description;
  requestInfo.themeID = themeID;
  requestInfo.markupID = markupID;
  requestInfo.gisStyleSheetName = gisStyleSheetName;
  requestInfo.viewExtent = viewExtent;
  this.mapObject.setWaiting(true);
  var doc = makeASyncPostRequest(this,requestInfo,XMLRPC_URL,'GIS.DrawPlane.add.Text',this.mapObject.sessionID,0,this.mapObject.mapImage.width(),this.mapObject.mapImage.height(),pointArray,true,themeID,gisStyleSheetName,textToPlace);
};

MarkupControl.prototype.processMapClickEvent = function(xPos,yPos,width,height,XPercent,YPercent,clickMode)
{
  var mapObject = document.mapObject;
  var _this = mapObject.markupControl;
  switch(clickMode)
  {
    case 'Markuppoint':
      var description = prompt("Please enter a description for this point.","");
      if (!description) return;
      var themeID = _this.getActiveMarkupThemeID();
      var gisStyleSheet = _this.newMarkup['point'][_this.activeMarkupID].styleSheet;
      var pointArray = new Array(Array(_this.convertPercentToMapCoord(XPercent,YPercent)));
      var viewExtent = mapObject.extent;
      _this.addMarkupPoint(description,themeID,_this.activeMarkupID,gisStyleSheet,pointArray,viewExtent);
      break;
    case 'Markuptext':
      var description = prompt("Please enter the text to place on the map.","");
      if (!description) return;
      var themeID = _this.getActiveMarkupThemeID();
      var gisStyleSheet = _this.newMarkup['text'][_this.activeMarkupID].styleSheet;
      var pointArray = new Array(Array(_this.convertPercentToMapCoord(XPercent,YPercent)));
      var viewExtent = mapObject.extent;
      _this.addMarkupText(description,themeID,_this.activeMarkupID,gisStyleSheet,pointArray,viewExtent,description);
      break;
    case 'Markupline':
      var coord = _this.convertPercentToMapCoord(XPercent,YPercent);
      var ptObj = new Object();
      ptObj.mapX = coord[0];
      ptObj.mapY = coord[1];
      ptObj.gfxX = _this.mapObject.mapImage.left()+xPos;
      ptObj.gfxY = _this.mapObject.mapImage.top()+yPos;
      _this.markupPoints.push(ptObj);
      if (_this.markupPoints.length > 1)
      {
        var lastPtObj = _this.markupPoints[_this.markupPoints.length-2];
        _this.gfx.drawLine(lastPtObj.gfxX-_this.gfxXOffset,lastPtObj.gfxY-_this.gfxYOffset,ptObj.gfxX-_this.gfxXOffset,ptObj.gfxY-_this.gfxYOffset);
        _this.gfx.paint();
      }
      break;
  }
};

MarkupControl.prototype.saveActiveLine = function()
{
  if (this.activeMarkupType != 'line') { 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 = this.getActiveMarkupThemeID();
  var gisStyleSheet = this.newMarkup['line'][this.activeMarkupID].styleSheet;
  var innerPointArray = new Array();
  for(var lcv=0;lcv < this.markupPoints.length;lcv++)
    innerPointArray.push(Array(this.markupPoints[lcv].mapX,this.markupPoints[lcv].mapY));
  var pointArray = new Array(innerPointArray);
  var viewExtent = this.mapObject.extent;
  this.addMarkupLine(description,themeID,this.activeMarkupID,gisStyleSheet,pointArray,viewExtent);
};

MarkupControl.prototype.clearActiveLine = function()
{
  if (this.markupPoints.length == 0)
    return;
  while(this.markupPoints.length > 0)
  {
    var ptObj = this.markupPoints.pop();
    delete ptObj;
  }
  this.gfx.clear();
};
MarkupControl.prototype.redrawActiveLine = function()
{
  this.gfx.clear();
  for(var lcv=1;lcv < this.markupPoints.length;lcv++)
  {
    var lastPtObj = this.markupPoints[lcv-1];
    var ptObj = this.markupPoints[lcv];
    this.gfx.drawLine(lastPtObj.gfxX-this.gfxXOffset,lastPtObj.gfxY-this.gfxYOffset,ptObj.gfxX-this.gfxXOffset,ptObj.gfxY-this.gfxYOffset);
  }
  this.gfx.paint();
};

MarkupControl.prototype.callback = function(serverReplyDoc, pendingOperation)
{
  this.mapObject.setWaiting(false);
  if (validateXMLDoc(serverReplyDoc))
  {
    var clientReply = new XMLRPCResponse();
    clientReply.setResponseByDoc(serverReplyDoc);
    if(clientReply.isFault())
    {
      alert('Fault '+clientReply.getFaultCode()+': '+clientReply.getFaultString());
      var data = null;
    }
    else
      var data = clientReply.getObject();
    if(data != null)
    {
      switch (pendingOperation.mode)
      {
        case 'initialize':
          delete(this.existingMarkup);
          if (data)
          {
            this.existingMarkup = data;
            this.setWorkspaceData();
          }
          else
          {
            this.existingMarkup = new Object();
            this.setWorkspaceData();
          }
          this.drawMarkupExistingPanel();
          break;
        case 'setWorkspaceData':
          break;
        case 'addMarkupPoint':
          if (this.mapObject.mapImage != null)
          {
            this.mapObject.mapImage.imageNode.src = this.mapObject.correctURL(data[0][0][1]);
            this.mapObject.extent = data[0][0][2];
          }
          if (this.mapObject.vmapImage != null)
            this.mapObject.vmapImage.imageNode.src = this.mapObject.correctURL(data[0][1][1]);
          var handle = data[1];
          this.addToExistingMarkup(pendingOperation,handle);
          this.drawMarkupExistingPanel();
          this.setWorkspaceData();
          break;
        case 'addMarkupText':
          if (this.mapObject.mapImage != null)
          {
            this.mapObject.mapImage.imageNode.src = this.mapObject.correctURL(data[0][0][1]);
            this.mapObject.extent = data[0][0][2];
          }
          if (this.mapObject.vmapImage != null)
            this.mapObject.vmapImage.imageNode.src = this.mapObject.correctURL(data[0][1][1]);
          var handle = data[1];
          this.addToExistingMarkup(pendingOperation,handle);
          this.drawMarkupExistingPanel();
          this.setWorkspaceData();
          break;
        case 'addMarkupLine':
          this.clearActiveLine();
          if (this.mapObject.mapImage != null)
          {
            this.mapObject.mapImage.imageNode.src = this.mapObject.correctURL(data[0][0][1]);
            this.mapObject.extent = data[0][0][2];
          }
          if (this.mapObject.vmapImage != null)
            this.mapObject.vmapImage.imageNode.src = this.mapObject.correctURL(data[0][1][1]);
          var handle = data[1];
          this.addToExistingMarkup(pendingOperation,handle);
          this.drawMarkupExistingPanel();
          this.setWorkspaceData();
          break;
        case 'removeMarkup':
          this.drawMarkupExistingPanel();
          this.setWorkspaceData();
          this.mapObject.redraw();
          break;
      }
    }
  }
};

MarkupControl.prototype.addToExistingMarkup = function(operationObj,handle)
{
  var markupEntryObj = new Object();
  switch(operationObj.mode)
  {
    case 'addMarkupPoint': markupEntryObj.type = 'point'; break;
    case 'addMarkupLine': markupEntryObj.type = 'line'; break;
    case 'addMarkupText': markupEntryObj.type = 'text'; break;
    case 'zoomToResults': markupEntryObj.type = 'zoomToResults'; break;
  }
  markupEntryObj.description = operationObj.description;
  markupEntryObj.themeID = operationObj.themeID;
  markupEntryObj.markupID = operationObj.markupID;
  markupEntryObj.gisStyleSheetName = operationObj.gisStyleSheetName;
  markupEntryObj.viewExtent = operationObj.viewExtent;
  markupEntryObj.drawPlaneHandle = handle;
  if (!this.existingMarkup[operationObj.themeID])
    this.existingMarkup[operationObj.themeID] = new Array();
  this.existingMarkup[operationObj.themeID].push(markupEntryObj);
  if (this.onadd)
    this.onadd(operationObj.themeID,this.existingMarkup[operationObj.themeID].length-1,markupEntryObj);  // theme, markupidx, metadata
  return(this.existingMarkup[operationObj.themeID].length-1);
};

MarkupControl.prototype.zoomToMarkupExtent = function(themeID,markupIdx)
{
  this.mapObject.zoomToExtent(this.existingMarkup[themeID][markupIdx].viewExtent);
};

MarkupControl.prototype.removeExistingMarkup = function(themeID,markupIdx,requestMap)
{
  var requestInfo = new Object();
  requestInfo.mode = 'removeMarkup';
  requestInfo.themeID = themeID;
  requestInfo.markupIdx = markupIdx;
  var mapWidth = -1;
  var mapHeight = -1;
  requestMap = false; // temp fix
  if (requestMap)
  {
    var mapDimensions = this.mapObject.getMapDimensions();
    mapWidth = mapDimensions[0][0];
    mapHeight = mapDimensions[0][1];
  }
  if (this.onremove)
    this.onremove(themeID,markupIdx);
  if (!this.clearThemeInProgress) this.mapObject.setWaiting(true);
  var drawPlaneHandle = this.existingMarkup[themeID][markupIdx].drawPlaneHandle;
  delete(this.existingMarkup[themeID][markupIdx]);
  
  var oldMarkup = cloneObject(this.existingMarkup[themeID]);
  this.existingMarkup[themeID] = new Array();
  //rebuild array; process entire theme as a sanity check
  var newIndex = 0;
  for (var oldIndex=0; oldIndex<oldMarkup.length; oldIndex++)
  {
    if (oldMarkup[oldIndex]!=null)
    {
      this.existingMarkup[themeID][newIndex] = cloneObject(oldMarkup[oldIndex]);
      newIndex++;
    }
  }
  if (!this.clearThemeInProgress)
    if (getArrayLength(this.existingMarkup[themeID]) == 0)
      delete(this.existingMarkup[themeID]);
  makeASyncPostRequest(this, requestInfo, XMLRPC_URL,'GIS.DrawPlane.remove.Shape',this.mapObject.sessionID,this.mapObject.mapNumber,themeID,drawPlaneHandle, mapWidth, mapHeight);
};

MarkupControl.prototype.clearThemeMarkup = function(themeID)
{
  var requestMap = false;
  this.mapObject.setWaiting(true);
  this.clearThemeInProgress = true;
  for(var markupIdx in this.existingMarkup[themeID])
  {
    if (getArrayLength(this.existingMarkup[themeID]) == 1)
      requestMap = true;
    this.removeExistingMarkup(themeID,markupIdx,requestMap);
  }
  delete(this.existingMarkup[themeID]);
  this.clearThemeInProgress = false;
  this.mapObject.setWaiting(false);
};

MarkupControl.prototype.drawMarkupNewPanel = function()
{
  if (!this.markupNewPanel) return;
  var indexHtml = '<div class="rightPanelFormHeader">Add New Markup</div><table width="100%" cellpadding="0" cellspacing="0">';
  indexHtml += '<tr class="rightPanelFormHeader"><td colspan="4">';
  indexHtml += this.buildThemeSelectorPullDown();
  indexHtml += '</td></tr>';
  for (var mtype in this.newMarkup)
  {
    indexHtml += '<tr>'
              +  '  <td colspan="2"  class="rightPanelFormHeader2">';
    switch(mtype)
    {
      case 'point': indexHtml += 'Points'; break;
      case 'line': indexHtml += 'Lines'; break;
      case 'text': indexHtml += 'Text'; break;
    }
    indexHtml += '  </td>'
              +  '</tr>';
    var rowcount = 0;
    var lineCount = 0;
    var maxLineCount = 0;
    if (mtype=='line')
      for(var tmp in this.newMarkup['line']) maxLineCount++;
    for(var markupID in this.newMarkup[mtype])
    {
      if (!this.newMarkup[mtype][markupID].hidden)
      {
        indexHtml+= '<tr style="'+(((rowcount%2)==0)?'background: #FEFEFF;':'')+'" onclick="document.markupControl'+this.cid+'.setActiveMarkup(\''+mtype+'\',\''+escapeQuotes(markupID)+'\');mapCursorRadioButtonGroup.setActiveButton(this.getElementsByTagName(\'INPUT\')[0].buttonIndex);this.getElementsByTagName(\'INPUT\')[0].checked=true;">'
        + '<td width="15px" class="layerControlLeftColumn" padding-left:  2px;">'
        + '<INPUT type="radio" name="mapNewMarkupSelector"></td>'
        + '<td width="*" style="padding-left: 3px;"><span class="pseudolink">';
        switch(mtype)
        {
          case 'point':
            if ((this.newMarkup[mtype][markupID].sampleURL != null)&&(this.newMarkup[mtype][markupID].sampleURL != ''))
              indexHtml += '<img style="vertical-align: middle;" src="'+this.newMarkup[mtype][markupID].sampleURL+'" />';
            indexHtml += escapeHTML((this.newMarkup[mtype][markupID].description.strtrim()!='')?(this.newMarkup[mtype][markupID].description):(markupID));
            break;
          case 'line':
            lineCount++;
            indexHtml += '<img style="vertical-align:middle; background:'+this.newMarkup[mtype][markupID]["color"]+';" width="20px" height="'+this.newMarkup[mtype][markupID]["thickness"]+'" src="'+GUI_THEME_PATH+'/'+GUI_THEME+'/images/pixel.gif" /> '
            +escapeHTML((this.newMarkup[mtype][markupID].description.strtrim()!='')?(this.newMarkup[mtype][markupID].description):(markupID));
            break;
          case 'text':
            indexHtml += '<span style="'+this.newMarkup[mtype][markupID].sampleCSS+'">'
            +escapeHTML((this.newMarkup[mtype][markupID].sampleText.strtrim()!='')?(this.newMarkup[mtype][markupID].sampleText):(markupID))
            +'</span>';
            break;
        }
        indexHtml += '</span>'
        + '</td>'
        + '</tr>';
        rowcount++;
        if ((mtype=='line') && (lineCount>=maxLineCount))
        {
          indexHtml+= '<tr>'
                   +  '  <td colspan="2" style="text-align: center; border-top: 1px #C0C0C0 solid; border-bottom: 1px #C0C0C0 solid; padding-left:  2px;">'
                   +  '  <span class="pseudolink" onclick="document.markupControl'+this.cid+'.saveActiveLine()">'+'Save Currently Drawn Line'+'</span>'
                   +  '  </td>'
                   +  '</tr>';
          rowcount++;
          indexHtml+= '<tr>'
                   +  '  <td colspan="2" style="text-align: center; padding-left:  2px;">'
                   +  '  <span class="pseudolink" onclick="document.markupControl'+this.cid+'.clearActiveLine()">Erase Currently Drawn Line</span>'
                   +  '  </td>'
                   +  '</tr>';
          rowcount++;
        }
      }
    }
  }
  indexHtml+='</table>';
  this.markupNewPanel.innerHTML = indexHtml;
  var inputTags = this.markupNewPanel.getElementsByTagName('INPUT');
  for(var lcv=0;lcv < inputTags.length;lcv++)
    if (inputTags[lcv].type == 'radio')
      inputTags[lcv].buttonIndex = mapCursorRadioButtonGroup.addButton(inputTags[lcv]);
};

MarkupControl.prototype.drawMarkupExistingPanel = function()
{
  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 this.existingMarkup)
  {
    indexHtml += '<tr>'
    + '<td colspan="4" class="rightPanelFormHeader2">'
    + this.getThemeNameByThemeID(themeID)
    + '</td>'
    + '<td style="text-align:  right;" class="rightPanelFormHeader2">'
    + '<img src="./'+GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/selectionClearTheme.png" title="Clear All Markup on this Theme" onclick="document.markupControl'+this.cid+'.clearThemeMarkup(\''+themeID+'\');" style="cursor:pointer;">'
    + '</td>'
    + '</tr>';
    for(var markupIdx in this.existingMarkup[themeID])
    {
      indexHtml+= '<tr class="'+(((rowcount%2)==1)?'tableRowEven':'tableRowOdd')+'">'
      + '<td width="1px"></td>'
      + '<td>'
      + '<span class="pseudolink" onclick="document.markupControl'+this.cid+'.zoomToMarkupExtent(\''+themeID+'\','+markupIdx+');">';
      switch(this.existingMarkup[themeID][markupIdx].type)
      {
        case 'point':
          indexHtml += (((this.newMarkup['point'][this.existingMarkup[themeID][markupIdx].markupID].sampleURL != null)&&(this.newMarkup['point'][this.existingMarkup[themeID][markupIdx].markupID].sampleURL != ''))?('<img style="vertical-align:middle" src="'+this.newMarkup['point'][this.existingMarkup[themeID][markupIdx].markupID].sampleURL+'" />'):(''))+this.existingMarkup[themeID][markupIdx].description;
          break;
        case 'line':
          indexHtml += '<img style="vertical-align:middle;background:'+this.newMarkup['line'][this.existingMarkup[themeID][markupIdx].markupID]["color"]+';" width="20px" height="'+this.newMarkup['line'][this.existingMarkup[themeID][markupIdx].markupID]["thickness"]+'px" src="'+GUI_THEME_PATH+'/'+GUI_THEME+'/images/pixel.gif" /> '+this.existingMarkup[themeID][markupIdx].description;
          break;
        case 'text':
          indexHtml += '<span style="'+this.newMarkup['text'][this.existingMarkup[themeID][markupIdx].markupID].sampleCSS+'">'+this.existingMarkup[themeID][markupIdx].description+'</span>';
          break;
        case 'zoomToResults':
          indexHtml += '<span>'+this.existingMarkup[themeID][markupIdx].markupID+'</span>';
          break;
        default:
          alert('Unknown Markup Type.\nTheme:  '+themeID+'\nID:  '+this.existingMarkup[themeID][markupIdx].markupID+'\nType:  '+this.existingMarkup[themeID][markupIdx].type);
          break;
      }
      indexHtml += '</span>'
      + '</td>'
      + '<td width="*">&nbsp;</td>'
      + '<td style="text-align:right;" width="15px"><img src="./'+GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/selectionZoom.png"  title="Zoom To Markup" onclick="document.markupControl'+this.cid+'.zoomToMarkupExtent(\''+themeID+'\','+markupIdx+');" style="cursor:pointer;"></td>'
      + '<td style="text-align:right;" width="15px"><img src="./'+GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/selectionClear.png" title="Erase Markup" onclick="document.markupControl'+this.cid+'.removeExistingMarkup(\''+themeID+'\','+markupIdx+',false);" style="cursor:pointer;"></td>'
      + '</tr>';
      rowcount++;
    }
  }
  indexHtml+='</table>';
  if (rowcount == 0)
    indexHtml+='<div class="rightPanelFormHeader" style="font-weight: normal;">No Markup Present</div>';
  indexHtml+='</div>';
  this.markupExistingPanel.innerHTML = indexHtml;
  if (this.ondrawMarkupExistingPanel)
    this.ondrawMarkupExistingPanel(this.markupExistingPanel);
};
