//Map.js
//Map Object
//  Handles the display of and user interaction with a map displayed on a map
//  panel.  Maintains extent state information, list of active / inactive
//  themes, etc.
//
//  If the vicinity map resource is an empty string, then no vicinity map will be used.

Map = function (newId)
{
  //note:  used to have a configuration parameter in constructor but this has
  //  been elimnated in version 3; use the setConfig function instead.
  OBJECT_MANAGER.addControl(this,'map', newId);
  this.id        = newId;

  this.config = null;
  this.mapNumber = 0;
  this.clientVersion = null;
  this.serverVersion = null;

  //interface objects directly controlled by the map object
  this.mapImage       = null;
  this.mapLoadImage = null;
  this.vmapPresent = false;
  this.vmapImage     = null;
  this.mapLoadImage = null;
  this.legendImage = null;
  this.customLegendImage = null;  //will be a string if a custom legend image should be used.
  
  //Ancillary controls
  this.bookmarkControl = null;
  this.markupControl = null;
  this.layerControl = null;
  this.bufferControl = null;
  this.themeControl = null;
  this.selectionControl = null;
  this.coordConvControl = null;
  this.measureControl = null;
  this.geocodeControl = null;
  this.zoomBar = null;
  this.scaleBar = null;

  this.extensionMapClickHandlers = new Array();  // JPW
  
  //session specific data
  this.sessionID = null;
  this.extent    = new Array;        //extent of main map
  this.dragExtent = Array(0,0,0,0);  //drag extent tracker
  this.vmapExtent    = new Array;    //extent of vicinity map
  this.bookmarks = new Array();      //contains bookmarks for current session
  this.bookmark_redrawmaps = true;    //???
  this.legendVisible = null;          //is the legend currently displayed?
  this.legendSync    = false;         //does the legend match the current map display?
  this.numWaitingRequests = 0;        //counter for load image
  this.printOptions = null;
  this.zoomFactor = 1.5;
  this.initialExtent = null;
  this.activeMapScheme = null;
  this.firstLoad = true;
  this.dragTileCounter = 0;
  this.dragTileSessionId = null;
  this.configDocNode = null;          //document node containing config data
this.eventCallbacks = {
  layerChange: [],
  imageChange: [],
  tileLoadStart: [],
  tileLoadFinish: []
};

this.setConfig = function(newConfig)
{
  this.config = newConfig;
  if (this.layerControl)
    this.layerControl.draw();
  this.selectionsExist = false;
  var selectionCount = 0;
  this.buffersExist = false;
  var bufferCount = 0;
  this.selectableThemes = new Array();
  this.bufferableThemes = new Array();
  for (var currentTheme in this.config.themes)
  {
    if(currentTheme=='toJSONString')continue;
    if (this.config.themes[currentTheme].selectOptions != null)
    {
      this.selectionsExist = true;
      this.selectableThemes[this.selectableThemes.length] = currentTheme;
      selectionCount++;
    }
    if (this.config.themes[currentTheme].bufferOptions != null)
    {
      this.bufferableThemes[this.bufferableThemes.length] = currentTheme;
      this.buffersExist = true;
      bufferCount++;
    }
  }
  
  this.vmapPresent = (this.config["vmap"]["resourceId"] != '');
  //Check for existence of ancillary controls and initialize
  if (this.selectionControl)
    this.selectionControl.initialize();
  if (this.bufferControl)
    this.bufferControl.initialize(this.bufferableThemes);
  if (this.coordConvControl)
    this.coordConvControl.draw();
  if (this.measureControl)
    this.measureControl.initialize();
  if (this.geocodeControl)
    this.geocodeControl.initialize();
};

this.initialize = function(sessionID)
{
  //arguments[1] = scheme id (if present)
  var useMapScheme = false;
  if (arguments.length > 0)
    if (arguments[1] != null)
      useMapScheme = true;
  var map0 = Array(this.config["resourceId"], this.config["previousStates"],this.mapImage.width(),this.mapImage.height(),false);
  if (this.vmapImage != null)
  {
    var map1 = Array(this.config["vmap"]["resourceId"],0,this.vmapImage.width(),this.vmapImage.height(),true,0,this.config["vmap"]["slaveType"],this.config["vmap"]["boundBoxPercentMin"],this.config["vmap"]["styleSheet"]);
    var map_args = Array(map0,map1);
  }
  else
  {
    var map_args = Array(map0);
  }
  if (this.scalebar != null)
    this.scalebar.initialize();
  this.setWaiting(true);
  if (useMapScheme&&(this.config.mapSchemeConfig.mapSchemes.length>0))
  {    
    var mapSchemes = this.config.mapSchemeConfig.mapSchemes;
    var schemeId = arguments[1];
    var idx=0;
    for (var i=0;i<mapSchemes.length;i++){
      if(mapSchemes[i]['id']==schemeId)
        idx=i;
    }
    this.activeMapScheme = schemeId;
    var scheme=mapSchemes[idx];
    var themeArray = new Array();
    for (var currentTheme in scheme.themes)
    {
      if(currentTheme=='toJSONString')continue;
      var theme=scheme.themes[currentTheme];
      themeArray.push([theme.id,(theme.display==1),theme.legend]);
    };
    makeASyncPostRequest(this, 'Initialize_withScheme', XMLRPC_URL, 'GIS.Session.initialize.with.preset.scheme', sessionID, map_args, themeArray);
  }
  else
    makeASyncPostRequest(this, 'Initialize', XMLRPC_URL,'GIS.Session.initialize',sessionID,map_args);
};

this.setMapLoadImage = function(newImagePanel)
{
  this.mapLoadImage = newImagePanel;
};

this.setMapImage = function(newMapImage)
{
  this.mapImage = newMapImage;
};

this.setVmapLoadImage = function(newImagePanel)
{
  this.vmapLoadImage = newImagePanel;
};

this.setVmapImage = function(newMapImage)
{
  this.vmapImage = newMapImage;
};

this.setLegendImage = function(newLegendImage, newLegendVisibility)
{
  this.legendImage = newLegendImage;
  this.legendVisible = newLegendVisibility;   //initial visibility of legend; will it be displayed when the page loads?
  this.legendSync    = false;
};

this.setWaiting = function(state)
{
  if (state)
  {
    if (this.mapImage != null)
      this.mapImage.setWaiting(true);
    if (this.vmapImage != null)
      this.vmapImage.setWaiting(true);
    this.numWaitingRequests++;
  }
  else
  {
    this.numWaitingRequests--;
    if (this.numWaitingRequests <= 0)
    {
      if (this.mapImage != null)
        this.mapImage.setWaiting(false);
      if (this.vmapImage != null)
        this.vmapImage.setWaiting(false);
    }
  }
};

this.getMapDimensions = function()
{
  if (this.vmapImage != null)
    return Array(Array(this.mapImage.width(),this.mapImage.height()),Array(this.vmapImage.imageNode.cbe.width(),this.vmapImage.imageNode.cbe.height()));    
  else
    return Array(Array(this.mapImage.width(),this.mapImage.height()))
};

this.loadLegend = function()
{
  if (this.customLegendImage!=null)
    this.legendImage.src = this.customLegendImage;
  else{
      makeASyncPostRequest(this,'Legend',XMLRPC_URL,'GIS.Legend.getImage',this.sessionID,0,this.config["legendAttributes"]["width"],this.config["legendAttributes"]["height"],this.config["legendAttributes"]["color"],this.config["legendAttributes"]["font"],this.config["legendAttributes"]["fontSize"],this.config["legendAttributes"]["valueFontSize"],this.config["legendAttributes"]["cellSpacing"]);
  }
};

this.loadLegendSync = function()
{
  if (this.customLegendImage!=null)
    this.legendImage.src = this.customLegendImage;
  else{
    var oldURL = this.legendImage.src; 
    this.setWaiting(true);
    var xmlrpcResponse = makeSyncPostRequest(XMLRPC_URL,'GIS.Legend.getImage',this.sessionID,0,this.config["legendAttributes"]["width"],this.config["legendAttributes"]["height"],this.config["legendAttributes"]["color"],this.config["legendAttributes"]["font"],this.config["legendAttributes"]["fontSize"],this.config["legendAttributes"]["valueFontSize"],this.config["legendAttributes"]["cellSpacing"]);
    var result = getXMLRPCResponseObject(xmlrpcResponse);
    var data = result.data;
    if(data != null)
    {
      this.legendImage.src = this.correctURL(data);
      //xMoveTo(this.legendImage,0,0);
      this.legendSync = true;
    }
    else
      alert('Communication Error:  Unable to load legend image');
    this.setWaiting(false);
  }
};

this.mouseMove = function(xPos,yPos,width,height,XPercent,YPercent,clickMode)
{
  switch (clickMode)
  {
    case 'MeasureDistance':
      this.setWaiting(false);
      var mapImageX = this.mapImage.left();
      var mapImageY = this.mapImage.top();
      var measurePointX = mapImageX + xPos;
      var measurePointY = mapImageY + yPos;
      var mapX = (XPercent * (this.extent[3]-this.extent[2])) + this.extent[2];  // XP * ExtentWidth + Left
      var mapY = (YPercent * (this.extent[1]-this.extent[0])) + this.extent[0];  // YP * ExtentHeight + Bottom
      if (this.measureControl != null)
      {
        this.measureControl.distanceCalculate({x:mapX,y:mapY});
        this.measureControl.areaCalculate({x:mapX,y:mapY});
      }
      else
        alert('Application Error\n'+this.id+'.click('+xPos+','+yPos+','+width+','+height+','+XPercent+','+YPercent+','+clickMode+')\nAttempting to process a measure point, but there is no measure control defined for the map object');
      break;
  }
}


this.click = function(xPos,yPos,width,height,XPercent,YPercent,clickMode)
{
  if ((clickMode != 'ZoomBox')&&(clickMode != 'MeasureDistance'))
    this.setWaiting(true);
  switch (clickMode)
  {
    case 'MeasureDistance':  // ADDED-BY: JPW
      //this.setWaiting(false);
      var measurePointX = xPos;
      var measurePointY = yPos;
      var mapX = (XPercent * (this.extent[3]-this.extent[2])) + this.extent[2];  // XP * ExtentWidth + Left
      var mapY = (YPercent * (this.extent[1]-this.extent[0])) + this.extent[0];  // YP * ExtentHeight + Bottom
      if (this.measureControl != null)
      {
        this.measureControl.distanceAddPoint(mapX,mapY);
        this.measureControl.distanceAddPointImage(measurePointX,measurePointY,xZIndex(this.mapImage.eventHandlerNode)+1);
        this.measureControl.distanceCalculate();
        this.measureControl.areaCalculate();
      }
      else
        alert('Application Error\n'+this.id+'.click('+xPos+','+yPos+','+width+','+height+','+XPercent+','+YPercent+','+clickMode+')\nAttempting to process a measure point, but there is no measure control defined for the map object');
      break;
    case 'ZoomIn':
      makeASyncPostRequest(this,clickMode,XMLRPC_URL,'GIS.Zoom.in.byPercent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),1.5,XPercent,YPercent);
      this.legendSync = false;
      break;
    case 'ZoomOut':
      makeASyncPostRequest(this,clickMode,XMLRPC_URL,'GIS.Zoom.out.byPercent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),1.5,XPercent,YPercent);
      this.legendSync = false;
      break;
    case 'Center':
      makeASyncPostRequest(this,clickMode,XMLRPC_URL,'GIS.Center.byPercent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),XPercent,YPercent);
      break;
    case 'Select':
      /** Select across all selectable themes **/
      var currentTheme = '';
      if (document.queryControl)
        document.queryControl.clearResults();
      document.getElementById('textResultTabContainer').innerHTML = '';
      this.clearAllBuffers();
      this.clearAllGeocodePoints();
      this.clearAllSelections();
      for (var currentThemeIndex = 0; currentThemeIndex < this.selectableThemes.length; currentThemeIndex++)
      {
        currentTheme = this.selectableThemes[currentThemeIndex];
        //this.clearThemeSelectionsSync(currentTheme);
        if (this.config.themes[currentTheme].visibility && (this.config.themes[currentTheme].selectOptions != null)&&this.selectionsExist)   //only process if the theme is displayed and configured for selection
        {
          var activeThemeTolerance=-1;  // use the server-side default for this theme
          var activeThemeName = currentTheme;
          var GIS_stylesheet = this.config.themes[currentTheme].selectOptions.styleSheet;
          var fieldsList = this.config.themes[currentTheme].selectOptions.fieldList;
          var activeThemeMaxSelectCount = this.config.themes[currentTheme].selectOptions.limit;
          var requestDetails = new Object;
          requestDetails["request"] = 'newSelection';
          requestDetails["themeId"] = currentTheme;
          requestDetails["deselect"] = false;
          if(this.config.themes[currentTheme].selectOptions.sqlParams)
          {
            var configSQLParams = this.config.themes[currentTheme].selectOptions.sqlParams;
            var sqlParams = Array();
            for(var pos=0;pos < configSQLParams.length;pos++)
            {
              sqlParams[pos] = Array();
              sqlParams[pos][0] = configSQLParams[pos].pdqIdentifier;
              var fieldPairs = Array();
              var limits = Array();
              for(var lcv=0;lcv < configSQLParams[pos].fieldList.length;lcv++)
              {
                fieldPairs[lcv] = Array();
                fieldPairs[lcv][0] = configSQLParams[pos].fieldList[lcv].fieldName;
                fieldPairs[lcv][1] = configSQLParams[pos].fieldList[lcv].pdqFieldName;
              }
              sqlParams[pos][1] = fieldPairs;
              if (configSQLParams[pos].queryType != '')
              {
                limits[0] = configSQLParams[pos].queryType;
                limits[1] = configSQLParams[pos].numRows;
                limits[2] = configSQLParams[pos].startAt;
                sqlParams[pos][2] = limits;
              }
            }
            xypoints = Array(Array(XPercent,YPercent));
            coordsinpercent = true;
            makeASyncPostRequest(this.selectionControl,requestDetails,XMLRPC_URL,'GIS.Selection.entity.byPoint',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),xypoints,coordsinpercent,activeThemeName,activeThemeTolerance,fieldsList,false,GIS_stylesheet,1,sqlParams);
          }
          else
          {
            xypoints = Array(Array(XPercent,YPercent));
            coordsinpercent = true;
            makeASyncPostRequest(this.selectionControl,requestDetails,XMLRPC_URL,'GIS.Selection.entity.byPoint',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),xypoints,coordsinpercent,activeThemeName,activeThemeTolerance,fieldsList,false,GIS_stylesheet,1);
          }
          this.redraw();
        }
        else
        {
          this.setWaiting(false);
        }
      }
      break;
      default:  // JPW
        if (this.extensionMapClickHandlers[clickMode])
        {
          this.setWaiting(false);
          this.extensionMapClickHandlers[clickMode](xPos,yPos,width,height,XPercent,YPercent,clickMode);
        }
        break;
  }
  return;
};

this.bufferOnCenter = function(bufferTheme, bufferDistance, MaxBufferCount)
{
  //this.setWaiting(true);
  document.getElementById('textResultTabContainer').innerHTML = '';
  this.clearAllBuffers();
  this.clearAllSelections();
  this.clearAllGeocodePoints();
  this.setWaiting(true);
  var GIS_stylesheet = this.config.themes[bufferTheme].bufferOptions.styleSheet;
  var bufferFieldList = this.config.themes[bufferTheme].bufferOptions.fieldList;
  var clearFirst = true;
  if (bufferDistance == 0) bufferDistance = 0.1;
  if (MaxBufferCount == 0) MaxBufferCount = ((this.config.themes[bufferTheme].bufferOptions.maxSelect>0)?(this.config.themes[bufferTheme].bufferOptions.maxSelect):(1));
  var bufferSQLparams = this.bufferControl.getSQLParams();
  if(this.config.themes[bufferTheme].bufferOptions.sqlParams != null)
  {
    var configSQLParams = this.config.themes[bufferTheme].bufferOptions.sqlParams;
    var sqlParams = Array();
    for(var pos=0;pos < configSQLParams.length;pos++)
    {
      sqlParams[pos] = Array();
      sqlParams[pos][0] = configSQLParams[pos].pdqIdentifier;
      var fieldPairs = Array();
      var limits = Array();
      for(var lcv=0;lcv < configSQLParams[pos].fieldList.length;lcv++)
      {
        fieldPairs[lcv] = Array();
        fieldPairs[lcv][0] = configSQLParams[pos].fieldList[lcv].fieldName;
        fieldPairs[lcv][1] = configSQLParams[pos].fieldList[lcv].pdqFieldName;
      }
      sqlParams[pos][1] = fieldPairs;
      if (configSQLParams[pos].queryType != '')
      {
        limits[0] = configSQLParams[pos].queryType;
        limits[1] = configSQLParams[pos].numRows;
        limits[2] = configSQLParams[pos].startAt;
       sqlParams[pos][2] = limits;
      }
    }
  }
  else
    var sqlParams = new Array();    
  makeASyncPostRequest(this.bufferControl,Array('BufferXY',bufferTheme),XMLRPC_URL,'GIS.Buffer.at.XY',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),0.5,0.5,true,bufferTheme,bufferDistance,bufferFieldList,true,GIS_stylesheet,MaxBufferCount,sqlParams);
};

this.bufferOnSelection = function(newSelectionHandle, newSourceTheme, newTargetTheme, newDistance, newSQLParams, newBufferSQLParams, newClearFirst)
{
  if (newSQLParams == null)
  {
    var bufferSQLparams = this.bufferControl.getSQLParams();
    if(this.config.themes[newTargetTheme].bufferOptions.sqlParams != null)
    {
      var configSQLParams = this.config.themes[newTargetTheme].bufferOptions.sqlParams;
      var sqlParams = Array();
      for(var pos=0;pos < configSQLParams.length;pos++)
      {
        sqlParams[pos] = Array();
        sqlParams[pos][0] = configSQLParams[pos].pdqIdentifier;
        var fieldPairs = Array();
        var limits = Array();
        for(var lcv=0;lcv < configSQLParams[pos].fieldList.length;lcv++)
        {
          fieldPairs[lcv] = Array();
          fieldPairs[lcv][0] = configSQLParams[pos].fieldList[lcv].fieldName;
          fieldPairs[lcv][1] = configSQLParams[pos].fieldList[lcv].pdqFieldName;
        }
        sqlParams[pos][1] = fieldPairs;
        if (configSQLParams[pos].queryType != '')
        {
          limits[0] = configSQLParams[pos].queryType;
          limits[1] = configSQLParams[pos].numRows;
          limits[2] = configSQLParams[pos].startAt;
         sqlParams[pos][2] = limits;
        }
      }
    }
    else
      var sqlParams = new Array();    
  }
  
  var bufferThemeParams = this.config.themes[newTargetTheme].bufferOptions;
  var GIS_stylesheet = this.config.themes[newTargetTheme].bufferOptions.styleSheet;
  var bufferFieldList = this.config.themes[newTargetTheme].bufferOptions.fieldList;
  var MaxBufferCount = this.config.themes[newTargetTheme].bufferOptions.maxSelect;
  var MapWidth = this.mapImage.width();
  var MapHeight = this.mapImage.height();

  this.setWaiting(true);
  if (bufferSQLparams == null)
    makeASyncPostRequest(this.bufferControl,Array('BufferOnSelection',newTargetTheme),XMLRPC_URL,'GIS.Buffer.on.Selection',this.sessionID,0,MapWidth,MapHeight,newSelectionHandle,newSourceTheme,newTargetTheme,newDistance,bufferFieldList,newClearFirst,GIS_stylesheet,MaxBufferCount,sqlParams);
  else
    makeASyncPostRequest(this.bufferControl,Array('BufferOnSelection',newTargetTheme),XMLRPC_URL,'GIS.Buffer.on.Selection',this.sessionID,0,MapWidth,MapHeight,newSelectionHandle,newSourceTheme,newTargetTheme,newDistance,bufferFieldList,newClearFirst,GIS_stylesheet,MaxBufferCount,sqlParams,newBufferSQLParams);
};

this.centerOnPoint = function(newMapX,newMapY)
{
  //accepts a new x,y coordinate pair in the current map units
  this.setWaiting(true);
  makeASyncPostRequest(this,'CenterOnPoint',XMLRPC_URL,'GIS.Center.onPoint',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),newMapX,newMapY);
};

