!******************************************************************************!
! Tests for LIST2 command. Focuses on adding/removing/updating rows in LIST2.
!
! Author : J. Czechowski IV / Neon Ngo
!******************************************************************************!
startmacro/tsetup=nxm.sys.test.test_list2_setup.tbl
  switch INTERACTIVE interAct   GET DEF=TRUE SDEF=TRUE  ! for normal interactive test(s)
  switch standalone  standalone GET DEF=TRUE SDEF=TRUE
  switch COREGRAPHICS coregraphics GET DEF=FALSE SDEF=TRUE  ! for a quick check of graphics - more extreme tests - since 3.8.1

  call setDatDir

  set rowData {absc=1000,ord=0,ord2=0,ord3=0}
  set addCount 0
  set updateAbsc 1000
  set updateOrd 10

  if interAct OR coreGraphics then
    res template1000 {F1={type="NUMBER",format="0.000",width=10}}
    res template2000 {F1={type="NUMBER",format="0.000",width=10},&
                      F2={type="NUMBER",format="0.000",width=10}}

    res template3000 {}
    res template3000._GLOBAL_ {TYPE="LIST2",AUTOHIDE="TRUE",AUTOORDER="TRUE",adjSelCells="ON"}
    res template3000.absc {type="NUMBER",format="#",width=10}
    res template3000.ord  {type="NUMBER",format="#",width=10}
    res template3000.ord2 {type="NUMBER",format="#",width=10}
    res template3000.ord3 {type="NUMBER",format="#",width=10}

    res template6000 {}

    set testFileTab  {1000=ram:test1000,2000=ram:test2000,3000=^{datDir}.testxy3000.prm,6000=^{datDir}.test6000.prm}
    set testTemplTab {1000=^{template1000},2000=^{template2000},3000=^{template3000},6000=^{template6000}}
    waveform testFileTab.1000 ELEM=10
    waveform testFileTab.2000 ELEM=20
    headermod testFileTab.2000 FS=2

    set testTab {}
    set testTab.1000 "AddToEnd,RemoveRow1"
    set testTab.2000 "AddToEnd,RemoveRow1"
    set testTab.3000 "AddToEnd,AddRow1,AddRow20,UpdateRow,SelectRows,RemoveRow1,RemoveRow20,&
                      Remove ORD=15,RemoveRows3to9,RemoveRows3and5,SelectCells,RemoveRow1,RemoveAll"
    set testTab.6000 "AddToEnd,RemoveRow1,BUG 1992"

    pipe init
      panel/msgid=MAIN/controls=gc
      list2/grid=on/msgid=MAIN/id=idlist testFileTab.3000 testTemplTab.3000
      if standalone isTrue then
        gcontrol label  macro   "MACRO"
        gcontrol menu MAIN "Exit with Status = " "PASS,FAIL" /tleft
        set gc.MAIN.itemColors {PASS=GREEN,FAIL=RED}
      endif
      res instructions " Do the buttons in order and observe results.\n&
                         Do tests for type 3000 then for type 1000, 2000 and 6000."
      gcontrol text idtext "Instructions" "^instructions" 24 12 /title

      gcontrol label  listTest   "List Test" AlwaysOpen
      gcontrol/nc=2 menu testFileType "File Type" "1000,2000,3000,6000" 3000 /tleft
      gcontrol/nc=2 button test "Task" "^testTab.3000" none
      !gcontrol lval updateAbsc "UpdateAbsc" 1000 0 10000 1 /nomsg
      !gcontrol lval updateOrd  "UpdateOrd "   10 0  1000 1 /nomsg

      invoke ,, reg.idlist.setPrimaryKey(ABSC)

    pipe off

  endif
endmacro

!******************************************************************************!
! Procedure for handling all messages
!******************************************************************************!
procedure processMessage m:msg
  if msg.name EQS "MAIN" then
    if msg.data EQS "EXIT" then
      pipe stop
    else
      assert/text="^reg.main.name: User indicated tests" msg.data eqss "PASS"
      pipe stop
    endif
  elseif msg.fid EQS "IDLIST" then
    !say "Got ^msg.name from ^msg.fid"

  elseif msg.name EQS "TESTFILETYPE" then
    set gc.TEST.items "^testTab.^{msg.data}"
    set reg.IDLIST.openfile    "^{testFileTab.^{msg.data}}"
    set reg.IDLIST.settemplate "^{testTemplTab.^{msg.data}}"
    set gc.IDTEXT.value "Click on the buttons below to test the Type ^{msg.data}"

