BufferControl = function (newId, newMapObject, newMapId, newResultTarget)
{
  if (arguments.length > 0)
    this.init(newId, newMapObject, newMapId, newResultTarget);
};

BufferControl.prototype = new Object();
BufferControl.constructor = BufferControl;
BufferControl.superclass = Object.prototype;
 
BufferControl.prototype.init = function (newId, newMapObject, newMapId, newResultTarget)
{
  this.id = newId;
  if (newMapId!=null)
  {
    this.mapObject = OBJECT_MANAGER.getControl(newMapId);
    this.mapId = newMapId;
  }
  else
  {
    this.mapObject = newMapObject;
    this.mapId = newMapObject.id;
  }
  
  this.mapObject.bufferControl = this;
  this.resultTarget = newResultTarget;
  this.activeTheme = '';
  this.activeSelection = '';
  this.buffers = new Object;

  this.bufferConfig = new Object;
  this.activeQuery = null;          //currently active buffer query (if any)
  this.bufferRadioButtonGroup = null;
  this.enabled = false;
  
  this.lastThemeBuffered = '';
};

BufferControl.prototype.initialize = function(bufferableThemes)
{
  //argument is an array of all bufferable theme ids in the map
  this.enabled = (bufferableThemes.length > 0);
  for (var i = 0; i < bufferableThemes.length; i++)
    this.buffers[bufferableThemes[i]] = null;
};

BufferControl.prototype.getSQLParams = function()
{
  return null;
  //check to see if a query panel is active.
  if (this.activeQuery != null)
  {
    var queryIndex = this.activeQuery.queryId;
    var dataPairs = this.activeQuery.getDataPairs();
    var sqlParams = new Array(this.activeQuery.queryConfig.request.pdqIdentifier,dataPairs);
  }
  else
    var sqlParams = null;
  return (sqlParams);
};

BufferControl.prototype.exportToCSV = function()
{
  return(this.exportData('csv'));
};
BufferControl.prototype.exportToXML = function()
{
  return(this.exportData('xml'));
};


BufferControl.prototype.exportData = function(exportType)
{
  if (this.buffers[this.lastThemeBuffered] == null)
    return;
  var bufferData = this.buffers[this.lastThemeBuffered][1];
  if (bufferData.length == 0)
    return;
  var config = this.mapObject.config.themes[this.lastThemeBuffered].bufferOptions;
  if (!config['export'])
    return;
  var fieldNames = new Array();
  var data = new Array();
  for(var lcv=0;lcv < bufferData.length;lcv++)
  {
    data[lcv] = new Array();
    colPos = 0;
    /* start with shape file fields */
    for(var fieldName in bufferData[lcv][0])
      if (fieldName != '_SHAPE_')
      {
        data[lcv][colPos++] = String.escapeHTML(bufferData[lcv][0][fieldName]);
        if (lcv==0)
          fieldNames.push(fieldName);
      }
    /* Now with the chained queries */
    for(var chainedQueryPos=1;chainedQueryPos < bufferData[lcv].length;chainedQueryPos++)
      for(var fieldName in bufferData[lcv][chainedQueryPos][0]) // just row 0 of the chained query
      {
        data[lcv][colPos++] = String.escapeHTML(bufferData[lcv][chainedQueryPos][0][fieldName]);
        if (lcv==0)
          fieldNames.push(fieldName);
      }
  }
  switch(exportType)
  {
    case 'csv':
      var request = 'Exporter.toCSV';
      var delim = config["export"].csv.delim; // delim
      var ifn = config["export"].csv.includeFieldNames; // includeFieldNames
      if (!ifn)
        fieldNames = new Array();
      this.mapObject.setWaiting(true);
      makeASyncPostRequest(this,Array(request),XMLRPC_URL,request,delim,data,true,fieldNames);
      break;
  };
};