this.clickVmap = function (xPosition,yPosition,imageWidth, imageHeight)  // ASYNC
{
  var XPercent = xPosition / imageWidth;
  var YPercent = 1.0 - (yPosition / imageHeight);
  var mapX = (XPercent * (this.vmapExtent[3]-this.vmapExtent[2])) + this.vmapExtent[2];  // XP * ExtentWidth + Left
  var mapY = (YPercent * (this.vmapExtent[1]-this.vmapExtent[0])) + this.vmapExtent[0];  // YP * ExtentHeight + Bottom
  this.setWaiting(true);
  makeASyncPostRequest(this,'CenterOnPoint',XMLRPC_URL,'GIS.Center.onPoint',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),mapX,mapY);
};

this.pan = function(DirStr)
{
  this.setWaiting(true);
  var mapData = makeASyncPostRequest(this,'Pan',XMLRPC_URL,'GIS.Pan.byDirection',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),DirStr,0.4);
};

this.zoomInitialExtent = function()
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomInitialExtent',XMLRPC_URL,'GIS.Zoom.to.initialExtent',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};

this.zoomFullExtent = function()
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomInitialExtent',XMLRPC_URL,'GIS.Zoom.to.fullExtent',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};

this.zoomPresetExtent = function(newPresetName)
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomPresetExtent',XMLRPC_URL,'GIS.Zoom.to.presetExtent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),newPresetName);
};

