!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubeset_spatial
  use cubetools_structure
  use cubemain_spapos_types
  use cubemain_spasize_types
  use cubemain_spasamp_types
  use cubeset_messaging
  !
  public :: spatial,cubeset_spatial_register
  public :: userspa
  private
  !
  type :: spatial_comm_t
     type(option_t), pointer :: comm
     type(option_t), pointer :: defaults 
     type(spapos_opt_t)      :: center
     type(spasize_opt_t)     :: size
     type(spasamp_opt_t)     :: sampling
   contains
     procedure, public  :: register => cubeset_spatial_register
     procedure, private :: parse    => cubeset_spatial_parse
  end type spatial_comm_t
  type(spatial_comm_t) :: spatial
  !
  type spatial_user_t
     type(spapos_user_t)  :: center
     type(spasize_user_t) :: size
     type(spasamp_user_t) :: sampling
     logical              :: dolist     = .false.
     logical              :: dodefaults = .false.
   contains
     procedure :: init          => cubeset_spatial_user_init
     ! procedure :: def_substruct => cubeset_spatial_user_def_substruct
     procedure :: toprog        => cubeset_spatial_user_toprog
     procedure :: list          => cubeset_spatial_user_list
  end type spatial_user_t
  type(spatial_user_t) :: userspa
  !
