/**************************************************
FreeanceXMLParser.js
  XML parser for the freeance configuration libraries
  extends the base xml parser, adding appropriate
  functions for dealing with the possible freeance
  extensions and core modules.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Dependancies:
  XMLParser-base.js
  Util.js
  X.js

**************************************************/

FreeanceXMLParser = function(newID)
{
  if (arguments.length > 0)
    this.init(newID);
};
FreeanceXMLParser.prototype = new XMLParser();
FreeanceXMLParser.prototype.constructor = FreeanceXMLParser;
FreeanceXMLParser.superclass = XMLParser.prototype;

FreeanceXMLParser.prototype.init = function(newID)
{
  FreeanceXMLParser.superclass.init.call(this, newID);  //call parent's init function
};

FreeanceXMLParser.prototype.getObject = function(objectName)
{
  //this overrides the default parser's getObject function
  if (this.xmlDoc == null)
    return null;
  if (arguments.length > 0)
  {
    switch (arguments[0])
    {
      case 'applicationConfig':
        return (this.parseApplicationConfig(this.xmlDoc.getElementsByTagName("applicationConfig").item(0)));
        break;
      case 'mapConfig':
        return (this.parseMapConfig(this.xmlDoc.getElementsByTagName("map").item(0)));
        break;
      case 'templateConfig':
        return (this.parseTemplateConfig(this.xmlDoc.getElementsByTagName("templates").item(0)));
        break;
      case 'extensionConfig':
        return(this.parseExtensionConfig(this.xmlDoc.getElementsByTagName('extensionConfig').item(0)));
        break;
      case 'queryConfig':
        return (this.parseQueryConfig(this.xmlDoc.getElementsByTagName("queryConfig").item(0)));
        break;
      case 'measureConfig':
        return (this.parseMeasureConfig(this.xmlDoc.getElementsByTagName(arguments[0]).item(0)));
        break;
      case 'emailConfig':
        return (this.parseEMailConfig(this.xmlDoc.getElementsByTagName(arguments[0]).item(0)));
        break;
      default:
        return (this.getObjectRecurse(this.xmlDoc.getElementsByTagName("value").item(0)));
    }
  }
  else
    return (this.getObjectRecurse(this.xmlDoc.getElementsByTagName("value").item(0)));
    //here we assume that they incorrectly declared the parser...
};

FreeanceXMLParser.prototype.getObjectRecurse = function()
{
  //first argument is the starting node. 
  //additional parameters may be required for certain node types; these vary
  
  
  //dprintf('FreeanceXMLParser.getObjectRecurse;executing native code for '+arguments[0].nodeName,false);
  var theNode = arguments[0];
  var returnValue = null;
  var i = 0;
  if (this.xmlDoc == null) 
    return null;
  else      
    switch (theNode.nodeName)
    {
      case 'left':
      case 'top':
      case 'zpos':
      case 'width':
      case 'height':
      case 'visibility':
      case 'style':
      case 'label':
      case 'imageName':
      case 'partOfExtension':
      case 'tooltip':
      case 'onTooltip':
      case 'offTooltip':
      case 'buttonState':
      case 'useRollover':
      case 'enableDrag':
      case 'groupName':
      case 'imageSource':
      case 'scaleImage':
      case 'orientation':
      case 'caption':
      case 'setActive':
      case 'useScroll':
      case 'pageType':
      case 'usePageControl':
      case 'color':
      case 'font':
      case 'fontSize': 
      case 'valueFontSize':
      case 'cellSpacing':
        if (this.__helper__getNextElementNamedChildNode(theNode,0,"value")!= -1)
          return (this.getObjectRecurse(theNode.childNodes[this.__helper__getNextElementNamedChildNode(theNode,0,"value")]));
        else
        {
          return null;
        }
        break;
      default:
      {
        dprintf('FreeanceXMLParser.getObjectRecurse; unknown node type: '+theNode.nodeName,false);
        //dprintf('FreeanceXMLParser.getObjectRecurse; executing parent class code for '+arguments[0].nodeName,false);
        return FreeanceXMLParser.superclass.getObjectRecurse.call(this, arguments[0]);
        break;
      }
    }
  return returnValue;
};