this.zoomIn = function()
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomIn',XMLRPC_URL,'GIS.Zoom.in',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),this.zoomFactor);
};

this.zoomOut = function()
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomOut',XMLRPC_URL,'GIS.Zoom.out',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),this.zoomFactor);
};

this.zoomTo = function(themeIndex, SQLstr, select)
{
  //Zooms to an entity on a theme, with the option to select the object.
  //themeIndex is the index of the theme to perform the zoom on
  //SQLstr is a query string used to identify the unique object
  //select is a boolean indicating whether or not to select the object if it is found
  //
  if (select)
  {
    if (document.queryControl)
      document.queryControl.clearResults();
    document.getElementById('textResultTabContainer').innerHTML = '';
    this.clearAllBuffers();
    this.clearAllGeocodePoints();
    this.clearAllSelections();
  }
  this.setWaiting(true);
  this.legendSync = false;
  if (!this.selectionsExist)
    select = false;
  var GIS_stylesheet = this.config.themes[themeIndex].selectOptions.styleSheet;
  if (select)
  {
    var requestDetails = new Object;
    requestDetails["request"] = 'newSelection';
    requestDetails["themeId"] = themeIndex;
    requestDetails["deselect"] = false;
    if(this.config.themes[themeIndex].selectOptions.sqlParams != null)
    {
      var configSQLParams = this.config.themes[themeIndex].selectOptions.sqlParams;
      var sqlParams = Array();
      for(var pos=0;pos < configSQLParams.length;pos++)
      {
        sqlParams[pos] = Array();
        sqlParams[pos][0] = configSQLParams[pos].pdqIdentifier;
        var fieldPairs = Array();
        var limits = Array();
        for(var lcv=0;lcv < configSQLParams[pos].fieldList.length;lcv++)
        {
          fieldPairs[lcv] = Array();
          fieldPairs[lcv][0] = configSQLParams[pos].fieldList[lcv].fieldName;
          fieldPairs[lcv][1] = configSQLParams[pos].fieldList[lcv].pdqFieldName;
        }
        sqlParams[pos][1] = fieldPairs;
        if (configSQLParams[pos].queryType != '')
        {
          limits[0] = configSQLParams[pos].queryType;
          limits[1] = configSQLParams[pos].numRows;
          limits[2] = configSQLParams[pos].startAt;
          sqlParams[pos][2] = limits;
        }
      }
      makeASyncPostRequest(this.selectionControl,requestDetails,XMLRPC_URL,'GIS.Zoom.to.entities',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),themeIndex,this.config.themes[themeIndex].selectOptions.fieldList,SQLstr,this.config.themes[themeIndex].selectOptions.zoomExtentRatio,1,select,select,false,GIS_stylesheet,sqlParams);
    }
    else
    {
      makeASyncPostRequest(this.selectionControl,requestDetails,XMLRPC_URL,'GIS.Zoom.to.entities',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),themeIndex,this.config.themes[themeIndex].selectOptions.fieldList,SQLstr,this.config.themes[themeIndex].selectOptions.zoomExtentRatio,1,select,select,false,GIS_stylesheet);
    }
  }
  else
  {
    makeASyncPostRequest(this,'zoomTo',XMLRPC_URL,'GIS.Zoom.to.entities',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),themeIndex,this.config.themes[themeIndex].selectOptions.fieldList,SQLstr,this.config.themes[themeIndex].selectOptions.zoomExtentRatio,1,select,select,false,GIS_stylesheet);
  }
  scrollToTopOfScreen();
};

