! Supports processing of layerwms_config.tbl
! Main categories: URL, Coordinate Reference System (CRS), WMS VERSION, and Layers
!
! @issue   NXM-3684 LayerWMS issues
! @author  Jeanette McCall
! @since   NeXtMidas 4.0.0 (loading logic moved to this include file in 4.0.1)
!
!******************************************************************************!

*******************************************************************************
*                      Setup-related procedures                               *
*******************************************************************************

*********************************************************
* Load table and set defaults
*********************************************************
procedure loadTableSetDefaults
  call setupURLs
  call setCoordinateReferenceSystem
  call setupLayers
  call setRequestedVersion
return

*******************************************************************************
*                      URL related procedures                                 *
*******************************************************************************

*********************************************************
* Setup URLS
*********************************************************
procedure setupURLs
  table layerwms_options GETKEY URLS urlsTable
  call formURLopts
  table urlsTable GETKEY URL1 url1Table
  table url1Table GETKEY URL defaultURL
  table url1Table GETKEY CLASSIFICATION defaultURL_class
  res actualURL defaultURL
return

*********************************************************
* Form table for easy grabbing of URLS
*********************************************************
procedure formURLopts
  res urlOpts ""
  res z:first true
  foreach urlKey INTABLE urlsTable
    IF FIRST ISFALSE THEN
      res urlOpts "^{urlOpts},"
    ENDIF
    TABLE urlsTable GETKEY ^{urlKey} urlTable
    TABLE urlTable GETKEY URL url_value
    TABLE urlTable GETKEY CLASSIFICATION url_class
    res urlEntry "^{urlKey}: ^{url_class} ^url_value"
    res urlOpts "^{urlOpts}^{urlEntry}"
    res z:first false
  endfor

return

*******************************************************************************
*                      CRS related procedures                                 *
*******************************************************************************

*********************************************************
* Set Coordinate Reference System value
*********************************************************
procedure setCoordinateReferenceSystem
 ! handle Coordinate Reference System
  if layerwms_options CONTAINS/K CRSS AND fullconfig isFalse then
    ! CRS option(s) specified by name gets preference NXM-3743
    call setUrlCrsUsingCRSS CRS_URL1
  elseif layerwms_options CONTAINS/K CRS_TABLE then
    ! full local CRS table specified
    table layerwms_options GETKEY CRS_TABLE crstable
    table crstable GETKEY CRS_TABLE1 crsDefault
    table crsTable GETVALUESS/S crsValues
    table crsTable GETVALUESS   crsArray
    res actualCRS ""
    res crsstable ""
  elseif layerwms_options CONTAINS/K CRSS then
    say "FULLCONFIG is not available since CRS_TABLE is not included"
    table layerwms_options GETKEY CRSS crsstable
    call setUrlCrsUsingCRSS CRS_URL1
    res z:fullConfig false
  else
    say "CRS will be determined by standard server/client negotiations - no override available"
    res z:fullConfig false
    res crsValues ""
    res actualCRS ""
    res crstable ""
    res z:fullConfig false
  endif

return

***********************************************************************
* Set CRS results based on CRSS table and CRS_URL key
* (if URL is not listed in CRSS, then no override of default CRS table)
***********************************************************************
procedure setUrlCrsUsingCRSS S:crsUrlKey
  table layerwms_options GETKEY CRSS crsstable
  if crsstable CONTAINS/K crsUrlKey then
    table crsstable GETKEY ^crsUrlKey crsDefault
    res actualCRS "^crsDefault"
  else
    res crsDefault "<Negotiated based on default CRS table>"
    res actualCRS ""
  endif
  res crsValues "^crsDefault"
  res crstable ""
return

*********************************************************
* Get mixed case Coordinate Reference System value
*********************************************************
procedure getMixedCaseCRS
  res actualCRS crsDefault

  foreach crsEntry IN crsArray
    invoke match upperCaseCRS.equalsIgnoreCase(crsEntry)
    if match then
      res actualCRS "^crsEntry"
    endif
  endfor

return

*******************************************************************************
*                      WMS Version related procedures                         *
*******************************************************************************

*********************************************************
* set WMS version
*********************************************************
procedure setRequestedVersion
  ! handle requested version
  if layerwms_options CONTAINS/K VERSIONS AND fullconfig isFalse then
    ! give preference to the VERSIONS table as it contains URL specific WMS version to use
    call setUrlVersionUsingVERSIONS VER_URL1
  elseif layerwms_options CONTAINS/K REQUESTEDVERSION then
    ! Let user select between default (1.3.0) and 1.1.1
    table layerwms_options GETKEY REQUESTEDVERSION requestedVersion
    invoke versions requestedVersion.split(",")
    invoke versionDefault versions.0
    set actualVersion versionDefault
    res versionstbl ""
  elseif layerwms_options CONTAINS/K VERSIONS then
    say "FULLCONFIG is not available since REQUESTEDVERSION is not included"
    call setUrlVersionUsingVERSIONS VER_URL1
    res z:fullConfig false
  else
    say "WMS VERSION will be determined by standard server/client negotiations - no override available"
    set requestedVersion ""
    set versionDefault ""
    res versionstbl ""
    res actualVersion ""
    res z:fullConfig false
  endif