FreeanceXMLParser.prototype.parseApplicationConfig = function(appNode)
{
  var appConfig = new Array;
  appConfig.id = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"applicationId")]);
  appConfig.organization = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"organization")]);
  appConfig.title = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"title")]);
  appConfig.clientType = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"clientType")]);
  if (this.__helper__getNextElementNamedChildNode(appNode,0,"stylesheet") != -1)
    appConfig.stylesheet = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"stylesheet")]);
  else
    appConfig.stylesheet = 'default';
  appConfig.administrator = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"administrator")]);
  appConfig.adminEmail = this.decodeSTRING(appNode.childNodes[this.__helper__getNextElementNamedChildNode(appNode,0,"adminEmail")]);
  var mapUnitIndex = this.__helper__getNextElementNamedChildNode(appNode,0,"mapUnits");
  appConfig.mapUnits = ((mapUnitIndex > -1)?(this.decodeSTRING(appNode.childNodes[mapUnitIndex])):('FT'));
  var vmapHeightIndex = this.__helper__getNextElementNamedChildNode(appNode,0,"vmapHeight");
  appConfig.vmapHeight = ((vmapHeightIndex > -1)?(this.decodeINT(appNode.childNodes[vmapHeightIndex])):(100));
  var customLayoutIndex = this.__helper__getNextElementNamedChildNode(appNode,0,"customOptions");
  appConfig.customOptions = ((customLayoutIndex!=-1)?(this.parseApplicationCustomOptions(appNode.childNodes[customLayoutIndex])):(null));
  OBJECT_MANAGER.setGuiValue("ApplicationConfig", appConfig);
  return appConfig;
};

FreeanceXMLParser.prototype.parseApplicationCustomOptions = function (customNode)
{
  //get values for page customization....
  var customConfig = new Object;
  var nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"pageHeaderHeight");
  customConfig.pageHeaderHeight = (nodeIndex==-1)?(70):(this.decodeINT(customNode.childNodes[nodeIndex]));
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"leftPanelDisplay");
  customConfig.leftPanelDisplay = (nodeIndex==-1)?(true):(this.decodeINT(customNode.childNodes[nodeIndex])==1);
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"legendDisplay");
  customConfig.legendDisplay = (nodeIndex==-1)?(true):(this.decodeINT(customNode.childNodes[nodeIndex])==1);
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"legendEnable");
  customConfig.legendEnable = (nodeIndex==-1)?(true):(this.decodeINT(customNode.childNodes[nodeIndex])==1);
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"layerDisplay");
  customConfig.layerDisplay = (nodeIndex==-1)?(false):(this.decodeINT(customNode.childNodes[nodeIndex])==1);
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"layerEnable");
  customConfig.layerEnable = (nodeIndex==-1)?(true):(this.decodeINT(customNode.childNodes[nodeIndex])==1);
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"resultPanelHeight");
  customConfig.resultPanelHeight = (nodeIndex==-1)?(50):(this.decodeINT(customNode.childNodes[nodeIndex]));
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"customPanelPosition");
  customConfig.customPanelPosition = (nodeIndex==-1)?(0):(this.decodeINT(customNode.childNodes[nodeIndex]));
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"customPanelTitle");
  customConfig.customPanelTitle = (nodeIndex==-1)?('Site Instructions'):(this.decodeSTRING(customNode.childNodes[nodeIndex]));
  nodeIndex = this.__helper__getNextElementNamedChildNode(customNode,0,"customLegendURL");
  customConfig.customLegendURL = (nodeIndex==-1)?(''):(this.decodeSTRING(customNode.childNodes[nodeIndex]));
  return customConfig;
};