this.zoomTo_ = function(layerid,attrib,fieldtype,value,select)
{
    //same effect as zoomTo, but without a specified where clause
  // attrib is map attribute to match
  // fieldtype(int) is the ims field type
  // value is the value to match against attrib
  var quote=((fieldtype==8)||(fieldtype==12)||(fieldtype==1)||(fieldtype==91));
  var sqlstr=attrib+"="+(quote?"'":"")+value+(quote?"\'":"");
  this.zoomTo(layerid,sqlstr,select);
};

this.zoomToSelection = function(themeIndex, SQLstr, select)
{
  this.setWaiting(true);
  this.legendSync = false;
  var GIS_stylesheet = this.config.themes[themeIndex].selectOptions.styleSheet;
  if (select)
  {
    if(this.config.themes[themeIndex].selectOptions.sqlParams != null)
    {
      var configSQLParams = this.config.themes[themeIndex].selectOptions.sqlParams;
      var sqlParams = Array();
      for(var pos=0;pos < configSQLParams.length;pos++)
      {
        sqlParams[pos] = Array();
        sqlParams[pos][0] = configSQLParams[pos].pdqIdentifier;
        var fieldPairs = Array();
        var limits = Array();
        for(var lcv=0;lcv < configSQLParams[pos].fieldList.length;lcv++)
        {
          fieldPairs[lcv] = Array();
          fieldPairs[lcv][0] = configSQLParams[pos].fieldList[lcv].fieldName;
          fieldPairs[lcv][1] = configSQLParams[pos].fieldList[lcv].pdqFieldName;
        }
        sqlParams[pos][1] = fieldPairs;
        if (configSQLParams[pos].queryType != '')
        {
          limits[0] = configSQLParams[pos].queryType;
          limits[1] = configSQLParams[pos].numRows;
          limits[2] = configSQLParams[pos].startAt;
          sqlParams[pos][2] = limits;
        }
      }
      makeASyncPostRequest(this,'zoomToSelection',XMLRPC_URL,'GIS.Zoom.to.entities',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),themeIndex,"*",SQLstr,this.config.themes[themeIndex].selectOptions.zoomExtentRatio,1,select,select,false,GIS_stylesheet,sqlParams);
    }
    else
      makeASyncPostRequest(this,'zoomToSelection',XMLRPC_URL,'GIS.Zoom.to.entities',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),themeIndex,"*",SQLstr,this.config.themes[themeIndex].selectOptions.zoomExtentRatio,1,select,select,false,GIS_stylesheet);
  }
  else
    makeASyncPostRequest(this,'zoomToSelection',XMLRPC_URL,'GIS.Zoom.to.entities',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),themeIndex,"*",SQLstr,this.config.themes[themeIndex].selectOptions.zoomExtentRatio,1,select,select,false,GIS_stylesheet);
};

