!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubeset_spectral
  use cubetools_parameters
  use cubetools_structure
  use cubetopology_speline_types
  use cubetopology_spevsys_types
  use cubetopology_sperange_types
  use cubeset_messaging
  !
  public :: spectral
  public :: userspe
  private
  !
  type :: spectral_comm_t
     type(option_t), pointer :: comm
     type(option_t), pointer :: defaults 
     type(speline_opt_t)     :: freq     
     type(spevsys_opt_t)     :: vsys
     type(sperange_opt_t)    :: range
   contains
     procedure, public  :: register => cubeset_spectral_register
     procedure, private :: parse    => cubeset_spectral_parse
  end type spectral_comm_t
  type(spectral_comm_t) :: spectral 
  !
  type spectral_user_t
     logical               :: dolist = .false.
     logical               :: dodefaults = .false.
     type(speline_user_t)  :: freq
     type(spevsys_user_t)  :: vsys
     type(sperange_user_t) :: range
   contains
     procedure :: init          => cubeset_spectral_user_init
     ! procedure :: def_substruct => cubeset_spectral_user_def_substruct
     procedure :: toprog        => cubeset_spectral_user_toprog
     procedure :: list          => cubeset_spectral_user_list
  end type spectral_user_t
  type(spectral_user_t) :: userspe
  !
contains
  !
  subroutine cubeset_spectral_command(line,error)
    !-------------------------------------------------------------------
    ! Support routine for command SPECTRAL
    !-------------------------------------------------------------------
    character(len=*), intent(in)    :: line
    logical,          intent(inout) :: error
    !
    character(len=*), parameter :: rname='SPECTRAL>COMMAND'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call spectral%parse(line,error)
    if (error) return
    if (userspe%dodefaults) then
       call userspe%init(error)
       if (error) return
    else
       ! Do nothing
    endif
    if (userspe%dolist) then
       call userspe%list(error)
       if (error) return
    else
       ! Do nothing
    endif
  end subroutine cubeset_spectral_command
  !
  !----------------------------------------------------------------------
  !
  subroutine cubeset_spectral_register(spectral,error)
    !-------------------------------------------------------------------
    ! Support routine for register SPECTRAL
    !-------------------------------------------------------------------
    class(spectral_comm_t), intent(inout) :: spectral
    logical,                intent(inout) :: error
    !
    character(len=*), parameter :: comm_abstract = &
         'Set the spectral region of interest'
    character(len=*), parameter :: comm_help = strg_id
    character(len=*), parameter :: rname='SPECTRAL>REGISTER'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call cubetools_register_command(&
         'SPECTRAL','',&
         comm_abstract,&
         comm_help,&
         cubeset_spectral_command,&
         spectral%comm,error)
    if (error) return
    !
    call spectral%range%register(&
         'RANGE',&
         'Set the velocity range of the spectral region of interest',&
         error)
    if (error) return
    !
    call spectral%freq%register(&
         'Set the line, frequency and unit for the region of interest',&
         error)
    if (error) return
    !
    call spectral%vsys%register(&
         'Set the systemic velocity for the region of interest',&
         error)
    if (error) return
    !
    call cubetools_register_option(&
         'DEFAULTS','',&
         'Reset SPECTRAL defaults',&
         strg_id,&
         spectral%defaults,error)
    if (error) return
  end subroutine cubeset_spectral_register
  !
  subroutine cubeset_spectral_parse(spectral,line,error)
    !-------------------------------------------------------------------
    ! SPECTRAL 
    ! /FREQUENCY line freq [unit]
    ! /VELOCITY vsys [unit]
    ! /RANGE first last [unit]
    ! /DEFAULTS
    !-------------------------------------------------------------------
    class(spectral_comm_t), intent(in)    :: spectral
    character(len=*),       intent(in)    :: line
    logical,                intent(inout) :: error
    !
    character(len=*), parameter :: rname='SPECTRAL>PARSE'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    if (cubetools_nopt().eq.0) then
       userspe%dolist = .true.
    else
       userspe%dolist = .false.
       call spectral%defaults%present(line,userspe%dodefaults,error)
       if (error) return
       call spectral%freq%parse(line,userspe%freq,error)
       if (error) return
       call spectral%vsys%parse(line,userspe%vsys,error)
       if (error) return
       call spectral%range%parse(line,userspe%range,error)
       if (error) return
    endif
  end subroutine cubeset_spectral_parse
  !
  !------------------------------------------------------------------------
  !
  subroutine cubeset_spectral_user_init(user,error)
    !----------------------------------------------------------------------
    ! 
    !----------------------------------------------------------------------
    class(spectral_user_t), intent(inout) :: user
    logical,                intent(inout) :: error
    !
    character(len=*), parameter :: rname='SPECTRAL>USER>INIT'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call user%freq%init(error)
    if (error) return
    call user%vsys%init(error)
    if (error) return
    call user%range%init(error)
    if (error) return
  end subroutine cubeset_spectral_user_init
  !
  ! subroutine cubeset_spectral_user_def_substruct(user,struct,error)
  !   use cubetools_userstruct
  !   !-------------------------------------------------------------------
  !   ! 
  !   !-------------------------------------------------------------------
  !   class(spectral_user_t), intent(in)    :: user
  !   type(userstruct_t),     intent(inout) :: struct
  !   logical,                intent(inout) :: error
  !   !
  !   type(userstruct_t) :: substruct
  !   character(len=*), parameter :: rname='SUBSTRUCT>USER>DEF>SUBSTRUCT'
  !   !
  !   call struct%def_substruct('spectral',substruct,error)
  !   if (error) return
  !   call user%freq%def_substruct(substruct,error)
  !   if (error) return
  !   call user%vsys%def_substruct(substruct,error)
  !   if (error) return
  !   call user%range%def_substruct(substruct,error)
  !   if (error) return
  ! end subroutine cubeset_spectral_user_def_substruct
  !
  subroutine cubeset_spectral_user_toprog(user,cube,truncate_mode,freq,vsys,range,error)
    use cube_types
    !----------------------------------------------------------------------
    ! Resolve
    !----------------------------------------------------------------------
    class(spectral_user_t), intent(inout) :: user
    type(cube_t), pointer,  intent(in)    :: cube
    integer(kind=code_k),   intent(in)    :: truncate_mode
    type(speline_prog_t),   intent(out)   :: freq
    type(spevsys_prog_t),   intent(out)   :: vsys
    type(sperange_prog_t),  intent(out)   :: range
    logical,                intent(inout) :: error
    !
    character(len=*), parameter :: rname='SPECTRAL>USER>TOPROG'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call user%freq%toprog(cube,freq,error)
    if (error) return
    call user%vsys%toprog(cube,vsys,error)
    if (error) return
    call user%range%toprog(cube,truncate_mode,range,error)
    if (error) return
  end subroutine cubeset_spectral_user_toprog
  !
  subroutine cubeset_spectral_user_list(user,error)
    !-------------------------------------------------------------------
    ! List
    !-------------------------------------------------------------------
    class(spectral_user_t), intent(in)    :: user
    logical,                intent(inout) :: error
    !
    character(len=*), parameter :: rname='SPECTRAL>USER>LIST'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call cubeset_message(seve%r,rname,blankstr)
    call user%freq%list(error)
    if (error) return
    call user%vsys%list(error)
    if (error) return
    call user%range%list(error)
    if (error) return
    call cubeset_message(seve%r,rname,blankstr)
  end subroutine cubeset_spectral_user_list
end module cubeset_spectral
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