! TODO: is this case used? cleanup if not.
!  elseif msg.name eqs "SELROW" then
!    invoke ,, reg.idlist.selectRow(1,false)
!    invoke ,, reg.idlist.selectRow(3,false)
!    invoke ,, reg.idlist.selectRow(5,false)
! 2012-01-31 NTN: commented out this unused? scenario

  elseif msg.name EQS "TEST" then
    if msg.name EQS "TEST" AND msg.data EQS "REMOVEROW1" then
      ! RemoveRow1 is global test for all types of files
      set gc.IDTEXT.value "Is the first row removed in the LIST?"
      invoke ,, reg.idlist.removeRow(1)

    elseif gc.TESTFILETYPE.value EQ 3000 then
      call handleType3000Actions msg

    elseif gc.TESTFILETYPE.value EQ 1000 then
      call handleType1000Actions msg

    elseif gc.TESTFILETYPE.value EQ 2000 then
      call handleType2000Actions msg

    elseif gc.TESTFILETYPE.value EQ 6000 then
      call handleType6000Actions msg
    endif

  else
    say "Unhandled messagename: ^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

!******************************************************************************!
! Set the dat directory
!******************************************************************************!
procedure setDatDir
  invoke nxmMajor env.nmversion.subString(0,1)
  invoke major java.lang.Integer.valueOf(nxmMajor)
  if major GE 4 then
    invoke s:datDir           nxm.sys.test.DatLocator.getDatDirLocation()
    invoke s:datDirSlash      nxm.sys.test.DatLocator.getDatDirSlashLocation()
    invoke z:sysDatFull       nxm.sys.test.DatLocator.sysDatFull()
    invoke z:sysTestDatExists nxm.sys.test.DatLocator.sysTestDatExists()
  else
    set s:datDir           "nxm.sys.dat"
    set s:datDirSlash      "nxm/sys/dat"
    set z:sysDatFull       true
    set z:sysTestDatExists false
  endif
return

!******************************************************************************!
! test handling of type 1000 file tests
!******************************************************************************!
procedure handleType1000Actions O:msg
  if msg.data EQS "ADDTOEND" then
    calc addCount addCount 1 +
    set gc.IDTEXT.value "Is the last row in the LIST ^{addCount}?"
    set reg.IDLIST.addrow {F1=^addCount}

  endif
return

!******************************************************************************!
! test handling of type 2000 file tests
!******************************************************************************!
procedure handleType2000Actions O:msg
  if msg.data EQS "ADDTOEND" then
    calc addCount addCount 1 +
    set gc.IDTEXT.value "Is the last row in the LIST F1=^{addCount}, F2=2.222?"
    set reg.IDLIST.addrow {F1=^addCount,F2=2.222}

  endif
return