this.zoomToExtent = function(newExtent)
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomToExtent',XMLRPC_URL,'GIS.Zoom.to.extent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),newExtent);
};

this.refresh = function()
{
  this.setWaiting(true);
  makeASyncPostRequest(this,'MapRedraw',XMLRPC_URL,'GIS.Map.redraw',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};

this.redraw = function()
{
  this.setWaiting(true);
  makeASyncPostRequest(this,'MapRedraw',XMLRPC_URL,'GIS.Map.redraw',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};

this.zoomToPrevious = function()
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomPrevious',XMLRPC_URL,'GIS.Zoom.to.previousExtent',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};

this.zoomToWindow = function(bottom,top,left,right)
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomWindow',XMLRPC_URL,'GIS.Zoom.to.windowPercent',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),bottom,top,left,right);
};

this.zoombar = function (ratio,divnum,numdivs)
{
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'ZoomBar',XMLRPC_URL,'GIS.Zoom.by.bar',this.sessionID,0,this.mapImage.width(),this.mapImage.height(),ratio,divnum,numdivs);
};

this.setThemes = function(newThemeList)
{
  for (i=0; i<newThemeList.length; i++)
  {
    this.themeLookup[newThemeList[i][0]] = i;
    this.themes[i] = new Array(newThemeList[i], "off");
  }
};

this.getThemeByName = function(newThemeName)
{
  return this.themes[this.themeLookup[newThemeName]];
};

this.setActiveTheme = function(newActiveTheme)
{
  this.config.activeTheme = newActiveTheme;
  if (this.layerControl)
    this.layerControl.update();
};

this.getBookmarkList = function ()
{
  //does not set the load image since it does not interfere with map operations
  if (this.bookmarkControl!=null)
    makeASyncPostRequest(this,'getBookmarkList',XMLRPC_URL,'GIS.Geobookmark.get.list',this.sessionID);
};

this.addBookmark = function (name)
{
  if (name != '')
    makeASyncPostRequest(this,'addBookmark',XMLRPC_URL,'GIS.Geobookmark.add.state',this.sessionID,0,name,false,false);
};

this.gotoBookmark = function (bookmarkIndex)
{
  var name = this.bookmarks[bookmarkIndex];  
  this.setWaiting(true);
  this.legendSync = false;
  makeASyncPostRequest(this,'gotoBookmark',XMLRPC_URL,'GIS.Geobookmark.restore.state',this.sessionID,0,name,this.bookmark_redrawmaps,true,true,true,false);
};

this.removeBookmark = function(bookmarkIndex)
{
  var name = this.bookmarks[bookmarkIndex];  
  this.setWaiting(true);
  makeASyncPostRequest(this,'removeBookmark',XMLRPC_URL,'GIS.Geobookmark.remove.state',this.sessionID,name);
};