FreeanceXMLParser.prototype.parseMapConfig = function(mapNode)
{
  var mapConfig = new Object();
  mapConfig['id'] = mapNode.getAttribute("id");
  mapConfig["resourceId"] = this.decodeSTRING(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"resourceId")]);
  mapConfig["imsHostname"] = this.decodeSTRING(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"imsHostname")]);
  mapConfig["previousStates"] = this.decodeINT(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"previousStates")]);
  if (this.__helper__getNextElementNamedChildNode(mapNode,0,"vicinityMap")!=-1)
    mapConfig['vmap'] = this.parseVMapConfig(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"vicinityMap")]);
  if (this.__helper__getNextElementNamedChildNode(mapNode,0,"themeDefinitions")!=-1)
    mapConfig['themes'] = this.parseThemeDefinitions(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"themeDefinitions")]);
  mapConfig["activeTheme"] = this.decodeSTRING(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"activeTheme")]);
  mapConfig['themeGroups'] = this.parseThemeGroups(mapNode);
  
  var legendAttributeIndex = this.__helper__getNextElementNamedChildNode(mapNode,0,"legendAttributes");
  var legendIndex = this.__helper__getNextElementNamedChildNode(mapNode,0,"legend");
  mapConfig['legendAttributes'] = this.parseLegendAttributes(mapNode.childNodes[(legendAttributeIndex>-1)?legendAttributeIndex:legendIndex]);

  //Configure the printing system
  var printNodes = mapNode.getElementsByTagName("pdfPrintConfig");
  mapConfig.printConfig = (printNodes.length)?this.parsePdfPrintConfig(printNodes[0]):{templates: new Array,defaultTemplate: -1};
  
  
  //Configure the CSV export system
  if (this.__helper__getNextElementNamedChildNode(mapNode,0,"exportConfig")!=-1)
    mapConfig['exportConfig'] = this.parseMapExportConfig(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"exportConfig")]);
  if (this.__helper__getNextElementNamedChildNode(mapNode,0,"scalebar")!=-1)
  {
    var scalebarConfigNode = mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"scalebar")];
    mapConfig['scalebarConfig'] = this.parseScalebarConfig(scalebarConfigNode);
  }
  else
  {
    mapConfig['scalebarConfig'] = null;
  }
  //Capture any geocode extension data
  if (this.__helper__getNextElementNamedChildNode(mapNode,0,"geocodeConfig")!=-1)
  {
    try{
      mapConfig['geocodeConfig'] = this.parseGeocodeConfig(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"geocodeConfig")]);
    }
    catch(e)
    {
      alert('Initialization Error:\nGeocode configuration is present but the extension could not be loaded.');
    }
  }

  //Capture any directmapping extension data
  try
  {
    if (this.__helper__getNextElementNamedChildNode(mapNode,0,"directMappingConfig")!=-1)
      mapConfig['directMappingConfig'] = this.parseDirectMappingConfig(mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"directMappingConfig")]);
  }
  catch(e)
  {
    //A direct mapping configuration is present but the direct mapping extension has not been loaded.
    //this can happen in some circumstances so let the error go, it won't hurt anything.
    dprintf('Warning: Freeance Direct is configured but not installed.');
  }
  
  //parse map schemes
  if (this.__helper__getNextElementNamedChildNode(mapNode,0,"mapSchemeDefinitions")!=-1)
  {
    var mapSchemeConfigNode = mapNode.childNodes[this.__helper__getNextElementNamedChildNode(mapNode,0,"mapSchemeDefinitions")];
    mapConfig['mapSchemeConfig'] = this.parseMapSchemeConfig(mapSchemeConfigNode);
  }
  else
  {
    mapConfig['mapSchemeConfig'] = null;
  }
  var seamlessPanIdx=this.__helper__getNextElementNamedChildNode(mapNode,0,"seamlessPan");
  var seamlessPan = false;
  if(seamlessPanIdx!=-1)
    seamlessPan=(mapNode.childNodes[seamlessPanIdx].getAttribute('enabled')=='true');
  mapConfig.seamlessPan = seamlessPan;
  
  
  OBJECT_MANAGER.setGuiValue(mapConfig['id'], mapConfig);
  return mapConfig;
};

FreeanceXMLParser.prototype.parseMapSchemeConfig = function (mapSchemeConfigNode)
{
  var mapSchemeConfig = {};
  var mapSchemeTags = this.getRemainingNamedChildNodes(mapSchemeConfigNode,0,"mapScheme");
  var defaultMapSchemeNode = mapSchemeConfigNode.childNodes[this.getNextNamedChildNodeIndex(mapSchemeConfigNode,0,"defaultScheme")];
  mapSchemeConfig.mapSchemes = [];
  mapSchemeConfig.defaultMapScheme = this.decodeINT(defaultMapSchemeNode);
  if (mapSchemeTags.length > 0)
  {
    for (var i = 0; i<mapSchemeTags.length; i++)
    {
      var currentMapSchemeId = parseInt(mapSchemeTags[i].getAttribute('id'));
      mapSchemeConfig.mapSchemes[currentMapSchemeId] = {
        name: this.decodeSTRING(mapSchemeTags[i].childNodes[this.getNextNamedChildNodeIndex(mapSchemeTags[i],0,"schemeName")]),
        themes: new Object
      }
      var themeTags = this.getRemainingNamedChildNodes(mapSchemeTags[i],0,"theme");
      for (var currentTheme = 0; currentTheme < themeTags.length; currentTheme++)
      {
        var themeId = themeTags[currentTheme].getAttribute('id');
        mapSchemeConfig["mapSchemes"][currentMapSchemeId]["themes"][themeId] = {
          id: themeId,
          display: parseInt(themeTags[currentTheme].getAttribute('display')),
          legend: themeTags[currentTheme].getAttribute('legend')
        }
      }
    }
  }
  else
    mapSchemeConfig = null;
  return mapSchemeConfig;
};


