QueryControl = function (newId, newQueryGroupId, newResultTarget, newResultTargetId, newLoadImage)
{
  OBJECT_MANAGER.addControl(this,'queryControl', newId);
  this.id = newId;
  this.queryGroupId = newQueryGroupId;       //Object with properties indicating the names of queries
  this.queryPanel = null;
  this.savedQueryIndexPanel = null;
  this.queryList = null;
  this.resultTarget = newResultTarget;
  this.resultTargetId = newResultTargetId;
  this.currentQueryPage = 0;
  this.currentQueryId = null;
  this.currentQueryValuePairs = null;
  this.loadImage = newLoadImage;
  return;
};

QueryControl.prototype.initialize = function()
{
  this.map = document.getGuiControl("map0");
  this.queryGroup = document.getGuiValue(this.queryGroupId);
  this.queryList=document.queryConfig.queries;
  /*
  this.queryList = new Object;
  for (var i =0; i<this.queryGroup.length; i++)
  {
    this.queryList[this.queryGroup[i]] = document.getGuiValue(this.queryGroup[i]); 
  }
  */
  if (this.resultTargetId!=null)
  {
    this.resultTarget = document.getWidgetById(this.resultTargetId);
  }
  else
  {
    this.resultTargetId = this.resultTarget.id;
  }
  /* NOTE: redundant? */
  /*
  for (var i in this.queryList)
  {
    this.queryList[i] = document.getGuiValue(i);
  }
  */
  if (this.queryPanel != null)
  {
    this.queryPanel.initialize();
  }
  this.savedQueryIndexPanel = document.getWidgetById("savedQueryIndexPanel");
  if (this.savedQueryIndexPanel != null)
  {
    this.savedQueryIndexPanel.queryControl = this;
    this.savedQueryIndexPanel.initialize();
  }
};

QueryControl.prototype.runQuery = function(queryId, newValuePairs, newStartPage, firstRun)
{
  this.currentQueryId = queryId;
  this.currentQuery = this.queryList[queryId];
  this.currentSourceValuePairs = newValuePairs;
  templatehow = 'elem';

  this.currentQueryPage = newStartPage;
  this.currentQueryValuePairs = new Array();
  var valueIndex = 0;
  for (currentValue in newValuePairs)
  {
    this.currentQueryValuePairs[valueIndex] = new Array(this.currentQuery.fieldList[currentValue].fieldName,newValuePairs[currentValue]);
    valueIndex++;
  }
  var data = makeASyncPostRequest(
             this,
             this.currentQuery.request.requestMethod,
             XMLRPC_URL,
             this.currentQuery.request.requestMethod,
             this.currentQuery.request.pdqIdentifier,
             this.currentQuery.templates.pageRows,
             this.currentQueryPage,
             this.currentQueryValuePairs);
             
  if (this.loadImage != null)
    document.getWidgetById(this.loadImage).show();
};

QueryControl.prototype.saveQuery = function(saveName, queryId, newValuePairs)
{
  var valueIndex = 0;
  var currentQuery = this.queryList[queryId];
  var currentQueryValuePairs = Array();
  for (currentValue in newValuePairs)
  {
    currentQueryValuePairs[valueIndex] = new Array(currentQuery.fieldList[currentValue].fieldName,newValuePairs[currentValue]);
    valueIndex++;
  }
  var request = 'SQL.storedDefinedQuery.save';
  makeASyncPostRequest(
        this,
        request,
        XMLRPC_URL,
        request,
        document.getSessionID(),
        saveName,
        queryId,
        currentQueryValuePairs
        );

  if (this.loadImage != null)
    document.getWidgetById(this.loadImage).show();
};

QueryControl.prototype.exportQuery = function(exportType,queryId, newValuePairs)
{
  var queryConfig = document.getGuiValueById(queryId);
  if (!queryConfig)
    return;
  var currentQueryId = queryId;
  var currentQuery = this.queryList[queryId];
  var currentSourceValuePairs = newValuePairs;

  var currentQueryPage = 1;
  var currentQueryValuePairs = new Array();
  var valueIndex = 0;
  for (currentValue in newValuePairs)
  {
    newValuePairs[currentValue] = escapeHTML(newValuePairs[currentValue]);
    
    currentQueryValuePairs[valueIndex] = new Array(currentQuery.fieldList[currentValue].fieldName,newValuePairs[currentValue]);
    valueIndex++;
  }
  var request = 'SQL.export.execute';
  var exportFormat = new Array();
  exportFormat[0] = exportType;
  exportFormat[1] = true;  // UseZip
  var queryType = 'definedQuery';
  switch(exportType)
  {
    case 'csv':
        exportFormat[2] = queryConfig["export"].csv.delim; // delim
        exportFormat[3] = queryConfig["export"].csv.includeFieldNames; // includeFieldNames
        break;
  }
  makeASyncPostRequest(
             this,
             request,
             XMLRPC_URL,
             request,
             exportFormat,
             queryType,
             currentQuery.request.pdqIdentifier,
             currentQueryValuePairs
             );
             
  if (this.loadImage != null)
    document.getWidgetById(this.loadImage).show();
};

QueryControl.prototype.loadNextPage = function()
{
  this.runQuery(this.currentQueryId,this.currentSourceValuePairs,this.currentQueryPage+1, false);
};

QueryControl.prototype.loadPreviousPage = function()
{
  this.runQuery(this.currentQueryId,this.currentSourceValuePairs,this.currentQueryPage-1, false);
};