this.loadThemes = function()
{
  //this.setWaiting(true);
  makeASyncPostRequest(this,'getThemes',XMLRPC_URL,'GIS.Themes.getList',this.sessionID,0);
};

this.setThemeState = function(themeName, visible)
{
  var themeArray = [[themeName,visible]];
  this.config["themes"][themeName]["visibility"] = visible;
  this.legendSync = false;
  if (this.activeMapScheme!=null)
    this.config.mapSchemeConfig.mapSchemes[this.activeMapScheme].themes[themeName].display=(visible?1:0);
  makeASyncPostRequest(this, 'setThemes', XMLRPC_URL, 'GIS.Themes.setList', this.sessionID, 0, themeArray);
};

this.setMapScheme = function(schemeId)
{
  var themeArray = [];
  var themes = this.config.mapSchemeConfig.mapSchemes[parseInt(schemeId)].themes;
  for (var cT in themes)
  {
    if(currentTheme=='toJSONString')continue;
    var currentTheme = themes[cT];
    themeArray.push([currentTheme.id,(currentTheme.display==1),currentTheme.legend]);
  };
  this.setWaiting(true);
  this.legendSync = false;
  this.activeMapScheme=parseInt(schemeId);
  makeASyncPostRequest(this, 'setMapScheme', XMLRPC_URL, 'GIS.Themes.setScheme', this.sessionID, 0, themeArray);
};

this.clearSelection = function(themeIndex, selectionHandle)
{
  this.setWaiting(true);
  makeASyncPostRequest(this.selectionControl,{request:  'clearSelection',themeIndex:themeIndex,handle: selectionHandle},XMLRPC_URL,'GIS.Selection.clear.EntityFromTheme',this.sessionID,0,themeIndex, selectionHandle, this.mapImage.width(),this.mapImage.height());
};

this.clearDuplicateSelection = function(themeIndex, selectionHandle)
{
  this.setWaiting(true);
  makeASyncPostRequest(this.selectionControl,{request: 'clearDuplicateSelection',themeIndex: themeIndex,handle: selectionHandle},XMLRPC_URL,'GIS.Selection.clear.EntityFromTheme',this.sessionID,0,themeIndex, selectionHandle, this.mapImage.width(),this.mapImage.height());
};

this.clearThemeSelections = function(themeIndex)
{
  this.setWaiting(true);
  this.selectionControl.selections[themeIndex].panel.innerHTML = '';
  makeASyncPostRequest(this.selectionControl,{request: 'clearTheme',themeIndex: themeIndex},XMLRPC_URL,'GIS.Selection.clear.AllFromTheme',this.sessionID,0,themeIndex);
};

this.clearAllSelections = function()
{
  //since only one feature on each layer can be selected at any given time, the selection handles do not need tracked. 
  if (this.selectionControl != null)
  {
    this.setWaiting(true);
    for (var themeIndex in this.selectionControl.selections){
      if(themeIndex=='toJSONString')continue;
      this.selectionControl.selections[themeIndex].panel.innerHTML = '';
      this.selectionControl.selections[themeIndex].panel.style.display = 'none';
    }
    var xmlrpcResponse = makeSyncPostRequest(XMLRPC_URL,'GIS.Selection.clear.AllThemes',this.sessionID,0);
    var mapData = getXMLRPCResponseObject(xmlrpcResponse);
    this.setWaiting(false);
  }
};

this.clearThemeSelectionsSync = function(themeIndex)
{
  this.setWaiting(true);
  var xmlrpcResponse = makeSyncPostRequest(XMLRPC_URL,'GIS.Selection.clear.AllFromTheme',this.sessionID,0,themeIndex);
  var mapData = getXMLRPCResponseObject(xmlrpcResponse);
  this.selectionControl.selections[themeIndex].panel.innerHTML = '';
  this.setWaiting(false);
};
this.clearSyncSelection = function(themeIndex, selectionHandle)
{
  this.setWaiting(true);
  var xmlrpcResponse = makeSyncPostRequest(XMLRPC_URL,'GIS.Selection.clear.EntityFromTheme',this.sessionID,0,this.themes[themeIndex][0][0], selectionHandle, this.mapImage.width(),this.mapImage.height());
  var mapData = getXMLRPCResponseObject(xmlrpcResponse);
  this.selectionControl.selections[themeIndex].panel.innerHTML = '';
  this.setWaiting(false);
};


this.clearThemeBuffer = function(themeName,bufferHandle)
{
  this.setWaiting(true);
  makeASyncPostRequest(this.bufferControl,Array('clearThemeBuffer',themeName,bufferHandle),XMLRPC_URL,'GIS.Buffer.clear.FromTheme',this.sessionID,0,themeName, bufferHandle, this.mapImage.width(),this.mapImage.height());
};

this.clearAllBuffers = function()
{
  if (this.bufferControl){
    if (this.bufferControl.hasBufferedResults()){
      this.setWaiting(true);
      var xmlrpcResponse = makeSyncPostRequest(XMLRPC_URL,'GIS.Buffer.clear.AllThemes',this.sessionID,0);
      var mapData = getXMLRPCResponseObject(xmlrpcResponse);
      if (this.bufferControl)
        this.bufferControl.clearAllBuffers();
      this.setWaiting(false);
    }
  }
};

this.clearAllGeocodePoints = function()
{
  if (this.geocodeControl!=null)
    this.geocodeControl.clearMarkup();
};