FreeanceXMLParser.prototype.parseThemeGroups = function(mapNode)
{
  var config = [];
  //determine type of layer control to use
  var themeGroupDefinitionNodes = mapNode.getElementsByTagName("themeGroupDefinitions");
  var layerControlNodes = mapNode.getElementsByTagName("layerControl");
  if (themeGroupDefinitionNodes.length>0) //pre-4.2 format, map to new structure
  {
    config = this.parseOldThemeGroups(themeGroupDefinitionNodes[0]);
  }
  else
  {
    //top-level is an implicit group
    for (var i=0;i<layerControlNodes[0].childNodes.length;i++)
      if (layerControlNodes[0].childNodes[i].nodeName=='groupItem')
        config.push(this.parseThemeGroupItem(layerControlNodes[0].childNodes[i]));
  }
  return config;
};


FreeanceXMLParser.prototype.parseThemeGroupItem = function(groupItemNode){
  var config = {
    type:groupItemNode.getAttribute('type'),
    name:groupItemNode.getAttribute('name'),
    layerid:groupItemNode.getAttribute('layerid'),
    toggle:groupItemNode.getAttribute('toggle')=='on',
    children:[]
  };
  if(config.type=='group')
    for(var i=0;i<groupItemNode.childNodes.length;i++)
      if(groupItemNode.childNodes[i].nodeName=='groupItem')
        config.children.push(this.parseThemeGroupItem(groupItemNode.childNodes[i]));
  return config;
};


FreeanceXMLParser.prototype.parseOldThemeGroups = function(parentNode)
{
  dprintf('loading pre-4.2 style theme groups');
  var config = [];
  var childconfig = [];
  var groupMemberNodes = null;
  var groupNodes = parentNode.getElementsByTagName('themeGroup');
  if (groupNodes.length==1) //treat as single group with label
  {
    config.push({
      type: 'label',
      name: this.decodeSTRING(groupNodes[0].getElementsByTagName('themeGroupName')[0]),
      toggle: false
    });
    groupMemberNodes = groupNodes[0].getElementsByTagName('themeGroupMember');
    for (var i=0;i<groupMemberNodes.length;i++){
      config.push({
        type:'layer',
        layerid:this.decodeSTRING(groupMemberNodes[i]),
        toggle:true
      });
    }
  }
  else
  {
    for (var i=0;i<groupNodes.length;i++){
      childconfig = [];
      groupMemberNodes = groupNodes[i].getElementsByTagName('themeGroupMember');
      for (var j=0;j<groupMemberNodes.length;j++){
        childconfig.push({
          type:'layer',
          layerid:this.decodeSTRING(groupMemberNodes[j]),
          name:'',
          toggle:true,
          children:[]
        });
      }
      config.push({
        type: 'group',
        name: this.decodeSTRING(groupNodes[i].getElementsByTagName('themeGroupName')[0]),
        layerid:'',
        toggle: false,
        children: childconfig
      });
    }
  }
  return config;  
};


FreeanceXMLParser.prototype.parseScalebarConfig = function(newNode)
{
  var scalebarConfig = new Array();
  for (var levelIndex = this.__helper__getNextElementNamedChildNode(newNode,0,"level");levelIndex!=-1;levelIndex=this.__helper__getNextElementNamedChildNode(newNode,levelIndex+1,"level"))
  {
    var levelNode = newNode.childNodes[levelIndex];
    scalebarConfig.push([
      parseInt(levelNode.getAttribute('topUnit')),
      parseFloat(levelNode.getAttribute('topLength')),
      parseInt(levelNode.getAttribute('bottomUnit')),
      parseFloat(levelNode.getAttribute('bottomLength')),
      parseFloat(levelNode.getAttribute('mapWidth'))
    ]);
  }
  return scalebarConfig;
};

FreeanceXMLParser.prototype.parseVMapConfig = function(vmapNode)
{
  return {
    id: vmapNode.getAttribute("id"),
    resourceId: this.decodeSTRING(vmapNode.childNodes[this.__helper__getNextElementNamedChildNode(vmapNode,0,"resourceId")]),
    slaveType: this.decodeSTRING(vmapNode.childNodes[this.__helper__getNextElementNamedChildNode(vmapNode,0,"slaveType")]),
    boundBoxPercentMin: this.decodeDOUBLE(vmapNode.childNodes[this.__helper__getNextElementNamedChildNode(vmapNode,0,"boundBoxPercentMin")]),
    styleSheet: this.decodeSTRING(vmapNode.childNodes[this.__helper__getNextElementNamedChildNode(vmapNode,0,"styleSheet")])
  };
};

