!******************************************************************************!
! Tests the Convert 'svinterp' function.
!
! Arguments:
! testName - The name of the test to run (TEST_1, TEST_2, or TEST_3)
!
! @bug      NXM-2578
! @since    NeXtMidas 3.3.2
! @author:  J. Hallam
!******************************************************************************!
startmacro S:testName[""]
  switch INTERACTIVE interAct GET DEF=TRUE  SDEF=TRUE  ! for normal interactive test(s)
  switch BASELINE    baseline GET DEF=FALSE SDEF=TRUE  ! for defects or more obscure test case(s)
  switch DEBUG       debug    GET DEF=TRUE  SDEF=TRUE

  if (testName EQS "") then
    error "Need to call ^{reg.main.name} with [testName] set to TEST_1, TEST_2, or TEST_3"
    stop
  endif

  res S:srPOS   "POSX/SD,POSY/SD,POSZ/SD"
  res S:srVEL   "VELX/SD,VELY/SD,VELZ/SD"
  res S:srACC   "ACCX/SD,ACCY/SD,ACCZ/SD"
  res S:srTIME  "TIME/SD"

  ! Since 3.8.0
  if ^{env.NMROOT} EQS "classpath:" then
    warn "SKIPPING ^reg.main.name since zip files are not copied into SYS JAR file"
    stop
  endif

  ! ==== CREATE TEST FILES =====================================================
  noop nxm.sys.test.sv1_acc.prm{TIMECODE="2012:01:01::00:00:00"} ram:sv1_acc
  file copy/l/f ram:sv1_acc ram:svfile_none                   /PROPMASK=ALL
  file copy/l/f ram:sv1_acc ram:svfile_time{TIME_NAME="TIME"} /PROPMASK=ALL


  ! We keep the test file zipped up since it reduces the size by ~70%
  fname zipFile OPT=SYS AREA=test NAME="nga17212.sp3.zip"
  res   sp3File "jar:file:^{zipFile}!/nga17212.sp3"
  convert sp3file{SELECTED=4} sv2blue ram:sp3file_none
  convert sp3file{SELECTED=4} sv2blue ram:sp3file_time{TIME_NAME=TIME}

  ! ==== TEST VALUES ===========================================================
  ! These values come from the X-Midas SVINTERP_TC with 2 terms (i.e. Linear),
  ! 4 terms (i.e. CubicHermite), or 6 terms (i.e. QuinticHermite).
  res T:allTestCases {&
        TEST_1={&
         DESCRIPTION="Modified sv1.prm (test 1 of 2)",&
         IN_NONE="ram:svfile_none",&
         IN_TIME="ram:svfile_time",&
         START_TIME=2012:01:01::00:00:00,&
         COLS="POS,VEL,ACC,TIME",&
         NUM_ROWS=100,&
         DELTA_WSEC=17.0,&
         DELTA_FSEC=0.0123,&
         TERMS_2={},&
         TERMS_4={},&
         TERMS_6={}},&
        TEST_2={&
         DESCRIPTION="Modified sv1.prm (test 2 of 2)",&
         IN_NONE="ram:svfile_none",&
         IN_TIME="ram:svfile_time",&
         START_TIME=2012:01:01::00:00:00,&
         COLS="POS,VEL,ACC,TIME",&
         NUM_ROWS=7,&
         DELTA_WSEC=200.0,&
         DELTA_FSEC=0.0,&
         TERMS_2={},&
         TERMS_4={},&
         TERMS_6={}},&
        TEST_3={&
         DESCRIPTION="SP3 file for GPS vehicle",&
         IN_NONE="ram:sp3file_none",&
         IN_TIME="ram:sp3file_time",&
         START_TIME=2013:01:01::00:00:00,&
         COLS="POS,VEL,TIME",&
         NUM_ROWS=100,&
         DELTA_WSEC=30.0,&
         DELTA_FSEC=0.0,&
         TERMS_2={},&
         TERMS_4={},&
         TERMS_6={}}}

  ! ==== INIT TESTS ============================================================
  invoke S:subrecs  nxm.sys.lib.ICEPacket.SUBRECORDS_NORMAL
  invoke B:dataRep  nxm.sys.lib.Shell.rep

  res  testCase          allTestCases.^{testName}
  calc testCase.DELTA    testCase.DELTA_WSEC testCase.DELTA_FSEC +
  calc testCase.END_TIME testCase.START_TIME testCase.NUM_ROWS testCase.DELTA * +
  ! TIMESPEC added for bug 2822 allowing user to specify start/stop/delta directly
  res timespec {start=^{testCase.START_TIME}, &
                  stop=^{testCase.END_TIME}, &
                  delta=^{testCase.DELTA}}


  status testCase.IN_TIME NC=nsr
  if (testCase.COLS EQS "POS,VEL,ACC,TIME") then
    res S:srOrig     "(^{srPOS},^{srVEL},^{srACC},^{srTIME})"
    res S:srSVINTERP "(^{srPOS},^{srVEL},^{srACC},^{srTIME})"
  else
    res S:srOrig     "(^{srPOS},^{srVEL},^{srTIME})"
    res S:srSVINTERP "(^{srPOS},^{srVEL},^{srTIME})"
  endif

  ! ==== CREATE TIME & PKT FILES ===============================================
  res    B:dataBPA   4 ! BPA("SF")=4
  res    B:dataMode 83 ! 83='S'
  res    B:dataType 70 ! 70='F'

  headermod/create ram:pktfile  TYPE=3000 SR="(^subrecs)"
  headermod/create ram:timefile TYPE=3000 SR="(TIME/SD)"

  file open/a p ram:pktfile
    file open/a t ram:timefile
      do i 0 ^{testCase.NUM_ROWS}-1 1
        calc L:j    i 1 +
        res  D:TCO  0
        calc D:FSEC testCase.DELTA_FSEC i *
        calc D:TCWS testCase.START_TIME testCase.DELTA_WSEC i * + FSEC FLOOR +
        calc D:TCFS FSEC 1 MOD
        calc D:TC   TCWS TCFS +
        calc L:ELEM 1K
        res  T:prow {KEYS=(101,102,103,0),CNT=^{j},ELEM=^{ELEM},USER=0,CHAN=1,SID=(0,0),&
                     REP=^{dataRep},BPA=^{dataBPA},MODE=^{dataMode},TYPE=^{dataType},&
                     TCM=0,TCS=1,TCO=^{TCO},TCWS=^{TCWS},TCFS=^{TCFS},&
                     RBST=0,RBSZ=0,RBDO=0,RBDS=0}
        res  T:trow {TIME=^{TC}}

        invoke ,, p.writeDataTable(prow)
        invoke ,, t.writeDataTable(trow)
      enddo
    file close t
  file close p

  ! ==== RUN THE TESTS =========================================================
  do order 2 6 2
    ! ---- INIT ----------------------------------------------------------------
    if (order == 2) then res interpOrder "Linear"
    if (order == 4) then res interpOrder "CubicHermite"
    if (order == 6) then res interpOrder "QuinticHermite"

    ! ---- RUN SVINTERP --------------------------------------------------------
    convert testCase.IN_TIME SVINTERP ram:svtime_pkt  TIMES=ram:pktfile  OPTIONS={INTERPOLATIONORDER=^{interpOrder}}
    convert testCase.IN_TIME SVINTERP ram:svtime_time TIMES=ram:timefile OPTIONS={INTERPOLATIONORDER=^{interpOrder}}
    convert testCase.IN_NONE SVINTERP ram:svnone_pkt  TIMES=ram:pktfile  OPTIONS={INTERPOLATIONORDER=^{interpOrder}}
    convert testCase.IN_NONE SVINTERP ram:svnone_time TIMES=ram:timefile OPTIONS={INTERPOLATIONORDER=^{interpOrder}}
    ! TIMESPEC added for bug 2822 allowing user to specify start/stop/delta directly
    convert testCase.IN_NONE SVINTERP ram:svnone_timespec TIMESPEC=timespec OPTIONS={INTERPOLATIONORDER=^{interpOrder}}

    ! ---- SAVE RESULTS FOR LATER VIEWING IN GUI -------------------------------
    noop ram:svtime_pkt{TYPE=3000,SR=^{srSVINTERP},FORM=SD} ram:svinterp^{order}

    ! ---- COMPARE TIME+ICEPacket to NONE+TIME ---------------------------------
    res T:fileTests {TEXT="^reg.main.name: (^{interpOrder}) TIME+ICEPacket = NONE+TIME"}
    file open ft ram:svtime_pkt
      file open fn ram:svnone_pkt
        assert/group=fileTests/test ft.XSTART EQ  fn.XSTART
        assert/group=fileTests/test ft.XDELTA EQT fn.XDELTA
        assert/group=fileTests/test ft.XUNITS EQ  fn.XUNITS

        do i 0 ^{testCase.NUM_ROWS}-1 1
          res    T:ftRow ft.getDataTable(i)
          invoke T:fnRow fn.getDataTable(i)

          foreach col inList testCase.COLS
            assert/group=fileTests/test ^{ftRow.^{col}} EQ/T ^{fnRow.^{col}}
          endfor
        enddo
      file close fn
    file close ft
    assert/group=fileTests/summary

    ! ---- COMPARE ?+ICEPacket to ?+TIME ---------------------------------------
    assert/text="^reg.main.name: (^{interpOrder}) TIME+ICEPacket = TIME+TIME" ram:svtime_pkt FEQ/S/D/H ram:svtime_time
    assert/text="^reg.main.name: (^{interpOrder}) NONE+ICEPacket = NONE+TIME" ram:svnone_pkt FEQ/S/D/H ram:svnone_time

    ! ---- COMPARE NONE+TIME to NONE+TIMESPEC (bug 2822)------------------------
    assert/TOL=1.0E-16/text="^reg.main.name: (^{interpOrder}) NONE+TIME = NONE+TIMESPEC" ram:svnone_time FEQ/S/D/H/T ram:svnone_timespec

    ! ---- CHECK TIME+ICEPacket VS EXPECTED RESULTS ----------------------------
    res T:fileTests {TEXT="^reg.main.name: (^{interpOrder}) TIME+ICEPacket is valid"}
    file open f ram:svtime_pkt
      assert/group=fileTests/test 0.0            EQ  f.XSTART
      assert/group=fileTests/test testCase.DELTA EQT f.XDELTA   /DELTA=1e-24
      assert/group=fileTests/test 1              EQ  f.XUNITS   ! 1=TIME_S

      ! Check against select X-Midas results
      foreach i inTable testCase.TERMS_^{order}
        res    T:expRow testCase.TERMS_^{order}.^{i}
        invoke T:actRow f.getDataTable(i)
        foreach col inList testCase.COLS
          assert/group=fileTests/test ^{expRow.^{col}} EQ/T ^{actRow.^{col}}
        endfor
      endfor

      ! Check against matches in the file
      file open ff testCase.IN_TIME
        do i 0 f.size-1
          invoke T:actRow f.getDataTable(i)
          calc D:offset actRow.TIME ff.TIME - ff.XDELTA /
          calc L:off    offset ROUND

          if/TOL=1e-12 (offset EQT off) then
            invoke T:expRow ff.getDataTable(off)

            foreach col inList testCase.COLS
              assert/group=fileTests/test ^{expRow.^{col}} EQ/T ^{actRow.^{col}}
            endfor
          endif
        enddo
      file close ff
    file close f
    assert/group=fileTests/summary
  enddo

  if (interAct) then
    noop testCase.IN_TIME{TYPE=3000,SR=^{srOrig},FORM=SD} ram:orig
    headermod ram:orig SIZE=^{testCase.NUM_ROWS}

    set inst "Viewing ^{testCase.DESCRIPTION} with ^{testCase.COLS}. Please &
              check to see that the colored lines closely follow the portion &
              of the white line which they are near. The colored lines should &
              be smooth and not wavy.\n&
              \n&
              KNOWN DR: Click ZoomVel to zoom in on the Velocity plot. The white line &
              and the colored line(s) should still line up (Bug 1161)."
    pipe on
      panel/msgid=MAIN/setup/controls=gc
      gcontrol label macro "MACRO"
      gcontrol menu MAIN "Exit with Status = " "PASS,FAIL" /tleft
      set gc.MAIN.itemColors {PASS=GREEN,FAIL=RED}
      gcontrol text idtext "INSTRUCTIONS" "^{inst}" 24 16 /title
      gcontrol button "ZoomVel" "" "ZoomVel"

      rem time
      foreach ord inList testCase.COLS
        if (ord EQS "TIME") then continue

        res T:layerOpt0 {LT="Scatter",X="TIME",Y="^{ord}X",TYPE="+SYMBOL",LINE={SYMBOL="STAR",COLOR="WHITE"}}
        res T:layerOpt2 {LT="Scatter",X="TIME",Y="^{ord}X",TYPE="-SYMBOL",LINE={SYMBOL="SQUARE",COLOR="RED"}}
        res T:layerOpt4 {LT="Scatter",X="TIME",Y="^{ord}X",TYPE="-SYMBOL",LINE={SYMBOL="SQUARE",COLOR="YELLOW"}}
        res T:layerOpt6 {LT="Scatter",X="TIME",Y="^{ord}X",TYPE="-SYMBOL",LINE={SYMBOL="SQUARE",COLOR="CYAN"}}

        calc abscStart testCase.START_TIME FILE(ram:orig).time - FILE(ram:orig).xdelta /
        calc abscEnd   testCase.END_TIME   FILE(ram:orig).time - FILE(ram:orig).xdelta /

        plot/id="PLOT_^{ord}X" ram:orig(^{abscStart}:^{abscEnd}){LAYER=^layerOpt0}|&
                               ram:svinterp2{LAYER=^layerOpt2}|&
                               ram:svinterp4{LAYER=^layerOpt4}|&
                               ram:svinterp6{LAYER=^layerOpt6} readout=+DateString
      endfor
    pipe off
  endif
