!******************************************************************************!
! Visualization tool for diagnosing issues with uSec or TC high precision time codes
!
! Arguments:
! IN - Input File
! OUT - 5000 output
! CSVOUT - CSV output
! REPORT - report file describing issues with file
! RESULT - boolean pass/fail result name
!
! @since    NextMidas 3.9.4
! @author:  Jeanette McCall
!******************************************************************************!
startmacro S:in S:out["timecodevisual5000.tmp"] S:csvout["timecodevisualcsv.csv"] S:report["timecodevisual_report.txt"]
  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 KEEP        keep     GET DEF=FALSE SDEF=TRUE  ! Keep created files - do not erase them
  switch DEBUG       debug    GET DEF=FALSE SDEF=TRUE  ! Show debug prints
  switch SHOWGOOD    showgood GET DEF=FALSE SDEF=TRUE  ! show good example as default, rather than wrapped file

  lookandfeel Gear4

  IF IN EQS "" THEN
    IF SHOWGOOD THEN
      res in nxm.sys.test.fft_wavechirp_tc.prm
    ELSE 
      ! Create input test file

      ! file names of starter/initial files 
      set testfile_usec_timeline "test_tlchecker_usec.tmp"
      set testfile_tc_timeline   "test_tlchecker_tc.tmp"
      res in testfile_tc_timeline

      ! make all the expected calculations and generate the initial files
      res Z:alwaysRefreshFiles true ! SET TO FALSE ONCE FILE CLEANUP IS WORKING
      call setupForTimelinePropagationTest "^testfile_usec_timeline" "^testfile_tc_timeline" alwaysRefreshFiles 128 38400
    ENDIF
  ENDIF

  status ^in XDELTA=file_xdelta YDELTA=file_ydelta TIMECODE=file_timecode TYPE=file_type 
  key ^in GET TC_PREC file_tcprec
  call getStartTimeFromInFile

  invoke columnnames nxm.sys.intr.Timelineisvalid.getCSVColumnNames()

  nxm.sys.intr.Timelineisvalid IN=^in OUT=^out CSVOUT=^csvout REPORT=^report RESULT=TL_VALID

  IF TL_VALID THEN
    res actual_color GREEN
    res instr_1st "Your file PASSED the Timelineisvalid check"
  ELSE
    res actual_color RED
    res instr_1st "Your file FAILED the Timelineisvalid check"
  ENDIF

  res elem_vs_time_quals {HEADERROWS=L:1,^columnnames,LAYER={LT="T5",DATATYPE="XYZ",Y="TIME",X="ELEM",Z="ENTRY",LABEL="TIMESTR",&
                          METADATAFIELDS="EXP_TIMESTR|ENTRY",AutoselectEnable=CLICK,AutoSelectMode=PIXEL,LINE={COLOR=^actual_color},SELECTCOLOR={COLOR="red",TYPE="symbol"}}}
  res ent_vs_off_quals {HEADERROWS=L:1,^columnnames,LAYER={LT="T5",DATATYPE="XYZ",Y="ENTRY",X="ELEM",Z="TIME",LABEL="TIMESTR",&
                          METADATAFIELDS="TIMESTR|EXP_TIMESTR",AutoselectEnable=CLICK,AutoSelectMode=PIXEL,LINE={COLOR=^actual_color},SELECTCOLOR={COLOR="red",TYPE="symbol"}}}
  res actTDelta_quals {HEADERROWS=L:1,^columnnames,TAG=ACTTDELTA,LAYER={NAME="ACTTDELTA",LT="T5",DATATYPE="XYZ",Y="ACT_TDELTA",X="ELEM",Z="TIME",LABEL="ACT_TDELTA",&
                          METADATAFIELDS="TIMESTR|ENTRY",AutoselectEnable=CLICK,AutoSelectMode=PIXEL,LINE={COLOR=^actual_color},SELECTCOLOR={COLOR="red",TYPE="symbol"}}}
  res fileTDelta_quals {HEADERROWS=L:1,^columnnames,TAG=FILETDELTA,LAYER={NAME="FILETDELTA",LT="T5",DATATYPE="XYZ",Y="FILE_TDELTA",X="ELEM",Z="TIME",LABEL="FILE_TDELTA",&
                          METADATAFIELDS="EXP_TIMESTR|ENTRY",AutoselectEnable=CLICK,AutoSelectMode=PIXEL,LINE={COLOR=BLUE},SELECTCOLOR={COLOR="blue",TYPE="symbol"}}}
  res expTime_quals {HEADERROWS=L:1,^columnnames,TAG=EXPTIME,LAYER={NAME=EXPTIME,LT="T5",DATATYPE="XYZ",Y="EXP_TIME",X="ELEM",Z="ENTRY",&
                          METADATAFIELDS="TOLR|ENTRY",AutoselectEnable=CLICK,AutoSelectMode=PIXEL,LINE={COLOR=BLUE},SELECTCOLOR={COLOR="red",TYPE="symbol"}}}
  res actTime_quals {HEADERROWS=L:1,^columnnames,TAG=ACTTIME,LAYER={NAME=ACTTIME,LT="T5",DATATYPE="XYZ",Y="TIME",X="ELEM",Z="ENTRY",&
                          METADATAFIELDS="EXP_TIMESTR|ENTRY",AutoselectEnable=CLICK,AutoSelectMode=PIXEL,LINE={COLOR=^actual_color},SELECTCOLOR={COLOR="blue",TYPE="symbol"}}}

  if interAct then
    set instructions "^instr_1st\n\n&
                      *************************************************\n&
                      ********** Left Side contains 2D Plots **********\n&
                      *************************************************\n&
                      All plots should start with X=element=1 (far left)\n&
                      If not, the timeline has likely wrapped\n\n&
                      All plots should have their Y values increase as element increases\n\n&
                      1) TIME hack value vs Data ELEMENT plot\n\n&
                      2) Time hack ENTRY vs Data ELEMENT plot\n\n&
                      3) TDELTA vs Data ELEMENT\n   &
                         BLUE points - File tdelta\n   &
                         ^actual_color points - effective tdelta since last hack\n\n&
                      4) TIME vs Data ELEMENT plot\n   &
                         BLUE points - anticipated time, based on last hack\n                 &
                                       and file tdelta\n   &
                         ^actual_color points - time hack times\n   &
                         Note: A high level of zooming is normally required\n   &
                         to distinguish actual from expected.\n\n&
                      *************************************************\n&
                      ********** Right Side contains 3D Plot **********\n&
                      *************************************************\n&
                      This plot should also start on the far left and have all values increasing\n\n&
                      XYZ graph of BLUE TC TIMELINE VALUES\n\n&
                      Z axis - TC SAMPLE #\n&
                      Y axis - ELEMENT #\n&
                      X axis - TIME\n\n&
                      ZOOM in AND Cntrl-LMB on lowest sample\n\n&
                      A valid Timeline would have Y of 1 for Z of 1\n\n&
                      File specs:\n&
                      XDELTA     - ^{file_xdelta}\n&
                      YDELTA     - ^{file_ydelta}\n&
                      Start Time - ^{str_starttime}\n&
                      TC_PREC    - ^{file_tcprec}"
    pipe on

      panel/msgid=MAIN/setup/controls=gc
      gcontrol label macro "Test MACRO"
      gcontrol menu  main "Exit with Status =" "PASS,FAIL" TABLE={ItemColors={PASS="GREEN",FAIL="RED"}} /tleft

      gcontrol text  idtext "Instructions" instructions 24 48 /title
      plot/id=3dplot ^out{Layer={LT=T5,DATATYPE="XYZ",METADATAFIELDS="EXP_TIMESTR|ELEM|ENTRY",AutoselectEnable=CLICK,AutoSelectMode=PIXEL,LINE={COLOR=^actual_color},SELECTCOLOR=AQUA,AutoSelectMode=PIXEL,SELECTCOLOR=AQUA}} view=3d xlabel=TIME_(X) ylabel=ELEMENT_(Y) zlabel=SAMPLE_(Z)
      plot/id=eltimeplot ^csvout^elem_vs_time_quals /READOUT=+ONAXIS xlabel=ELEMENT ylabel=TIME X1=1
      plot/id=entOffPlot ^csvout^ent_vs_off_quals /READOUT=+ONAXIS xlabel=ELEMENT ylabel=ENTRY  X1=1
      plot/id=tDeltaPlot ^csvout^fileTDelta_quals|^csvout^actTDelta_quals /READOUT=+ONAXIS xlabel=ELEMENT ylabel=TDELTA X1=1
      plot/id=timePlot ^csvout^expTime_quals|^csvout^actTime_quals /READOUT=+ONAXIS xlabel=ELEMENT ylabel=TIME X1=1
    pipe off

  endif
  
  call cleanupTimeCodeVisualFiles