FreeanceXMLParser.prototype.parseTemplateConfig = function(templateRootNode)
{
  var templates = new Object();
  var htmlString = '';
  for (var templateIndex = this.__helper__getNextElementNamedChildNode(templateRootNode,0,"template");templateIndex!=-1;templateIndex=this.__helper__getNextElementNamedChildNode(templateRootNode,templateIndex+1,"template"))
  {
    for (var lcv=0;lcv < templateRootNode.childNodes[templateIndex].childNodes.length;lcv++)
    {
      if (templateRootNode.childNodes[templateIndex].childNodes.item(lcv).nodeType == 4)
        htmlString = templateRootNode.childNodes[templateIndex].childNodes.item(lcv).nodeValue;
    }
    templates[templateRootNode.childNodes[templateIndex].getAttribute("id")] = htmlString;
  }
  OBJECT_MANAGER.setGuiValue('templates', templates);
  return templates;
};

FreeanceXMLParser.prototype.parseExtensionConfig = function(extensionConfigNode)
{
  var extensions = new Object();
  var extensionNodes = extensionConfigNode.getElementsByTagName('extension');
  for(var lcv=0; lcv < extensionNodes.length;lcv++)
  {
    var extension = extensionNodes[lcv];
    var name = extension.getAttribute('name');
    var enabled = extension.getAttribute('enabled');
    extensions[name] = new Object();
    extensions[name].enabled = (enabled == 'true'); //?true:false;
    if (extensions[name].enabled)
    {
      var forceLoad = extension.getAttribute('forceLoad');
      extensions[name].forceLoad = ((typeof(forceLoad)=='string')?((forceLoad == 'true')?true:false):(false));
    }
    extensions[name].loaded = false;
  }
  OBJECT_MANAGER.setGuiValue('extensions',extensions);
  return(extensions);
};

FreeanceXMLParser.prototype.parseThemeDefinitions = function (newNode)
{
  var themeDefinitions = new Array();
  for (themeIndex=this.__helper__getNextElementNamedChildNode(newNode,0,"theme");themeIndex!=-1;themeIndex=this.__helper__getNextElementNamedChildNode(newNode,themeIndex+1,"theme"))
  {
    themeDefinitions[newNode.childNodes[themeIndex].getAttribute("id")] = this.parseTheme(newNode.childNodes[themeIndex]);
  }
  return themeDefinitions;
};

FreeanceXMLParser.prototype.parseTheme = function (themeNode)
{
  var themeAttributes = new Array();
  themeAttributes["id"] = themeNode.getAttribute("id");
  themeAttributes["hideTheme"] = themeNode.getAttribute("hideTheme");
  if (themeAttributes["hideTheme"] == null)
    themeAttributes["hideTheme"] = false;
  else
    themeAttributes["hideTheme"] = themeAttributes["hideTheme"] == 'true';
  
  themeAttributes["themeName"] = this.decodeSTRING(themeNode.childNodes[this.__helper__getNextElementNamedChildNode(themeNode,0,"themeName")]);
  if (this.__helper__getNextElementNamedChildNode(themeNode,0,"selectOptions")!=-1)
    themeAttributes["selectOptions"] = this.parseThemeSelectOptions(themeNode.childNodes[this.__helper__getNextElementNamedChildNode(themeNode,0,"selectOptions")]);
  else
    themeAttributes["selectOptions"] = null;
  if (this.__helper__getNextElementNamedChildNode(themeNode,0,"bufferOptions")!=-1)
    themeAttributes["bufferOptions"] = this.parseThemeBufferOptions(themeNode.childNodes[this.__helper__getNextElementNamedChildNode(themeNode,0,"bufferOptions")]);
  else
    themeAttributes["bufferOptions"] = null;
  themeAttributes["visibility"] = false;
  return themeAttributes;
};

FreeanceXMLParser.prototype.parseThemeSelectOptions = function(newNode)
{
  var selectAttributes = {
    styleSheet: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"styleSheet")]),
    fieldList: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"fieldList")]),
    limit: this.decodeINT(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"limit")]),
    tolerance: this.decodeDOUBLE(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"tolerance")]),
    idField: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"idField")]),
    keyField: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"keyField")])
  };
  var keyFieldTypeIndex = this.__helper__getNextElementNamedChildNode(newNode,0,"keyFieldType");
  selectAttributes["keyFieldType"] = ((keyFieldTypeIndex!=-1)?(this.decodeINT(newNode.childNodes[keyFieldTypeIndex])):(12));
  var zoomExtentRatioIndex = this.__helper__getNextElementNamedChildNode(newNode,0,"zoomExtentRatio");
  if (zoomExtentRatioIndex == -1)
    selectAttributes["zoomExtentRatio"] = 1.2;
  else
    selectAttributes["zoomExtentRatio"] = this.decodeDOUBLE(newNode.childNodes[zoomExtentRatioIndex]);
  selectAttributes["resultTemplate"] = this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"resultTemplate")]);
  var sqlParamsIndex = this.__helper__getNextElementNamedChildNode(newNode,0,"sqlParams");
  if (sqlParamsIndex > -1)
    selectAttributes["sqlParams"] = this.parseChainedQuerySqlParams(newNode.childNodes[sqlParamsIndex]);
  else
    selectAttributes["sqlParams"] = null;
  return selectAttributes;
};

