! xfltr.def [100] - definitions and instructions for XFILTR.SBX
!------------------------------------------------------------------------
!EDIT HISTORY
!Version 1.0:-
! [100] 27-Dec-17 / jdm / created
!------------------------------------------------------------------------
!REQUIREMENTS
!   A-Shell 6.2 (for DIMX pass by reference)
!NOTES
!   Must be ++included in programs XCALLing XFILTR
!
!   XFILTR.SBX implements a general-purpose XTREE dialog via which 
!   a non-technical user can filter records from a file/table by selecting 
!   fields from a drop-down list, along with suitable comparison operators, 
!   operands and logical conjunctions.  Calling program provides the array of 
!   fields and field/comparison types.  SBX sends back an array of 
!   <field> <comparison operator> <value> <and/or> element. The actual
!   filtering of the data is left to the caller.
!
!   (The SBX is purely "presentation" - it has no knowledge of actual data or
!   business logic. Even though the paradigm seems to be fields within a table/file, 
!   it could be any collection of named values that is meaningful to the 
!   calling program and the user.)
!
!CALLING SYNTAX
!   xcall XFILTR, TITLE$, FSETUP(), FSELECT(), STATUS, FLAGS
!where
!   TITLE$    - (str) [in] - dialog title
!   FSETUP()  - (ST_XFILTR_SETUP) [in/byref] - array of fields & selection info (see def)
!   FSELECT() - (ST_XFILTR_SELECT) [out/byref] - array of filter criterial passed back (see def)
!   STATUS    - 0=ok, -1=cancel, -2=help, -99=environment not sufficient
!   FLAGS     - (num) [in] - option flags (to be defined)
!
!CALLING PROGRAM USAGE
!   The calling program needs to define auto_extending dimx arrays for
!   the fsetup() and fselect() parameters:
!
!       dimx fsetup(0), ST_XFILTR_SETUP, auto_extend
!       dimx fselect(0), ST_FILTR_SELECT, auto_extend
!
!   Then it must fill out the fsetup() array with the fields that 
!   will be available for selection. The program has the option of
!   using separate field display names and internal field identifiers
!   or can ignore the internal identifiers and use the same strings
!   for both. (Blank fldid$ members will be automatically set to match
!   the fldnam$ member.)
!
!       fsetup(1).fldnam$ = "Customer Name"  : fsetup(1).type = XFLTR_GEN
!       fsetup(2).fldnam$ = "Credit Limit"   : fsetup(2).type = XFLTR_NUM
!       fsetup(3).fldnam$ = "Last Sale Date" : fsetup(3).type = XFLTR_DATE
!       ...
!       xcall XFILTR, "Filter Customers", fsetup(), fselect(), status
!
!   On return, status will be set to indicate ok, cancel, help, etc.
!   In the OK case, you would then use the fselect() array to process
!   the filtering parameters input by the user...
!
!       strsiz ST_XFLTR_SELECT.fldid$              ! (needed for switch below)
!       if status # 0 then                      ! cancel, help, error, etc
!           <handle non-ok cases>
!       endif
!
!       do while <records left to be processed>     ! scan the raw data
!           <load record into local storage, e.g. cusrec>
!           ! apply filter logic to record
!           bselect = .TRUE                     ! start assuming record meets criteria               
!           for i = 1 to .extent(fselect())     ! iterate thru filter clauses
!               switch fselect(i).fldid$           ! process selection logic
!                   case "Customer Name"        
!                       fldval$ = cusrec.name   ! data to compare
!                       exit
!                   case "Credit Limit"
!                       fldval$ = cusrec.crlimit
!                       exit
!                   case "Last Sale Date"
!                       fldval$ = cusrec.lastsale$   ! (normalize to CCYYMMDD?)
!                       exit
!                   ...
!               endswitch
!
!               ! pass field, comparison value and operator to general purpose function
!               bselect = fn'filter(fldval$,fselect(i).comval$,fselect(i).comop)
!               if not bselect then
!                   if fselect(i).logop$ # "or" then
!                       exit
!                   endif
!               endif
!           next i
!
!           if bselect then
!               <record survived filtering - add to report>
!           endif
!       loop        ! repeat for next rec
!

!------------------------------------------------------------------------

! define field/selection type codes
define XFLTR_GEN  = 0             ! generic value (string or number)
define XFLTR_NUM  = 1             ! generic number
define XFLTR_DATE = 2             ! date
define XFLTR_TIME = 3             ! time

! define size of certain fields in the arrays that we might want to adjust with coordination
define XFLTR_NAME_LEN   = 24      ! length of name and id fields
define XFLTR_COMOP_LEN  = 10      ! length of comparison operator field
define XFLTR_VAL_LEN    = 50      ! length of comparison value field

! setup array - to be filled out by caller and passed to XFILTR.SBX (dimx byref)
defstruct ST_XFILTR_SETUP         ! filter setup (to configure the dialog)
    map2 fldnam$,s,XFLTR_NAME_LEN   ! field name (displayed to user)
    map2 fldid$,s,XFLTR_NAME_LEN     ! field id (optional internal id)
    map2 type,b,2                 ! 0)gen string, 1)gen num, 2)date, 3)time, ...
    map2 options,b,2              ! selection options (not yet defined)
endstruct

! selection array - filled out by XFILTR.SBX, passed back to caller (dimx byref)
defstruct ST_XFILTR_SELECT        ! selection criteria passed back to caller)
    map2 fldid$,s,XFLTR_NAME_LEN     ! field # (from ST_XFILTR_SETUP)
    map2 type,b,2                 ! field/sel type (copied from ST_XFILTR_SETUP for convenience)
    map2 comop$,s,XFLTR_COMOP_LEN ! comparison operator: =,<,<=,>,>=,contains,in,...   
    map2 comval$,s,XFLTR_VAL_LEN  ! comparison value: value/list to compare against
    map2 logop$,s,3               ! and/or/end
endstruct

!example allocation of the setup and select arrays:
!   dimx fsetup(0),  ST_XFILTR_SETUP, auto_extend
!   dimx fselect(0), ST_XFILTR_SELECT, auto_extend