contains
  !
  subroutine cubeset_spatial_command(line,error)
    !-------------------------------------------------------------------
    ! Support routine for command SPATIAL
    !-------------------------------------------------------------------
    character(len=*), intent(in)    :: line
    logical,          intent(inout) :: error
    !
    character(len=*), parameter :: rname='SPATIAL>COMMAND'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call spatial%parse(line,error)
    if (error) return
    if (userspa%dodefaults) then
       call userspa%init(error)
       if (error) return
    else
       ! Do nothing
    endif
    if (userspa%dolist) then
       call userspa%list(error)
       if (error) return
    else
       ! Do nothing
    endif
  end subroutine cubeset_spatial_command
  !
  !----------------------------------------------------------------------
  !
  subroutine cubeset_spatial_register(spatial,error)
    use cubetools_parameters
    !-------------------------------------------------------------------
    ! Support routine for register SPATIAL
    !-------------------------------------------------------------------
    class(spatial_comm_t), intent(inout) :: spatial
    logical,               intent(inout) :: error
    !
    character(len=*), parameter :: comm_abstract = &
         'Set the spatial region of interest'
    character(len=*), parameter :: comm_help = &
         strg_id
    character(len=*), parameter :: rname='SPATIAL>REGISTER'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call cubetools_register_command(&
         'SPATIAL','',&
         comm_abstract,&
         comm_help,&
         cubeset_spatial_command,&
         spatial%comm,error)
    if (error) return
    !  
    call spatial%center%register(&
         'CENTER',&
         'Set the center of the spatial region of interest',&
         error)
    if (error) return
    !
    call spatial%size%register(&
         'Set the size of the spatial region of interest',&
         error)
    if (error) return
    !
    call spatial%sampling%register(&
         'SAMPLING',&
         'Set the sampling between spectra',&
         error)
    if (error) return
    !
    call cubetools_register_option(&
         'DEFAULTS','',&
         'Reset SPATIAL defaults',&
         strg_id,&
         spatial%defaults,error)
    if (error) return
  end subroutine cubeset_spatial_register
  !
  subroutine cubeset_spatial_parse(spatial,line,error)
    !-------------------------------------------------------------------
    ! SPATIAL
    ! /DEFAULTS
    ! /SIZE sx [sy [unit]]
    ! /CENTER cx cy [unit]
    !-------------------------------------------------------------------
    class(spatial_comm_t), intent(in)    :: spatial
    character(len=*),      intent(in)    :: line
    logical,               intent(inout) :: error
    !
    character(len=*), parameter :: rname='SPATIAL>PARSE'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    if (cubetools_nopt().eq.0) then
       userspa%dolist = .true.
    else
       userspa%dolist = .false.
       call spatial%defaults%present(line,userspa%dodefaults,error)
       if (error) return
       call spatial%center%parse(line,userspa%center,error)
       if (error) return
       call spatial%size%parse(line,userspa%size,error)
       if (error) return
       call spatial%sampling%parse(line,userspa%sampling,error)
       if (error) return
    endif
  end subroutine cubeset_spatial_parse
  !
  !----------------------------------------------------------------------
  !
  subroutine cubeset_spatial_user_init(user,error)
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(spatial_user_t), intent(inout) :: user
    logical,               intent(inout) :: error
    !
    character(len=*), parameter :: rname='SPATIAL>USER>INIT'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call user%center%init(error)
    if (error) return
    call user%size%init(error)
    if (error) return
    call user%sampling%init(error)
    if (error) return
  end subroutine cubeset_spatial_user_init
  !
  ! subroutine cubeset_spatial_user_def_substruct(user,struct,error)
  !   use cubetools_userstruct
  !   !-------------------------------------------------------------------
  !   ! 
  !   !-------------------------------------------------------------------
  !   class(spatial_user_t), intent(in)    :: user
  !   type(userstruct_t),    intent(inout) :: struct
  !   logical,               intent(inout) :: error
  !   !
  !   type(userstruct_t) :: substruct
  !   character(len=*), parameter :: rname='SPATIAL>USER>DEF>SUBSTRUCT'
  !   !
  !   call cubeset_message(setseve%trace,rname,'Welcome')
  !   !    
  !   ! *** JP What happens if the sub-structure already exists?
  !   call struct%def_substruct('spatial',substruct,error)
  !   if (error) return
  !   call user%center%def_substruct(substruct,error)
  !   if (error) return
  !   call user%size%def_substruct(substruct,error)
  !   if (error) return    
  !   call user%sampling%def_substruct(substruct,error)
  !   if (error) return
  ! end subroutine cubeset_spatial_user_def_substruct
  !
  subroutine cubeset_spatial_user_toprog(user,cube,xrange,yrange,error)
    use cube_types
    use cubetools_parameters
    use cubemain_sparange_types
    !-------------------------------------------------------------------
    ! 
    !-------------------------------------------------------------------
    class(spatial_user_t), intent(inout) :: user
    type(cube_t), pointer, intent(in)    :: cube
    type(sparange_prog_t), intent(out)   :: xrange
    type(sparange_prog_t), intent(out)   :: yrange
    logical,               intent(inout) :: error
    !
    integer(kind=ndim_k), parameter :: ix = 1
    integer(kind=ndim_k), parameter :: iy = 2
    type(spapos_prog_t) :: center
    type(spasamp_prog_t) :: sampling
    character(len=*), parameter :: rname='SPATIAL>USER>TOPROG'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call user%center%toprog(cube,center,error)
    if (error) return
    call user%sampling%toprog(cube,sampling,error)
    if (error) return
    call xrange%fromuser(cube%head%set%il,cube,center%rela(ix),&
         userspa%size%x,userspa%size%unit,sampling%x,sampling%unit,error)
    if (error) return
    call yrange%fromuser(cube%head%set%im,cube,center%rela(iy),&
         userspa%size%y,userspa%size%unit,sampling%y,sampling%unit,error)
    if (error) return
  end subroutine cubeset_spatial_user_toprog
  !
  subroutine cubeset_spatial_user_list(user,error)
    use cubetools_parameters    
    !-------------------------------------------------------------------
    ! List
    !-------------------------------------------------------------------
    class(spatial_user_t), intent(in)    :: user
    logical,               intent(inout) :: error
    !
    character(len=*), parameter :: rname='SPATIAL>USER>LIST'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call cubeset_message(seve%r,rname,blankstr)    
    call user%center%list(error)
    if (error) return    
    call user%size%list(error)
    if (error) return
    call user%sampling%list(error)
    if (error) return
    call cubeset_message(seve%r,rname,blankstr)
  end subroutine cubeset_spatial_user_list
end module cubeset_spatial
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
