!******************************************************************************!
! Test timeline propagation include file for procedures common to test_timeline_propagation tests 
!
! @bug      NXM-3637 Wrapped BLUE TC timelines only writing entries since wrap
!                    Wrapped usec TIMELINE writing entries out in buffer order
!                      even when wrap is in the middle
!           NXM-3638 Timelines need to be properly propagated when in a pipe
!           NXM-3639 Nextmidas does not propagate time hacks properly - file-to-file > 128 hacks
!
! note: 38400 elements gives good display of usec wrap issue on timecodevisual
!
! @since     NeXtMidas 3.9.4
! @author :  Jeanette McCall

!******************************************************************************!

!******************************************************************************!
! Initial setup - calculate expected and create initial files if they do not exist
!******************************************************************************!
procedure setupForTimelinePropagationTest U:usec_file_to_create U:tc_file_to_create U:plat_file_to_create Z:refresh L:tll[-1] L:numElem[40k]

    res temp_file_timeline_propagation ram:temp_file_waveform

    ! settings
    set  sr          1e5
    set  sfreq       sr/10
    set  elemPerTimestamp 64                                 ! place a timestamp every this many elements
    calc fft_size    elemPerTimestamp 2 *                    ! just showing extra timestamps ignored by having 2 timestamps per frame
    calc nEntries    numElem  elemPerTimestamp /             ! expected number of time stamp entries - original
    res  num_wrap    128                                     ! expected number of timeline wraps, since default timeline size is 128
    res  numWrapGrow 256                                     ! expected number of timeline wraps after growing
    set  numWrapNewDefault 256                               ! expected number of timeline wraps with new default value
    calc nFFTEntries nEntries elemPerTimestamp * fft_size /  ! number of FFT frames / elements

    ! high precision TC calculations
    calc lastHack0 numElem ^elemPerTimestamp -
    calc lastHack1 lastHack0 1 +                                                        ! TC is 1-based
    calc numElemBackWrap num_wrap 1 - elemPerTimestamp *                                ! number of elements between first and last TC time hacks (with TLL=128)
    calc firstHackWrap lastHack1 numElemBackWrap -                                      ! first TC time hack (with TLL=128)
    calc numElemBackWrapNewDefault numWrapNewDefault 1 - elemPerTimestamp *             ! number of elements between first and last TC time hacks (with TLL=256)
    calc firstHackWrapNewDefault lastHack1 numElemBackWrapNewDefault -                  ! first TC time hack (with TLL=256)
    calc numElemBackWrapFFT num_wrap 1 -                                                ! number of elements between first and last FFT TC time hacks (with TLL=128)
    calc firstHackWrapFFT nFFTEntries numElemBackWrapFFT -                              ! first FFT TC time hack (with TLL=128)
    calc numElemBackWrapFFTGrow numWrapGrow 1 -                                         ! number of elements between first and last FFT TC time hacks (with TLL=-256)
    calc firstHackWrapFFTGrow nFFTEntries numElemBackWrapFFTGrow -                      ! first FFT TC time hack (with TLL=-256)

    ! usec TIMELINE byte calculations
    res  bytesPerSI 2                                                                   ! each element is SI 2 bytes
    calc lastHackByte lastHack0 bytesPerSI *                                            ! Microsecond is 0-based
    calc numBackByteswrap num_wrap 1 - bytesPerSI * elemPerTimestamp *                  ! number of bytes between first and last Microsecond time hacks (with TLL=128)
    calc firstHackByte lastHackByte numBackByteswrap -                                  ! first Microsecond time hack in bytes (with TLL=128)
    res  bytesPerCF 4                                                                   ! each FFT element is CF 4 bytes
    calc bytesperFFT fft_size bytesPerCF *                                              ! number of bytes per FFT Microsecond
    calc lastHackByteFFT nFFTEntries 1 - bytesperFFT *                                  ! last FFT Microsecond time hack in bytes
    calc numBackBytesFFTwrap num_wrap 1 - bytesPerCF * fft_size *                       ! number of bytes between first and last FFT Microsecond time hacks (with TLL=128)
    calc firstHackByteFFTwrap lastHackByteFFT numBackBytesFFTwrap -                     ! first FFT Microsecond time hack in bytes (with TLL=128)
    calc numBackBytesFFTwrapGrow numWrapGrow 1 - bytesPerCF * fft_size *                ! number of bytes between first and last FFT Microsecond time hacks (with TLL=-256)
    calc firstHackByteFFTwrapGrow lastHackByteFFT numBackBytesFFTwrapGrow -             ! first FFT Microsecond time hack in bytes (with TLL=-256)
    calc numBackBytesFFTwrapNewDefault numWrapNewDefault 1 - bytesPerCF * fft_size *    ! number of bytes between first and last FFT Microsecond time hacks (with TLL=256)
    calc firstHackByteFFTwrapNewDefault lastHackByteFFT numBackBytesFFTwrapNewDefault - ! first FFT Microsecond time hack in bytes (with TLL=256)

    ! platinum timeline calculations
    set lastHackPlat lastHack0                                                          ! Platinum is 0-based
    set numElemBackWrapPlat numElemBackWrap                                             ! number of elements between first and last Platinum time hacks (with TLL=128)
    calc firstHackWrapPlat lastHackPlat numElemBackWrapPlat -                           ! first Platinum time hack (with TLL=128)
    set numElemBackWrapPlatNewDefault numElemBackWrapNewDefault                         ! number of elements between first and last Platinum time hacks (with TLL=256)
    calc firstHackWrapPlatNewDefault lastHackPlat numElemBackWrapPlatNewDefault -       ! first Platinum time hack (with TLL=256)
    set numElemBackWrapPlatFFT numElemBackWrapFFT                                       ! number of elements between first and last FFT Platinum time hacks (with TLL=128)
    calc firstHackWrapPlatFFT nFFTEntries 1 - numElemBackWrapPlatFFT -                  ! first FFT Platinum time hack (with TLL=128)
    calc numElemBackWrapPlatFFTGrow numWrapGrow 1 -                                     ! number of elements between first and last FFT Platinum time hacks (with TLL=-256)
    calc firstHackWrapPlatFFTGrow nFFTEntries 1 - numElemBackWrapFFTGrow -              ! first FFT Platinum time hack (with TLL=-256)

    if DEBUG then
      res nFFTEntries
      ! TC
      res lastHack1
      res firstHackWrap
      res firstHackWrapFFT
      res firstHackWrapFFTGrow
      ! TIMELINE
      res lastHackByte
      res firstHackByte
      res lastHackByteFFT
      res firstHackByteFFTwrap
      res firstHackByteFFTwrapGrow
      ! PLATINUM
      res lastHackPlat
      res firstHackWrapPlat
      res firstHackWrapPlatFFT
      res firstHackWrapPlatFFTGrow
    endif


    !****************************************************************************
    ! Create the initial files if they do not exist or we are refreshing them
    !****************************************************************************

    if testfile_usec_timeline NFEXISTS OR testfile_tc_timeline NFEXIST OR testfile_plat_timeline NFEXIST OR refresh then
      ! Defines a new timeline with a fixed size
      set s:epochTL "2010:03:13::00:00:00.000000" ! used to set TimeLine
      new nxm.sys.lib.Time(^epochTL) startTime
      res delta 0.2
      res l:bpe 2
      invoke tolr nxm.sys.lib.TimeLine.MICROSECOND_TOLERANCE
      invoke timelineNew nxm.sys.test.TestTimelineCreator.timelineFixedSize(delta,bpe,starTtime,numElem,elemPerTimestamp,nEntries,tolr)

      ! The timeline gets passed into a new waveform file
      waveform OUT=temp_file_timeline_propagation  FORM=SI ELEM=numElem DELTA=delta AMP=10  START=startTime ! file to add a timeline to
      noop temp_file_timeline_propagation usec_file_to_create
      file open/d/w tag usec_file_to_create
      invoke ,, tag.setTimeLineObject(timelineNew)
      file close tag

      convert ^usec_file_to_create KWCONV tc_file_to_create{USEBLUETCTIMELINE=true,TLL=-1} OPTIONS={}

      convert ^usec_file_to_create KWCONV plat_file_to_create{USEPLATINUMTIMELINE=true,TLL=-1} OPTIONS={}
      say ""
      call printPlatWarnMsgs
    endif