FreeanceXMLParser.prototype.parseChainedQuerySqlParams = function(sqlParamsNode)
{
  var sqlParams = new Array();
  var sqlParamNodeList = sqlParamsNode.getElementsByTagName('sqlParam');
  var numQueries = 0;
  for(var lcv=0;lcv < sqlParamNodeList.length;lcv++)
  {
    numQueries++;
    var theNode = sqlParamNodeList[lcv];
    sqlParams[lcv] = new Object;
    sqlParams[lcv]["pdqIdentifier"] = this.decodeSTRING(theNode.childNodes[this.__helper__getNextElementNamedChildNode(theNode,0,"pdqIdentifier")]);
    sqlParams[lcv]["fieldList"] = new Array();
    var fieldListNode = theNode.childNodes[this.__helper__getNextElementNamedChildNode(theNode,0,"fieldList")];
    var fieldNodeList = fieldListNode.getElementsByTagName('field');
    for(var fieldIndex=0;fieldIndex < fieldNodeList.length;fieldIndex++)
    {
      var fieldListIndex = sqlParams[lcv]["fieldList"].length;
      sqlParams[lcv]["fieldList"][fieldListIndex] = new Object();
      sqlParams[lcv]["fieldList"][fieldListIndex]["fieldName"] = this.decodeSTRING(fieldNodeList[fieldIndex].getElementsByTagName("fieldName")[0]);
      sqlParams[lcv]["fieldList"][fieldListIndex]["pdqFieldName"] = this.decodeSTRING(fieldNodeList[fieldIndex].getElementsByTagName("pdqFieldName")[0]);
    }
    if (this.__helper__getNextElementNamedChildNode(theNode,0,"queryType") > -1)
    {
      sqlParams[lcv]["queryType"] = this.decodeSTRING(theNode.childNodes[this.__helper__getNextElementNamedChildNode(theNode,0,"queryType")]);
      sqlParams[lcv]["numRows"]   = this.decodeINT(theNode.childNodes[this.__helper__getNextElementNamedChildNode(theNode,0,"numRows")]);
      sqlParams[lcv]["startAt"] = this.decodeINT(theNode.childNodes[this.__helper__getNextElementNamedChildNode(theNode,0,"startAt")]);
    }
    else  // do not want.  use full select instead
    {
      sqlParams[lcv]["queryType"] = '';
      sqlParams[lcv]["numRows"] = 0;
      sqlParams[lcv]["startAt"] = 0;
    }
  }
  if (numQueries == 0)
    sqlParams = null;
  return(sqlParams);
};

FreeanceXMLParser.prototype.parseThemeBufferOptions = function(newNode)
{
  var bufferAttributes = {
    styleSheet: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"styleSheet")]),
    fieldList: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"fieldList")]),
    limit: this.decodeINT(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"limit")]),
    resultTemplate: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"resultTemplate")]),
    invalidTemplate: this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"invalidTemplate")]),
    maxSelect: this.decodeINT(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"maxSelect")])
  };
  var sqlParamsIndex = this.__helper__getNextElementNamedChildNode(newNode,0,"sqlParams");
  if (sqlParamsIndex > -1)
    bufferAttributes["sqlParams"] = this.parseChainedQuerySqlParams(newNode.childNodes[sqlParamsIndex]);
  else
    bufferAttributes["sqlParams"] = null;
  if (this.__helper__getNextElementNamedChildNode(newNode,0,"filterQueries") != -1)
  {
    var queryListNode = newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"filterQueries")];
    bufferAttributes["filterQueries"] = new Object;
    for (var queryIndex = this.__helper__getNextElementNamedChildNode(queryListNode,0,"query");queryIndex!=-1;queryIndex=this.__helper__getNextElementNamedChildNode(queryListNode,queryIndex+1,"query"))
    {
      bufferAttributes["filterQueries"][this.decodeSTRING(queryListNode.childNodes[queryIndex])] = null;
    }
  }
  else
    bufferAttributes["filterQueries"] = null;
  if (this.__helper__getNextElementNamedChildNode(newNode,0,"export_csv")!=-1)
  {
    if (!bufferAttributes["export"])
      bufferAttributes["export"] = new Object;
    bufferAttributes["export"].csv = new Object;
    if(this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"export_csv")]) == 'true')
    {
      bufferAttributes["export"].csv.enabled = true;
      bufferAttributes["export"].csv.delim = this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"export_csv_delim")]);
      if(this.decodeSTRING(newNode.childNodes[this.__helper__getNextElementNamedChildNode(newNode,0,"export_csv_includefieldnames")])=='true')
        bufferAttributes["export"].csv.includeFieldNames = true;
      else
        bufferAttributes["export"].csv.includeFieldNames = false;
    }
    else
      bufferAttributes["export"].csv.enabled = false;
  }
  return bufferAttributes;
};