endmacro

!******************************************************************************!
! Main process message for this macro. Should be right after the ENDMACRO.
!******************************************************************************!
procedure processMessage m:msg
  if msg.name eqs "MAIN" then
    if TL_VALID isFALSE then
      info "Input File did NOT pass BLUE TC KEYWORD validation"
    else
      info "Input File PASSED BLUE TC KEYWORD validation"
    endif
    assert/text="^reg.main.name: User indicated tests" msg.data eqss "PASS"
    pipe stop
  else
    say "Unhandled message name: ^msg.name from fid: ^msg.fid data: ^msg.data"
  endif
return

!******************************************************************************!
! If an unexpected exception is caught, mark test as failed, unless it is expected
!******************************************************************************!
procedure processException m:emsg
  if expectedException REXISTS then
    assert/text="^reg.main.name: Expected ERROR starts with: ^{expectedException}" expectedException EQSS emsg.data.message
    remove expectedException
  else
    assert/text="^reg.main.name: Caught unexpected exception ^{emsg.data}" "FALSE" isTrue
    if "Trace" SUBS ENV.DEBUG then invoke ,, emsg.data.printStackTrace()
  endif
return

!******************************************************************************!
! Get start time
!******************************************************************************!
procedure getStartTimeFromInFile
  key ^in GET TIMELINE value_timeline TCSAMPLE_1 element_tc TC_WHOLE_1 tcwhole TC_FRAC_1 tcfrac

  if element_tc NISNULL THEN
    if element_tc EQ 1 THEN
      new nxm.sys.lib.Time(^tcwhole,^tcfrac) time_starttime
    else
      new nxm.sys.lib.Time(0) time_starttime
    endif
  elseif value_timeline NISNULL THEN
    if value_timeline.2 EQ 0 THEN
      res time_from_timeline value_timeline.3
      new nxm.sys.lib.Time(time_from_timeline) time_starttime
    else
      new nxm.sys.lib.Time(0) time_starttime
    endif
  else
    status ^in TIMECODE=file_timecode
    new nxm.sys.lib.Time(file_timecode) time_starttime
  endif
  invoke str_starttime time_starttime.toString(9)

return

!******************************************************************************!
! Create a new table with the specified entry removed from the original
! (Note: we can not access the Table's remove method directly from the macro language)
!
!******************************************************************************!
procedure tableRemoveEntry T:origtable S:keyToDelete T:newtable

  foreach S:key INTABLE origtable
    if key NEQS keyToDelete then
      TABLE newtable SETKEY ^key origtable.^key
    endif
  endfor

return

!******************************************************************************!
! Cleanup files generated, unless we are keeping them for reference
!******************************************************************************!
procedure cleanupTimeCodeVisualFiles

    ! cleanup test files (if user did not added switch to keep test files)
    if keep isFalse then
      IF testfile_usec_timeline FEXISTS THEN ERASE testfile_usec_timeline
      IF testfile_tc_timeline   FEXISTS THEN ERASE testfile_tc_timeline
    else
      info "Not erasing these files: ^{testfile_usec_timeline},^{testfile_tc_timeline}
    endif
return

!******************************************************************************!
! Include procedures common to test_timeline_propagation test:
! setupForTimelinePropagationTest and checkTablesSame
!******************************************************************************!
include test_timeline_propagation.inc