return

!******************************************************************************!
! Check if the tables are the same and either warn or error out
! This allows a check against desired behavior that only issues a warning
!******************************************************************************!
procedure checkTablesSame u:tbl1name u:tbl2name Z:info_only S:message
  res Z:tables_equal true
  res firstname tbl1name
  res t:tbl1 ^tbl1name
  res secondname tbl2name
  res t:tbl2 ^tbl2name

  foreach key intable tbl1
    if tbl2 ncontains ^{key} then
      res key
      res Z:tables_equal false
      if info_only then
        INFO "^{message}\n    ^firstname: ^tbl1 ^secondname:   ^tbl2"
        return
      else
        assert/text="^message\n      ^firstname: ^tbl1\n       ^secondname:   ^tbl2" true isfalse
        return
      endif
    else
      invoke str_value1 java.lang.String.valueOf(tbl1.^key)
      invoke str_value2 java.lang.String.valueOf(tbl2.^key)
      
      if str_value1 NEQS str_value2 then
        if info_only then
          INFO "^{message}\n      ^firstname: ^tbl1\n      ^secondname:   ^tbl2"
          return
        else
          assert/text="^message\n      ^firstname: ^tbl1\n      ^secondname:   ^tbl2" true isfalse
          return
        endif
      endif
    endif

  endfor
  
  if tables_equal then
    assert/text="^message" true istrue
  endif
return

!******************************************************************************!
! Print out warning message with regards to using Platinum cdif files
!******************************************************************************!
procedure printPlatWarnMsgs
  info "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
  info "Expect to see this warning with regards to Platinum cdif files:"
  info "Midas TimeCode+TC_PREC+Start not matching Platinum TIMETAG.TIME"
  info "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
return