!******************************************************************************!
! test handling of type 3000 file tests
!******************************************************************************!
procedure handleType3000Actions O:msg
  if msg.data EQS "ADDTOEND" then
    calc rowData.absc rowData.absc 1 +
    invoke ,, reg.idlist.addRow(rowData)
    set gc.IDTEXT.value "A row should be added to the bottom of the list with ABSC=^{rowData.absc}"

  elseif msg.data eqs "SELECTROWS" then
    invoke ,, reg.idlist.selectRow(1,false)
    invoke ,, reg.idlist.selectRow(3,false)
    invoke ,, reg.idlist.selectRow(5,false)
    set gc.IDTEXT.value "Rows 1, 3, and 5 should be selected.\n\n&
                         These rows should stay selected when adding and removing other rows."

  elseif msg.data eqs "SELECTCELLS" then
    ! make sure there at least 20 rows
    calc rowData.absc rowData.absc 1 +
    invoke ,, reg.idlist.addRow(20,rowData)
    invoke model reg.idlist.getTableSelectionModel()
    invoke ,, model.changeCellSelection(4,0,2,true)
    invoke ,, model.changeCellSelection(8,3,4,true)
    set gc.IDTEXT.value "Cells in rows 5 through 9 should be selected.\n\n&
                         These rows should stay selected when adding and removing other rows."

  elseif msg.data EQS "ADDROW1" then
    calc rowData.absc rowData.absc 1 +
    invoke ,, reg.idlist.addRow(1,rowData)
    set gc.IDTEXT.value "A new row 1 with ABSC=^{rowData.absc} should be added."

  elseif msg.data EQS "ADDROW20" then
    calc rowData.absc rowData.absc 1 +
    invoke ,, reg.idlist.addRow(20,rowData)
    set gc.IDTEXT.value "A new row 20 with ABSC=^{rowData.absc} should be added.\n\n&
                         If there were less than 19 rows, the 'gap' will be new rows with &
                         data values of all 0."

  elseif msg.data EQS "REMOVEROW20" then
    invoke ,, reg.idlist.removeRow(20)
    set gc.IDTEXT.value "Row 20 (if it existed) should be removed."

  elseif msg.data EQS "REMOVEROWS3TO9" then
    invoke ,, reg.idlist.removeRows(3,9)
    set gc.IDTEXT.value "Row 3 through 9 (if they existed) should be removed."

  elseif msg.data EQS "REMOVEROWS3AND5" then
    invoke ,, reg.idlist.removeRows("3,5")
    set gc.IDTEXT.value "Row 3 and 5 (if they existed) should be removed."

  elseif msg.data EQS "REMOVE ORD=15" then
    invoke ,, reg.idlist.setPrimaryKey("ORD")
    set t:tbl {ORD=15.0}
    invoke row reg.idlist.getRow(tbl)    !!! FOR BUG 1725
    if row ISNULL then
      ! do nothing
      set gc.IDTEXT.value "There was no ORD=15 row, so nothing should have happened."
    else
      invoke ,, reg.idlist.removeRow(row)
      set gc.IDTEXT.value "The row with ORD=15 should be removed.\n\n&
                           If there is more than one row with ORD=15, the first one will be removed."
    endif

  elseif msg.data EQS "REMOVEALL" then
    invoke ,, reg.idlist.removeAllRows()
    set gc.IDTEXT.value "All rows should be removed."

  elseif msg.data EQS "UPDATEROW" then
    set updateRow {}
    set updateRow.absc updateAbsc
    set updateRow.ord  updateOrd

    invoke ,, reg.idlist.updateRow(updateRow)
    set gc.IDTEXT.value "Any row with ABSC=^{updateAbsc} will get updated to ORD=^{updateOrd}.\n\n&
                         If row does not exist, a new row will be added with those values."

    calc updateAbsc updateAbsc 1 +
    calc updateOrd  updateOrd  1 +

  else
    warn "Unknown test ^msg.data"
  endif

  !set gc.IDTEXT.value "Does the LIST reflect the change? In the Type 3000 file, &
  !  selected rows and cells should adjust (keep the same data selected).\n&
  !  In other files, a selected row or cell does not adjust (the same row # stays selected)."
return

!******************************************************************************!
! test handling of type 6000 file initially for BUG 1992
!******************************************************************************!
procedure handleType6000Actions O:msg
  if msg.data EQS "ADDTOEND" then
    set gc.IDTEXT.value "Does the LIST reflect the change (new row appended, the &
                   CC should be incrementing by one from the last time this button was pressed)?"
    calc addCount addCount 1 +
    invoke ,, reg.idlist.addRow({F1="add",R1="toEnd",CC=^addCount,FF=921,GG="AddToEnd of LIST2 of type 6000"})

  elseif msg.data EQS "BUG 1992" then
    set gc.IDTEXT.value "1. Two row should be added to end of list.\n&
                         2. status of cached RAM file is automatically asserted (e.g. no errors in terminal).\n&
                         3. On the Save File dialogs select OK twice and there should be no errors in terminal."
    set nsr 0  ! reset results before test
    invoke ,, reg.idlist.addRow({F1="test1",R1="Bug 1992",CC=88,FF=321,GG="addRow to 6000 file, then status"})
    ! MUST call listfile.update() to ensure that extended headers are flush to disk for Type 6000 files after a list2.addRow(.) (#2 of BUG 1992)
    invoke ,, reg.idlist.listfile.update()
    status list2_temp_00 NumberSubRecords=nsr
    assert/text="^reg.main.name: status LIST2's temp/cached RAM file of type 6000 after addRow(.)" nsr ge 5

    ! need to add another row to end to make sure we overwrite extended header to test File -> Save Copy.. (#3 of BUG 1992)
    invoke ,, reg.idlist.addRow({F1="test2",R1="Bug 1992",CC=88,FF=321,GG="addRow, test File Menu -> Save Copy"})

    ! simulate MMB, File -> Save Copy... mouse actions for LIST2 to semi-automate last part of test case
    message send idlist ,, MENU ,, "FILE.SAVE_COPY"

  endif

return