endmacro

!******************************************************************************!
procedure processMessage m:msg
  !say "msg.name ^msg.name, data ^msg.data"

  if (msg.name EQS "MAIN") then
    assert/text="^reg.main.name: Interactive tests for SVINTERP" msg.data eqs "PASS"
    pipe stop

  elseif (msg.name EQS "ZoomVel") then
    message send PLOT_VELX NAME=ZOOM INFO=0 DATA={XMIN=D:1.9565291918457816E9,XMAX=D:1.9565292090301435E9,&
                                                  YMIN=D:-4.866472551806098,YMAX=D:-4.842489927986739}
  else
    say "^reg.main.name: Unhandled message name: ^msg.name from fid: ^msg.fid data: ^msg.data"
  endif
return


!******************************************************************************!
! Taken from %TEST_FILE
procedure _checkRecDefPRM T:testGroup T:recDef S:expName S:expFormat L:expOffset S:expType S:expUnits
  assert/group=testGroup/test recDef.^{expName}.NAME   EQS expName
  assert/group=testGroup/test recDef.^{expName}.FORMAT EQS expFormat
  assert/group=testGroup/test recDef.^{expName}.OFFSET EQ  expOffset
  assert/group=testGroup/test recDef.^{expName}.TYPE   EQS expType
  assert/group=testGroup/test recDef.^{expName}.UNITS  EQS expUnits
return