return

*****************************************************************
* Set WMS VERSION results based on VERSIONS table and VER_URL key
* (if URL is not listed in VERSIONS, then no override of default)
*****************************************************************
procedure setUrlVersionUsingVERSIONS S:versionUrlKey
  table layerwms_options GETKEY VERSIONS versionstbl
  if versionstbl CONTAINS/K versionUrlKey then
    table versionstbl GETKEY ^versionUrlKey requestedVersion
    set actualVersion ^requestedVersion
  else
    set requestedVersion "<Negotiated with WMS 1.3.0 given preference>"
    set actualVersion ""
  endif
  set versionDefault requestedVersion
return

*******************************************************************************
*                      WMS Layers related procedures                          *
*******************************************************************************

*********************************************************
* Initial Layers Setup
*********************************************************
procedure setupLayers
  table layerwms_options GETKEY LAYERS layersTable
  !table layersTable LIST
  res layersLabelRootTitle "Available Layers based on URL Selection - current layers"
  call createLayerDefault URL1
  res actualLayers "^urlsLayers"
return

*********************************************************
* Create Layer Default Setting from numbers
*********************************************************
procedure createLayerDefault S:NEWURL
  table layersTable GETKEY LAYERS_^{NEWURL} thisUrlLayers
  ! If LAYER_## is not a table, but a reference to a LAYERS_GROUP_#
  ! grab the layer group table
  IF thisUrlLayers NINSTANCEOF nxm.sys.lib.Table THEN
    TABLE layersTable GETKEY ^thisUrlLayers thisUrlLayers
  ENDIF
  table thisUrlLayers GETKEY     CLASSIFICATION layerClassification
  table thisUrlLayers GETKEY ALL layerSelections
  table layerSelections GETVALUESS/S layerOptions
  table thisUrlLayers GETKEY   DEFAULT layerDefNums
  if layerDefNums NEQS "" then
    invoke arrayNums layerDefNums.split(",")
    res LayerDefault ""
    foreach num IN arrayNums
      res thisLayer layerSelections.LAYER_^num
      res LayerDefault "^LayerDefault|^{thisLayer}"
    endfor
    res LayerDefault "^LayerDefault|"
    call calcUrlsLayers LayerDefault
  else
   res LayerDefault ""
   res urlsLayers ""
  endif
  table thisUrlLayers GETKEY BADBACKGROUND layerBadBackNum
  res badBackgroundLay layerSelections.LAYER_^layerBadBackNum
return

*********************************************************
* Create This URLs Layers - used for secondary URL
*********************************************************
procedure createURLsLayers S:NEWURL
  table layersTable GETKEY LAYERS_^{NEWURL} thisUrlLayers
  ! If LAYER_## is not a table, but a reference to a LAYERS_GROUP_#
  ! grab the layer group table
  IF thisUrlLayers NINSTANCEOF nxm.sys.lib.Table THEN
    TABLE layersTable GETKEY ^thisUrlLayers thisUrlLayers
  ENDIF
  table thisUrlLayers GETKEY     CLASSIFICATION layerClassification
  table thisUrlLayers GETKEY ALL layerSelections
  table layerSelections GETVALUESS/S layerOptions
  table thisUrlLayers GETKEY   DEFAULT layerDefNums
  if layerDefNums NEQS "" then
    invoke arrayNums layerDefNums.split(",")
    res OptLayerDefault ""
    foreach num IN arrayNums
      res thisLayer layerSelections.LAYER_^num
      res OptLayerDefault "^OptLayerDefault|^{thisLayer}"
    endfor
    res OptLayerDefault "^OptLayerDefault|"
    call calcUrlsLayers OptLayerDefault
  else
   res OptLayerDefault ""
   res urlsLayers ""
  endif
return

*********************************************************
* Create comma separated layers
*********************************************************
procedure calcUrlsLayers S:pipeSeparated
  invoke urlsLayers  pipeSeparated.replace("|",",")
  invoke actLength   urlsLayers.length
  calc end actLength 1 -
  invoke urlsLayers  urlsLayers.substring(1,^end)
return

*********************************************************
* Create All But version of Layers
* ex: layers["*,-tiger-ny,-shapePolitical,-cadrg"]
*********************************************************
procedure formAllButLayers S:pipeSeparated
  table layerSelections GETVALUESS layerOptions
  invoke defArray actualLayers.split(",")
  invoke defList java.util.Arrays.asList(defArray)
  res allButLayers "*"
  for option IN layerOptions
    invoke keep defList.contains("^option")
    if keep isFALSE then
      res allButLayers "^{allButLayers},-^{option}"
    endif
  endfor
return

*********************************************************
* Get mixed case layers value
*********************************************************
procedure getMixedCaseLayers
  res actualLayers defaultLayers

  foreach layersGrp IN layersArray
    invoke match upperCaseLayers.equalsIgnoreCase(layersGrp)
    if match then
      res actualLayers "^layersGrp"
    endif
  endfor

  invoke actualLayers  actualLayers.replaceAll(" ",",")

return