FreeanceXMLParser.prototype.parseLegendAttributes = function (newNode)
{
  return (newNode.nodeName=='legendAttributes')?{
    width: this.decodeINT(newNode.getElementsByTagName('width')[0].getElementsByTagName('int')[0]),
    height: this.decodeINT(newNode.getElementsByTagName('height')[0].getElementsByTagName('int')[0]),
    color: this.decodeSTRING(newNode.getElementsByTagName('color')[0].getElementsByTagName('string')[0]),
    font: this.decodeSTRING(newNode.getElementsByTagName('font')[0].getElementsByTagName('string')[0]),
    fontSize: this.decodeINT(newNode.getElementsByTagName('fontSize')[0].getElementsByTagName('int')[0]),
    valueFontSize: this.decodeINT(newNode.getElementsByTagName('valueFontSize')[0].getElementsByTagName('int')[0]),
    cellSpacing: this.decodeINT(newNode.getElementsByTagName('cellSpacing')[0].getElementsByTagName('int')[0])
  }:{
    width: newNode.getAttribute('width'),
    height: parseInt(newNode.getAttribute('height')),
    color: newNode.getAttribute('color'),
    font: newNode.getAttribute('font'),
    fontSize: newNode.getAttribute('fontSize'),
    valueFontSize: parseInt(newNode.getAttribute('valueFontSize')),
    cellSpacing: parseInt(newNode.getAttribute('cellSpacing'))
  };
};


FreeanceXMLParser.prototype.parseMapExportConfig = function(newNode)
{
  var exportConfig = new Object;
  exportConfig.enabled = newNode.getAttribute('enabled');
  return exportConfig;
};

FreeanceXMLParser.prototype.parsePdfPrintConfig = function (newNode)
{
  var printConfig = {
    templates: [],
    defaultTemplate: parseInt(newNode.getAttribute('defaultTemplate'))
  };
  var templateNodes = newNode.getElementsByTagName('template');
  for(var i=0;i<templateNodes.length;i++)
  {
    var inputNodes = templateNodes[i].getElementsByTagName('userinput');
    var userinput = [];
    for (var j=0;j<inputNodes.length;j++)
      userinput.push({
          id:inputNodes[j].getAttribute('id'),
          description:inputNodes[j].getAttribute('description'),
          maxlength:parseInt(inputNodes[j].getAttribute('maxlength'))
      });
    printConfig.templates.push({
      displayName: this.decodeSTRING(templateNodes[i].getElementsByTagName("displayname")[0]),
      templateName: this.decodeSTRING(templateNodes[i].getElementsByTagName("templatename")[0]),
      orientation: templateNodes[i].getAttribute('orientation'),
      unit: templateNodes[i].getAttribute('unit'),
      width: parseFloat(templateNodes[i].getAttribute('width')),
      height: parseFloat(templateNodes[i].getAttribute('height')),
      mapwidth: parseFloat(templateNodes[i].getAttribute('mapwidth')),
      mapheight: parseFloat(templateNodes[i].getAttribute('mapheight')),
      userinput: userinput
    });
  }
  if ((printConfig.templates.length > 0)&&(printConfig.defaultTemplate==-1))
    printConfig.defaultTemplate = 0;
  if (printConfig.templates.length==0)
    printConfig.defaultTemplate = -1;
  printConfig.activeTemplate = printConfig.defaultTemplate;
  return printConfig;
};

FreeanceXMLParser.prototype.parseQueryConfig = function(queryRootNode)
{
  var queries = new Object();
  var htmlString = '';
  for (var queryIndex = this.__helper__getNextElementNamedChildNode(queryRootNode,0,"definedQuery");queryIndex!=-1;queryIndex=this.__helper__getNextElementNamedChildNode(queryRootNode,queryIndex+1,"definedQuery"))
  {
    var currentQuery = queryRootNode.childNodes[queryIndex];
    queries[currentQuery.getAttribute("id")] = this.parseDefinedQuery(currentQuery);
  }
  OBJECT_MANAGER.setGuiValue('queries', queries);
  return queries;
};