this.callback = function(serverReplyDoc, pendingOperation)
{
  var clearMeasurePoints = false;
  if (!validateXMLDoc(serverReplyDoc))
  {
    this.setWaiting(false);
    this.refresh();
    return null;
  }

  var clientReply = new XMLRPCResponse();
  //clientReply.setResponseByStr(serverReplyDoc.xml);
  clientReply.setResponseByDoc(serverReplyDoc);

  if(clientReply.isFault())
  {
    var data = null;
  }
  else
    var data = clientReply.getObject();

  if((data != null))
  {
    switch (pendingOperation)
    {
      case 'CoordConvSP2LatLon':  // ADDED-BY: JPW
        if (this.coordConvControl)
          this.coordConvControl.callback(data,pendingOperation);
        break;
      case 'Initialize_withScheme':
      case 'Initialize':
        _MAP_INITIALIZED = true;
        this.extent = data[0][1];
        if (this.firstLoad)
        {
          this.firstLoad = false;
          this.initialExtent = cloneObject(data[0][1]);
        }
        if (this.mapImage != null)
        {
          this.setWaiting(true);
          this.mapImage.imageNode.mapObject = this;
          this.mapImage.imageNode.onload=this.imageLoadCallback;
          this.setMapImage(data[0][0]);
        }
        if (this.vmapImage != null)
        {
          this.setWaiting(true);
          this.vmapImage.imageNode.mapObject = this;
          this.vmapImage.imageNode.onload=this.imageLoadCallback;
          this.vmapImage.imageNode.src = this.correctURL(data[1][0]);
        }
        this.vmapExtent = data[1][1];
        this.sessionID = data[data.length-1];
        document.setSessionID(this.sessionID);
        this.extent = data[0][1];
        this.loadThemes();
        this.loadLegend();
        this.getBookmarkList();
        if (this.labelControl != null)
          this.labelControl.initialize();
        if (this.selectionControl != null)
        {
          this.selectionControl.initialize();
        }
        if (this.zoomBar)
          this.zoomBar.initialize();
        runCMDs();
        break;
      case 'getThemes':
        for (i = 0; i < data.length; i++){
          try{
            this.config["themes"][data[i][0]]["visibility"] = data[i][1];
          }
          catch(e)
          {
            alert('Warning:\nUnable to set the visibility for map layer "'+data[i][0]+'"\nThere may be a mismatch between the client configuration and the map resource.');
          }
        }
        if (this.layerControl)
          this.layerControl.update();
        break;
      case 'setThemes':
        break;
      case 'setMapScheme':
        this.loadThemes();
        this.redraw();
        break;
      case 'Legend':
        if (this.legendImage != null)
          this.legendImage.src = this.correctURL(data);
        this.legendSync = true;
        break;
      case 'LoadLayers':
        break;
      case 'getBookmarkList':
        if (this.bookmarkControl)
          this.bookmarkControl.callback(data,'getBookmarkList');
        break;
      case 'addBookmark':
        if (this.bookmarkControl)
          this.bookmarkControl.callback(data,'addBookmark');
        this.getBookmarkList();
        break;
      case 'removeBookmark':
        if (this.bookmarkControl)
          this.bookmarkControl.callback(data,'removeBookmark');
        this.getBookmarkList();
        break;
      case 'gotoBookmark':
        if (this.mapImage != null)
        {
          this.setWaiting(true);
          this.setMapImage(data[0][1]);
        }
        if (this.vmapImage != null)
        {
          this.setWaiting(true);
          this.vmapImage.imageNode.src = this.correctURL(data[1][1]);
        }
        this.extent = data[0][2];
        this.loadThemes();
        if (this.legendVisible)
          this.loadLegend();
        clearMeasurePoints = true;
        break;
      case 'Select':
        break;
      case 'dEmail':
        break;
      case 'BufferXY':
        this.extent = data[0][0][2];
        if (this.mapImage != null){
          this.setWaiting(true);
          this.setMapImage(data[0][0][1]);
        }
        if (this.vmapImage != null){
          this.setWaiting(true);
          this.vmapImage.imageNode.src = this.correctURL(data[0][1][1]);
        }
        break;
      case 'zoomTo':
      case 'zoomToSelection':
        if (this.mapImage != null){
          this.setWaiting(true);
          this.setMapImage(data[0][0][1]);
        }
        if (this.vmapImage != null){
          this.setWaiting(true);
          this.vmapImage.imageNode.src = this.correctURL(data[0][1][1]);
        }
        if (this.legendVisible)
          this.loadLegend;
        this.extent = data[0][0][2];
        clearMeasurePoints = true;
        break;
      case 'getPrintImage':
        this.printMap(data);
        break;
      case 'getExportedMap':
        this.downloadExportedMap(data);
        break;
      default:
        this.extent = data[0][2];
        if (this.mapImage != null){
          this.setMapImage(data[0][1]);
          this.setWaiting(true);
        }
        if (this.vmapImage != null){
          this.setWaiting(true);
          this.vmapImage.imageNode.src = this.correctURL(data[1][1]);
        }
        if (!this.legendSync)
        {
          this.loadLegend();
        }
        clearMeasurePoints = true;
        break;
    }
  }
  else
  {
    switch(parseInt(clientReply.getFaultCode()))
    {
      case 1018: // No Buffer elements found
        break;
      default:
        alert('A Server Error occurred in a Map request.\n\nOperation:  '+pendingOperation+'\nFault Code: '+clientReply.getFaultCode()+'\nError Message:\n'+clientReply.getFaultString());
    }
  }
  if ((this.measureControl != null) && clearMeasurePoints)
  {
    this.measureControl.distanceReset();
  }
  if ((this.zoomBar!=null)&&(this.zoomBar.initialized))
    this.zoomBar.highlightNearestDiv();
  if (this.scalebar)
    this.scalebar.drawScalebar();
  this.setWaiting(false);
};


this.setMapImage = function(imgURL)
{
  //set image to correct path and load tiles (if used)
  this.mapImage.imageNode.src = this.correctURL(imgURL);
  if (this.config.seamlessPan)
  {
    var extentsMatch = true;
    for (var i=0;((i<this.extent.length)&&extentsMatch);i++)
      extentsMatch = (this.extent[i]==this.dragExtent[i]);
    if (!extentsMatch){  //only draw tiles if the extent changed.
      this.mapImage.clearDragTiles();
      this.dragExtent = cloneObject(this.extent);
      var $_this = this;
      var extentHeight = this.extent[1]-this.extent[0];
      var extentWidth = this.extent[3]-this.extent[2];
      var minLeft = this.extent[2]-extentWidth;
      var minBottom = this.extent[0]-extentHeight;
      var maxTop = this.extent[1]+extentHeight;
      var maxRight = this.extent[3]+extentWidth;
      var newExtents = [
        [this.extent[1],maxTop,minLeft,this.extent[2]],
        [this.extent[1],maxTop,this.extent[2],this.extent[3]],
        [this.extent[1],maxTop,this.extent[3],maxRight],
        [this.extent[0],this.extent[1],minLeft,this.extent[2]],
        [this.extent[0],this.extent[1],this.extent[2],this.extent[3]],
        [this.extent[0],this.extent[1],this.extent[3],maxRight],
        [minBottom,this.extent[0],minLeft,this.extent[2]],
        [minBottom,this.extent[0],this.extent[2],this.extent[3]],
        [minBottom,this.extent[0],this.extent[3],maxRight]
      ];
      var $_tileCounter = ++this.dragTileCounter;
      if (this.dragTileSessionId)
        this.mapTile_initializeCallback({data:[this.dragTileSessionId]},newExtents,$_tileCounter);
      else
        freeance_request(function(result){$_this.mapTile_initializeCallback(result,newExtents,$_tileCounter)},'GIS.Session.initialize','',Array(Array(this.config["resourceId"],1,1,1,false)));
    }
  }
};

