!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubetools_setup_types
  use cubetools_parameters
  use cubetools_datasize
  !
  private
  ! These should be private when all the get/set API is implemented:
  public :: cube_setup_buffer_t
  public :: cube_setup_output_t
  public :: cube_setup_t
  ! Public set/get API
  public :: cube_setup_api_t
  !
  ! --- Setup flags ----------------------------------------------------
  ! This structure holds all the setup flags. It should be entirely
  ! private at some point, only the public API should be used.
  !
  ! Support for SETUP\BLANKING
  type :: cube_setup_blanking_t
    integer(kind=4) :: rmode = code_patchblank_otf  ! Read mode
  end type cube_setup_blanking_t
  !
  ! Support for SETUP\BUFFER
  type :: cube_setup_buffer_t
    integer(kind=code_k) :: input  = code_buffer_memory
    integer(kind=code_k) :: output = code_buffer_memory
    real(kind=size_k)    :: limit  =  2.0*GiB  ! [Bytes]
    real(kind=size_k)    :: block  = 512.*MiB  ! [Bytes] Default block size (disk mode)
    real(kind=size_k)    :: task   = 256.*kiB  ! [Bytes] Default task size (1 plane of 250x250 pixels)
  end type cube_setup_buffer_t
  !
  ! Support for SETUP\OUTPUT (cubes customization)
  type :: cube_setup_output_t
    logical          :: extrema = .true.    ! Compute and update the extrema section
    logical          :: write = .true.      ! Write the file on disk?
    logical, private :: radio2sfl = .true.  ! Convert radio to SFL projection at export time?
  end type cube_setup_output_t
  !
  ! Support for SETUP\TIMING
  type :: cube_setup_timing_t
    logical, private :: io = .false.       ! IO timing feedback
    logical, private :: command = .false.  ! Command timing feedback
  end type cube_setup_timing_t
  !
  ! Support for SETUP\INDEX
  type :: cube_setup_index_t
    integer(kind=code_k), private :: default=code_index_dag
  end type cube_setup_index_t
  !
  type :: cube_setup_t
    type(cube_setup_blanking_t)        :: blanking
    type(cube_setup_buffer_t)          :: buff
    type(cube_setup_index_t),  private :: index
    type(cube_setup_output_t)          :: output
    type(cube_setup_timing_t), private :: timing
  end type cube_setup_t
  !
  ! Internal setup flags, read and written only with the public API
  type(cube_setup_t), private :: setup
  !
  ! --- Public API -----------------------------------------------------
  ! ZZZ To be done for all components. Should consider a set/get class?
  !
  ! --- OUTPUT ---------------------------------------------------------
  type :: cube_setup_output_radio2sfl_api_t
  contains
    procedure, nopass, public :: set => setup_output_radio2sfl_set
    procedure, nopass, public :: get => setup_output_radio2sfl_get
  end type cube_setup_output_radio2sfl_api_t
  !
  type :: cube_setup_output_api_t
    type(cube_setup_output_radio2sfl_api_t), public :: radio2sfl
  contains
    procedure, nopass, public :: reset => setup_output_reset
  end type cube_setup_output_api_t
  !
  ! --- TIMING ---------------------------------------------------------
  type :: cube_setup_timing_io_api_t
  contains
    procedure, nopass, public :: set => setup_timing_io_set
    procedure, nopass, public :: get => setup_timing_io_get
  end type cube_setup_timing_io_api_t
  type :: cube_setup_timing_command_api_t
  contains
    procedure, nopass, public :: set => setup_timing_command_set
    procedure, nopass, public :: get => setup_timing_command_get
  end type cube_setup_timing_command_api_t
  !
  type :: cube_setup_timing_api_t
    type(cube_setup_timing_io_api_t),      public :: io
    type(cube_setup_timing_command_api_t), public :: command
  contains
    procedure, nopass, public :: reset => setup_timing_reset
  end type cube_setup_timing_api_t
  !
  ! --- INDEX ----------------------------------------------------------
  type :: cube_setup_index_default_api_t
  contains
    procedure, nopass, public :: set => setup_index_default_set
    procedure, nopass, public :: get => setup_index_default_get
  end type cube_setup_index_default_api_t
  !
  type :: cube_setup_index_api_t
    type(cube_setup_index_default_api_t), public :: default
  contains
    procedure, nopass, public :: reset => setup_index_reset
  end type cube_setup_index_api_t
  !
  ! --- Public API -----------------------------------------------------
  type :: cube_setup_api_t
    type(cube_setup_output_api_t), public :: output
    type(cube_setup_timing_api_t), public :: timing
    type(cube_setup_index_api_t),  public :: index
  end type cube_setup_api_t
  !
contains
  !
  ! --- OUTPUT ---------------------------------------------------------
  subroutine setup_output_radio2sfl_set(val,error)
    logical, intent(in)    :: val
    logical, intent(inout) :: error
    setup%output%radio2sfl = val
  end subroutine setup_output_radio2sfl_set
  subroutine setup_output_radio2sfl_get(val)
    logical, intent(out) :: val
    val = setup%output%radio2sfl
  end subroutine setup_output_radio2sfl_get
  !
  subroutine setup_output_reset()
    type(cube_setup_output_t) :: default
    setup%output = default
  end subroutine setup_output_reset
  !
  ! --- TIMING ---------------------------------------------------------
  subroutine setup_timing_io_set(val,error)
    logical, intent(in)    :: val
    logical, intent(inout) :: error
    setup%timing%io = val
  end subroutine setup_timing_io_set
  subroutine setup_timing_io_get(val)
    logical, intent(out) :: val
    val = setup%timing%io
  end subroutine setup_timing_io_get
  !
  subroutine setup_timing_command_set(val,error)
    logical, intent(in)    :: val
    logical, intent(inout) :: error
    setup%timing%command = val
  end subroutine setup_timing_command_set
  subroutine setup_timing_command_get(val)
    logical, intent(out) :: val
    val = setup%timing%command
  end subroutine setup_timing_command_get
  !
  subroutine setup_timing_reset()
    type(cube_setup_timing_t) :: default
    setup%timing = default
  end subroutine setup_timing_reset
  !
  ! --- INDEX ----------------------------------------------------------
  subroutine setup_index_default_set(val,error)
    integer(kind=code_k), intent(in)    :: val
    logical,              intent(inout) :: error
    setup%index%default = val
  end subroutine setup_index_default_set
  subroutine setup_index_default_get(val)
    integer(kind=code_k), intent(out) :: val
    val = setup%index%default
  end subroutine setup_index_default_get
  !
  subroutine setup_index_reset()
    type(cube_setup_index_t) :: default
    setup%index = default
  end subroutine setup_index_reset
  !
end module cubetools_setup_types
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