FreeanceXMLParser.prototype.parseDefinedQuery = function(queryNode)
{
  var requestNode = queryNode.getElementsByTagName('request')[0];
  var fieldsNode = queryNode.getElementsByTagName('fieldList')[0];
  var exportNode = queryNode.getElementsByTagName('exportQuery')[0];
  var templateNode = queryNode.getElementsByTagName('resultTemplates')[0];
  var fieldList = [];
  var fieldNodes = fieldsNode.getElementsByTagName('textField');
  for (var i=0;i<fieldNodes.length;i++)
  {
    fieldList.push({
        fieldName:this.decodeSTRING(fieldNodes[i].getElementsByTagName('fieldName')[0]),
        initialValue:this.decodeSTRING(fieldNodes[i].getElementsByTagName('initialValue')[0]),
        defaultValue:this.decodeSTRING(fieldNodes[i].getElementsByTagName('defaultValue')[0])
    });
  }
  var dbtypeIndex = this.getNextElementNamedChildNode(requestNode,0,"dbtype");
  var config = {
    id: queryNode.getAttribute('id'),
    display: (this.decodeSTRING(queryNode.childNodes[this.getNextElementNamedChildNode(queryNode,0,"display")])=='true'),
    title: this.decodeSTRING(queryNode.getElementsByTagName('title')[0]),
    description: this.decodeSTRING(queryNode.getElementsByTagName('description')[0]),
    HTMLForm: this.decodeSTRING(queryNode.getElementsByTagName('HTMLForm')[0]),
    fieldList:fieldList,
    request:{
      dbtype: (dbtypeIndex>0)?this.decodeSTRING(requestNode.childNodes[dbtypeIndex]):null,
      requestMethod: this.decodeSTRING(requestNode.childNodes[this.getNextElementNamedChildNode(requestNode,0,"requestMethod")]),
      pdqIdentifier: this.decodeSTRING(requestNode.childNodes[this.getNextElementNamedChildNode(requestNode,0,"pdqIdentifier")])
    },
    export_:{
      csv:{
        enabled: (this.decodeSTRING(exportNode.getElementsByTagName('export_csv')[0])=='true'),
        delim:this.decodeSTRING(exportNode.getElementsByTagName('export_csv_delim')[0]),
        includeFieldNames:(this.decodeSTRING(exportNode.getElementsByTagName('export_csv_includefieldnames')[0])=='true')
      },
      xml:{
        enabled: (this.decodeSTRING(exportNode.getElementsByTagName('export_xml')[0])=='true')
      }
    },
    templates:{
      validTemplate:this.decodeSTRING(templateNode.getElementsByTagName('validTemplate')[0]),
      invalidTemplate:this.decodeSTRING(templateNode.getElementsByTagName('invalidTemplate')[0]),
      emptyTemplate:this.decodeSTRING(templateNode.getElementsByTagName('emptyTemplate')[0]),
      pageRows:this.decodeINT(templateNode.getElementsByTagName('pageRows')[0])
    },
    suggestConfig:null
  }
  var suggestNodeIndex = this.getNextElementNamedChildNode(queryNode,0,"suggestConfig");
  if (suggestNodeIndex!=-1)
  {
    config["suggestConfig"] = new Array();
    var suggestConfigNode = queryNode.childNodes[suggestNodeIndex];
    var suggestNodes = suggestConfigNode.getElementsByTagName('suggestInput');
    for (var i=0;i<suggestNodes.length;i++)
    {
      config.suggestConfig.push({
        pdqfield: suggestNodes[i].getAttribute('pdqfield'),
        elementId: suggestNodes[i].getAttribute('elementId'),
        resultElementId: suggestNodes[i].getAttribute('resultElementId'),
        timeout: parseInt(suggestNodes[i].getAttribute('timeout')),
        dbid: suggestNodes[i].getAttribute('dbid'),
        tablename: suggestNodes[i].getAttribute('tablename'),
        fieldname: suggestNodes[i].getAttribute('fieldname'),
        resultlimit: parseInt(suggestNodes[i].getAttribute('resultlimit'))
      });
    }
  }
  return config;  
};

FreeanceXMLParser.prototype.parseMeasureConfig = function(configNode)
{
  var config = null;
  if (configNode != null)
  {
    config = {
      distanceSourceUnits: this.decodeSTRING(configNode.childNodes[this.__helper__getNextElementNamedChildNode(configNode,0,'distanceSourceUnits')]),
      distanceMeasureUnits: this.decodeSTRING(configNode.childNodes[this.__helper__getNextElementNamedChildNode(configNode,0,'distanceMeasureUnits')]),
      distanceColor: this.decodeSTRING(configNode.childNodes[this.__helper__getNextElementNamedChildNode(configNode,0,'distanceColor')]),
      distanceThickness: this.decodeSTRING(configNode.childNodes[this.__helper__getNextElementNamedChildNode(configNode,0,'distanceThickness')])
    }
  }
  OBJECT_MANAGER.setGuiValue('MeasureConfig',config);
  return (config);
};


