! Tests restarts when original file has fixed starttime and timeline keywords
!
! Issue: NXM-3183 TimeLine restarts
! Since: NextMidas 3.8.0
!
! Author:  Neon Ngo, Jeanette McCall
!
startmacro S:throttle["REAL"]
  switch INTERACTIVE   interAct     GET DEF=TRUE  SDEF=TRUE
  switch BASELINE      baseline     GET DEF=FALSE SDEF=TRUE

  switch ERASE         eraseFiles     GET DEF=FALSE  SDEF=TRUE ! erase the large files created/used by this test
  switch RANDOMJITTER  randomJitter   GET DEF=TRUE  SDEF=TRUE  ! jitter varied randomly (versus by count)
  switch TIMELINEKW    timelinekw     GET DEF="TIMELINE"       ! TimeLine keywors "TIMELINE" or "TC"
  switch TLL           timelineLength GET DEF=-1               ! TimeLine length default is GROW_AS_NEEDED

  env get IOOptions origIOOptions
  !env set IOOptions +FixPipeRestartTimeLines               ! No longer needed in 3.9.4
  !env set IOOptions +DoNotPropagateTimelineKeywordsInPipe  ! No longer needed in 3.9.4

  ! Only allow interAct if PANEL command Exists - may be running in LIBNXM mode
  invoke panelExists reg.shell.M.dictionary.isDictionaryEntry(PANEL)

  res initTime "2018:01:02::08:00:00"
  new nxm.sys.lib.Time(^initTime) starttime

  if interAct AND panelExists then
    set instructions "1) Do a pipe RESTART by changing the FFT frame size\n&
                      2) Check the time values across the frequency change and verify that &
                      time does NOT go back to ^{initTime}.\n\n&
                      NOTE: Known Issue fft.open grabs time information from the header &
                      resulting in incorrect values during restarts\n\n&
                      FUTURE: This can be used for more detailed testing of RESTARTS &
                      and timelines once FFT is fixed or a primitive with XSTART/YSTART &
                      control is added."

    ! TimeLine tolerance and setting transfer length so timeline will be propagated
    set tolr       1e-6  ! timeline tolerance
    set xferlength 256   ! should match smallest frame size
    set maxJitter  1e-5  ! should be greater than tolerance


    ! waveform properties
    set format sf         ! format scalar float
    set sr 1e4            ! sample rate
    set sfreq sr/10       ! sampling frequency
    set chirpamt sfreq/4  ! chirp amount
    set amp 1e4           ! amplitude

    ! fft properties
    set over 0            ! overlap
    set fsize 512         ! default frame size

    ! Use with timeAtPos1 and timeAtPos1 GControls
    set firstClick true

    ! Set file properties - names and number of elements
    set numelem 1e7
    set baseFN  test_wavechirp3183_1e7
    set filewavechip ^{baseFN}.tmp
    res filetimeline baseFN
    res filetimeline
    if randomJitter then
      invoke filetimeline filetimeline.concat("r")
    endif
    invoke filetimelinetc filetimeline.concat("tc.tmp")  ! Create name for file with BLUE TC timeline keywords
    invoke filetimelineb filetimeline.concat("b.tmp")    ! Create name for file with microsecond TIMELINE keywords
    if timelinekw EQS TC then
      res filetimeline filetimelinetc
    else
      res filetimeline filetimelineb
    endif
    info " This test will create file ^filetimeline if is not already in your read aux - use /ERASE if you want files created by this test case to be erased"

    ! Create files if they are not found in READ AUX
    if ^filetimeline NFEXISTS then
      say "CREATING TEST FILES - THIS WILL TAKE SOME TIME **********************"
      if filewavechip NFEXISTS then
        ! create original chirped waveform in write aux
        say "*** creating file containing chirped waveform: ^filewavechip ***"
        waveform ^filewavechip format ^numelem cos freq=sfreq amp=amp delta=1/sr chirp=^chirpamt start=starttime
      endif
      say "*** creating file with TIMELINE keywords: ^filetimelineb ***"
      nxm.sys.test.addjitter in=^filewavechip out=^filetimelineb{TLT=^tolr,TLL=^timelineLength} jitter=^maxJitter /TL=1024 /RANDOM=randomJitter
      say "*** creating matching file with BLUE TC Keywords: ^filetimelinetc ***"
      convert ^filetimelineb KWCONV ^filetimelinetc{USEBLUETCTIMELINE=true} OPTIONS={}
    endif


    pipe init
      panel/msgid=MAIN/setup/controls=gc

      ! (chirped waveform with timeline) -> fft -> plot
      if timelinekw EQS TC then
        ! pipe file containing chirped waveform and BLUE TC TIMELINE
        noop/throttle=^throttle ^filetimeline{USEBLUETCTIMELINE=true,TLT=^tolr,TLL=^timelineLength} &
                                _wave{USEBLUETCTIMELINE=true,TLT=^tolr,TLL=^timelineLength} /TL=xferlength
        fft/dbf/id=fft _wave _fft{USEBLUETCTIMELINE=true,form=sf,TLT=^tolr,TLL=^timelineLength} fsize over=over
        plot/id=idplotfft/msgid=MAIN/READOUT=Show|OnAxis|T|dT|extPrec|DateString _fft{USEBLUETCTIMELINE=true,TLT=^tolr,TLL=^timelineLength} view=iXY
      elseif timelinekw EQS TIMELINE then
        noop/throttle=^throttle ^filetimeline _wave{TLT=1e-6,TLL=^timelineLength} /TL=^xferlength
        fft/dbf/id=fft _wave _fft{form=sf,TLT=^tolr,TLL=^timelineLength} nfft=fsize over=over
        plot/id=idplotfft/msgid=MAIN/READOUT=Show|OnAxis|T|dT|extPrec|DateString _fft{TLT=^tolr,TLL=^timelineLength} view=iXY
      else 
         say "timeline keywords of type ^timelinekw not covered"
      endif

      ! add box feature to plot for creating a user selectable dragbox on the raster plot
      FEATURE/id=box1 label=box1 table={NAME=BOX1,TYPE=BOX,COLOR=WHITE,ENABLE=1} plot=idplotfft
      FEATURE/id=box2 label=box2 table={NAME=BOX2,TYPE=BOX,COLOR=WHITE,ENABLE=1} plot=idplotfft2

      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" "^instructions" 24 16 /title

      gcontrol label  plot  "PLOT/TIMELINE"
      gcontrol choice framesz "Set FFT FRAME Size:" "256,512,1k" "512" /tleft