BufferControl.prototype.callback = function(serverReplyDoc, pendingOperation)
{
  if (this.resultTarget.scrollHandler!=null)
    this.resultTarget.scrollHandler.cleanup();
  if (!validateXMLDoc(serverReplyDoc))
  {
    return null;
  }
  var clientReply = new XMLRPCResponse();
  clientReply.setResponseByDoc(serverReplyDoc);
  if(clientReply.isFault())
  {
    switch (parseInt(clientReply.getFaultCode()))
    {
      case 1018:  //no results found
        this.mapObject.callback(serverReplyDoc,pendingOperation[0]); //no elements found...
        this.mapObject.redraw();
        var templateName = this.mapObject.config.themes[pendingOperation[1]].bufferOptions.invalidTemplate;
        var templateData = new Array();
        templateData[0] = new Array();
        var source = document.getTemplate(templateName);
        this.buffers[pendingOperation[1]] = null;  //remove buffer handle...
        this.resultTarget.innerHTML = source.run(templateData);
        this.resultTarget.scrollTop = 0;
        if (this.onBufferReturn)
          this.onBufferReturn();
        break;
      default:
        alert(this.id+'.callback:  clientReply fault:\n\n'+clientReply.getFaultCode()+'\n'+clientReply.getFaultString());
        this.mapObject.callback(serverReplyDoc,pendingOperation[0]); //no elements found...
        break;
    }
  }
  else
    var data = clientReply.getObject();
  if (data != null)
  {
    switch (pendingOperation[0])
    {
      case 'BufferXY':
      case 'BufferOnSelection':
        this.lastThemeBuffered = pendingOperation[1];
        var templateName = this.mapObject.config.themes[pendingOperation[1]].bufferOptions.resultTemplate;
        var templateData = data[2];
        
        //modify template data to account for 1:n results in chained queries.
        var updatedTemplateData = new Array();
        var newResultIndex = 0;
        for (var originalResultIndex = 0; originalResultIndex < templateData.length; originalResultIndex++)
        {
          if (templateData[originalResultIndex][1])
          {
            if ((templateData[originalResultIndex][1].length==0)||(templateData[originalResultIndex][1].length==null))//no chained query results are present.
            {
              updatedTemplateData[newResultIndex] = new Array;
              updatedTemplateData[newResultIndex][0]=cloneObject(templateData[originalResultIndex][0]);
              newResultIndex++;
            }
            else //one or more chained query rows have been returned
            {
              for (var currentChainedQueryIndex = 0; currentChainedQueryIndex<templateData[originalResultIndex][1].length; currentChainedQueryIndex++)
              {
                updatedTemplateData[newResultIndex] = new Array;
                updatedTemplateData[newResultIndex][0]=cloneObject(templateData[originalResultIndex][0]);
                updatedTemplateData[newResultIndex][1]=new Array;
                updatedTemplateData[newResultIndex][1][0] = cloneObject(templateData[originalResultIndex][1][currentChainedQueryIndex]);
                newResultIndex++;
              }
            }
          }
          else
          {
            updatedTemplateData[newResultIndex] = new Array;
            updatedTemplateData[newResultIndex][0]=cloneObject(templateData[originalResultIndex][0]);
            newResultIndex++;
          }
        }
        this.buffers[pendingOperation[1]] = Array(data[1],updatedTemplateData);  //handle, queryData
        
        var templateSpecialRequests = Array();
        /* Check to see if this theme wants to export the buffer data to CSV */
        if (this.mapObject.config.themes[pendingOperation[1]].bufferOptions['export'].csv.enabled==true)
          templateSpecialRequests["includeExportBufferToCSV"] = true;
        var source = document.getTemplate(templateName,false,templateSpecialRequests);
        this.resultTarget.innerHTML = source.run(updatedTemplateData);
        this.resultTarget.scrollTop = 0;

        if (this.resultTarget.scrollHandler!=null)
          this.resultTarget.scrollHandler.cleanup();
        var tables = this.resultTarget.getElementsByTagName('TABLE');
        if ((tables.length>0)&&(!xOp7Up))
        {
          var header = new ScrollableTable(tables[0],this.resultTarget,-2);
        }
        
        /** TODO:  Add code to fix urls for images and hyperlinks.  **/
        this.mapObject.callback(serverReplyDoc,'BufferXY');
        if (this.onBufferReturn)
          this.onBufferReturn();
        break;
      case 'clearThemeBuffer':
        this.buffers[pendingOperation[1]] = null;
        this.mapObject.callback(serverReplyDoc,'clearThemeBuffer');
        if (this.onBufferClear)
          this.onBufferClear();
        break;
      case 'Exporter.toCSV':
      case 'Exporter.toXML':
        this.mapObject.setWaiting(false);
        var url = data;
        downloadFile(url);
        break;
    }
  }
};