QueryControl.prototype.zoomToResults = function(themeId,themeTargetField,queryFieldName,fieldQuotes,stylesheet)  // JPW
{
  var whereClauseArr = Array();
  var whereClauseStr = '';
  var realData = this.currentResultData[3];
  
  if (fieldQuotes)
    var quotes = "'";
  else
    var quotes = "";

  var hasLabelControl = false;
  try { var labelTest = (typeof this.map.labelControl.addMarkupToIndex); hasLabelControl=true; }
  catch(e) { }
  if ((realData.length == 0) || (hasLabelControl == false)) // haha very funny
  {
    if (this.loadImage != null)
      document.getWidgetById(this.loadImage).show();
    if (realData.length == 0)
      alert('No data to zoom to.');
    else
      alert('This requires the markup extension to be enabled in this application.  Please notify your system administrator.');
    if (this.loadImage != null)
      document.getWidgetById(this.loadImage).hide(); // see, its FAST!
    return;
  }
  
  for(var lcv=0;lcv < realData.length;lcv++)
    whereClauseArr[whereClauseArr.length] = "("+themeTargetField+"="+quotes+realData[lcv][queryFieldName]+quotes+")";
  whereClauseStr = whereClauseArr.join(" or ");

  var request = 'GIS.Zoom.to.queryResults';
  var requestInfo = new Object();
  requestInfo.themeID = themeId;
  requestInfo.request = request;
  var wantReturnFields = false;
  var returnFields = '';
  var zoomFactor = 1.0;
  var maxCount = 0;  // all

  //makeASyncPostRequest(this,requestInfo,XMLRPC_URL,request,this.sessionID,0,this.mapImage.imageNode.cbe.width(),this.mapImage.imageNode.cbe.height(),Array(pointArray),false,themeName,stylesheet);
  makeASyncPostRequest(this,requestInfo,XMLRPC_URL,request,this.map.sessionID,0,this.map.mapImage.imageNode.cbe.width(),this.map.mapImage.imageNode.cbe.height(),themeId,returnFields,whereClauseStr,zoomFactor,maxCount,wantReturnFields,stylesheet);
  if (this.loadImage != null)
    document.getWidgetById(this.loadImage).show();
};

QueryControl.prototype.addZoomToMarkupToIndex = function(themeID,data)  // JPW
{
  var markupObj = new Object;
  markupObj.handle = data.handle;
  markupObj.themeName = themeID;
  markupObj.labelName = stripQuotes(escapeHTML('Results: '+this.map.config.themes[themeID].themeName));
  markupObj.extent = data.zoomExtent;
  markupObj.type = 'zoomToResults'; // i guess...
  markupObj.style = '0';

  this.map.labelControl.addMarkupToIndex(themeID,markupObj);
};

QueryControl.prototype.callback = function(serverReplyDoc, requestType)
{
  if (this.loadImage != null)
  {
    document.getWidgetById(this.loadImage).hide();
  }
  /* begin error checks */
  if (serverReplyDoc == null)
  {
    return (null);
  }
  if (serverReplyDoc.xml == '') 
  {
    return (null);
  }
  if (serverReplyDoc.documentElement.nodeName == 'parsererror')
  {
    return (null);
  }
  var clientReply = new XMLRPCResponse();
  //clientReply.setResponseByStr(serverReplyDoc.xml);
  clientReply.setResponseByDoc(serverReplyDoc);
  if (clientReply.isFault())
  {
    var sqlData = null;
    //We're expecting this to happen, suppress certain fault messages
    if ((clientReply.getFaultCode()!=2003)&&(clientReply.getFaultCode()!=2004)&&(clientReply.getFaultCode()!=2005))
    {
      alert('clientReply.isFault()');
      alert('clientReply fault:\n\n'+clientReply.getFaultCode()+'\n'+clientReply.getFaultString());
    }
    if (clientReply.getFaultCode() == 2003)  //Requested page number less than 1
      this.currentQueryPage++;
    if (clientReply.getFaultCode() == 2004)  //requested page number greater than last page
      this.currentQueryPage--;
    if (clientReply.getFaultCode() == 2005)  //no results found.
    {
      templateData = new Array();
      templateData[0] = new Array();
      var source = document.getTemplate(this.currentQuery.templates.invalidTemplate);
      this.resultTarget.element.innerHTML = source.run(templateData);
    }
  }
  else
  {
    if (typeof requestType == "object")
    {
      var requestInfo = requestType;
      requestType = requestType.request;
    }
    switch (requestType)
    {
      case 'GIS.Zoom.to.queryResults':
        var data = clientReply.getObject();
        if (this.map.measureControl != null)
           this.map.measureControl.distanceReset();
        this.map.extent = data.zoomExtent;
        this.map.mapImage.imageNode.src = this.map.correctURL(data.mapImages[0][1]);
        if (this.map.vmapPresent)
          this.map.vmapImage.imageNode.src = this.map.correctURL(data.mapImages[1][1]);
        if (this.map.legendVisible)
          this.map.loadLegend();
        this.addZoomToMarkupToIndex(requestInfo.themeID,data);
        break;
      case 'SQL.storedDefinedQuery.save':
        if (this.savedQueryIndexPanel)
          this.savedQueryIndexPanel.getList();
        break;
      case 'SQL.export.execute':
        var url = clientReply.getObject();
        downloadFile(url);
        break;
      default:
        var sqlData = clientReply.getObject();
        if ((sqlData == null) || (sqlData != false))
        {
          this.currentResultData = cloneObject(sqlData);
          var source = document.getTemplate(this.currentQuery.templates.validTemplate);
          try{ this.resultTarget.element.innerHTML = source.run(sqlData); }
          catch(e)
          {
            this.resultTarget.element.innerHTML = '';
          }
          this.resultTarget.query = this;
        }
    }
  }
};