!      gcontrol choice adjstart "Tweak seconds on FFT start time:" "-0.5 0.0,0.5,100.0" "0.0" /tleft  ! for debug of xstart/ystart adjustment - requires modifying fft
      gcontrol tval   timeAtPos1 "Time at 1st click" 0 0 -1 /flags="NoMsg|NoEdit"
      gcontrol tval   timeAtPos2 "Time at 2nd click" 0 0 -1 /flags="NoMsg|NoEdit"
      gcontrol tval   tmin "box tMin" 0 0 -1 /msg=no /edit=no
      gcontrol tval   tmax "box tMax" 0 0 -1 /msg=no /edit=no

    pipe off

    ! Not erase files by default, so they can be use for more detailed check
    if eraseFiles then
      erase ^{baseFN}*
    endif
  endif

  env set IOOptions origIOOptions
endmacro

!******************************************************************************!
procedure processMessage m:msg

  if msg.name eqs "MAIN" then
    assert/text="^reg.main.name: User indicated tests" msg.data eqss "PASS"
    pipe stop
  elseif msg.name eqs "DRAGBOX"  then
    if msg.fid eqss "IDPLOTFFT" then
      result tmin msg.data.tmin
      result tmax msg.data.tmax
      timex tmin d:gc.tmin.value
      timex tmax d:gc.tmax.value
      set box1.setBoundsFromTable(msg.data)
    endif
  elseif msg.name eqs "FRAMESZ" then ! since 3.7.2 for NXM-3040
    ! set frame size of both ffts
    res fsize msg.data
    set reg.fft.nfft fsize
  elseif msg.name eqs "ADJSTART" then ! since 3.8.0 for NXM-3040 - for debug only
    say "This was for debug only as fft does not actually have a way to adjust xstart/ystart and currently is not handling pipe restart timelines correctly"
    res adjstart msg.data
!    set reg.fft.adjstart adjstart
  elseif msg.name eqs "MARK"
    ! set the "Time At # Click" gcontrols
    if firstClick then
      res gc.timeAtPos1.value msg.data.time
      res firstClick false
    else
      res gc.timeAtPos2.value msg.data.time
      res firstClick true
    endif
  elseif msg.name eqs "UNZOOM"
    if msg.fid eqs "IDPLOTFFT" then
      invoke reg.idplotfft.refresh()
    elseif msg.fid eqs "IDPLOTNOOP" then
      invoke reg.idplotnoop.refresh()
    endif
  elseif msg.name eqs "ZOOM"
  else
    say "Unhandled message name=^msg.name info=^msg.info fid=^msg.fid data=^msg.data"
  endif

return