this.mapTile_initializeCallback = function(result,newExtents,dragTileCounter)
{
  var $_this = this;
  if (this.dragTileCounter==dragTileCounter)
  {
    var $_sessionId = result['data'][result['data'].length-1];
    this.dragTileSessionId = $_sessionId;
    var themeArray = [];      //array of theme information to pass to server
    for (var i in this.config['themes']){
      if(i=='toJSONString')continue;
      themeArray.push([i,this.config['themes'][i]['visibility']]);
    }
    freeance_request(function(result){$_this.mapTile_setThemesCallback(result,newExtents,dragTileCounter,$_sessionId)},'GIS.Themes.setList', $_sessionId, 0, themeArray);
  }
  else
    dprintf('map tile request '+dragTileCounter+' cancelled');
};

this.mapTile_setThemesCallback = function(result,newExtents,dragTileCounter,sessionId)
{
  if (this.dragTileCounter==dragTileCounter)
  {
    var width = this.mapImage.width();
    var height = this.mapImage.height();
    for (var tileIndex=0;tileIndex<9;tileIndex++)
      if (tileIndex!=4) //skip center
        this.mapTile_makeImageRequest(newExtents[tileIndex],dragTileCounter,sessionId,tileIndex,width,height);
  }
  else
    dprintf('map tile request '+dragTileCounter+'['+tileIndex+'] cancelled');
};

this.mapTile_makeImageRequest = function(extent,dragTileCounter,sessionId,tileIndex,width,height)
{
  var $_this = this;
  freeance_request(function(result){$_this.mapTile_imageCallback(result,dragTileCounter,tileIndex);},'GIS.Zoom.to.extent',sessionId,0,width,height,extent);  
};

this.mapTile_imageCallback = function(result,dragTileCounter,tileIndex)
{
  if (this.dragTileCounter==dragTileCounter)
  {
    this.mapImage.dragTiles[tileIndex].setAttribute('src',this.correctURL(result['data'][0][1]));
  }
  else
    dprintf('map tile request '+dragTileCounter+'['+tileIndex+'] cancelled');

};

this.imageLoadCallback = function()
{
  this.mapObject.setWaiting(false);
};

this.selectionCallback = function (data)
{
  var returnValue;
  if (data)
  {
    this.mapImage.imageNode.src = this.correctURL(data[0][1]);
    if (this.vmapImage != null)
      this.vmapImage.imageNode.src = this.correctURL(data[1][1]);
    this.extent = data[0][2];
    returnValue = true;
  }
  else
    returnValue = null;
  this.setWaiting(false);
  if (data != null)
    if (this.onSelect)
      this.onSelect();
  return returnValue;
};

this.correctURL = function (newURL)
{
  var returnValue = newURL;
  if (returnValue.substr(0,1) == '/')  //trying to deal with relative paths
  {
    returnValue = 'http://'+this.config["imsHostname"]+newURL;
  }
  else
  {
    var url = /(\w+):\/\/([^\/]+)\/(\S*)/;
    //var url = /(\w+):\/\/([\w.]+)\/(\S*)/;
    var result = newURL.match(url);
    if (result == null)
      returnValue = newURL;  // setup doesn't have an ip or fully qualified name separated w/ .'s
    else
      returnValue = result[1]+'://'+this.config["imsHostname"]+'/'+result[3];
  }
  return returnValue;
};

this.exportMap = function()
{
  this.setWaiting(true);
  makeASyncPostRequest(this,'getExportedMap',XMLRPC_URL,'ArcIMS.Map.export',this.sessionID,0,this.mapImage.width(),this.mapImage.height());
};
this.downloadExportedMap = function(url)
{
  url = this.correctURL(url);
  downloadFile(url);
};

this.print = function()
{
  //arguments[0] = array of name,value pairs for placeholder variables
  //arguments[1] = callback fcn
  //arguments[2] = extent array
  var extent = [];
  var scale_config = [];
  if(arguments.length>2) extent = arguments[2];
  if(arguments.length>3) scale_config = arguments[3];
  var placeholderVariables = new Array();
  if (this.config.printConfig.defaultTemplate == -1)
  {
    alert('Freeance Internal Error:  Unable to Print.\nReason:  No print configurations have been defined.');
  }
  else
  {
    this.loadLegendSync();
    this.setWaiting(true);
    placeholderVariables[0] = Array('legendImage',this.legendImage.src);
    if (this.vmapImage!=null)
      placeholderVariables[1] = Array('vmapImage',this.vmapImage.imageNode.src);
    else
      placeholderVariables[1] = Array('vmapImage',GuiWidget.THEME_PATH+'/'+GuiWidget.THEME+'/images/blank.gif');
    if (arguments.length > 0)
    {
      for (var i=0;i<arguments[0].length;i++)  //process placeholders
      {
        placeholderVariables.push([arguments[0][i][0],arguments[0][i][1]]);
      }
    }
    //var xmlrpcResponse = makeASyncPostRequest(this,'printMap',XMLRPC_URL,'PDFPrint.Template.Map',this.config.printConfig.templates[this.config.printConfig.activeTemplate].templateName,placeholderVariables,document.sessionID,0,document.mapObject.mapImage.width(),document.mapObject.mapImage.height(),5);
    
    freeance_request(arguments[1],'PDFPrint.Template.Map',this.config.printConfig.templates[this.config.printConfig.activeTemplate].templateName,placeholderVariables,document.sessionID,0,document.mapObject.mapImage.width(),document.mapObject.mapImage.height(),5,extent,scale_config);
    
  }
};
};


