!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
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 :: 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)
    !-------------------------------------------------------------------
    !
    !-------------------------------------------------------------------
    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)
    !-------------------------------------------------------------------
    !
    !-------------------------------------------------------------------
    class(spectral_comm_t), intent(inout) :: spectral
    logical,                intent(inout) :: error
    !
    character(len=*), parameter :: rname='SPECTRAL>REGISTER'
    !
    call cubeset_message(setseve%trace,rname,'Welcome')
    !
    call cubetools_register_command(&
         'SPECTRAL','',&
         'Set the spectral region of interest',&
         'Without options, SPECTRAL lists the current spectral defaults.'//strg_cr//&
         'Use /DEFAULT to reset all spectral defaults. If /DEFAULT is&
         & combined with other keys on the same command line, reset takes&
         precedence.'//strg_cr//&
         'Use /FREQUENCY, /VSYS, and /RANGE to tune the line rest frequency,'//strg_cr//&
         'source systemic velocity, and spectral range settings for the spectral'//strg_cr//&
         'region of interest.'//strg_bl//&
         'Associated commands: SET\SPATIAL.',&
         cubeset_spectral_command,&
         spectral%comm,&
         error)
    if (error) return
    call spectral%range%register(&
         'RANGE',&
         'Set the spectral-axis range',&
         error)
    if (error) return
    call spectral%freq%register(&
         'Set the line name, rest frequency, and its unit',&
         error)
    if (error) return
    call spectral%vsys%register(&
         'Set the source systemic velocity',&
         error)
    if (error) return
    !
    call cubetools_register_option(&
         'DEFAULT','',&
         'Reset spectral settings',&
         'Reset SPECTRAL settings. If /DEFAULT is combined with other keys&
         & on the same command line, reset takes precedence.',&
         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]
    ! /DEFAULT
    !-------------------------------------------------------------------
    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_toprog(user,cube,truncate_mode,freq,vsys,range,error)
    use cube_types
    !----------------------------------------------------------------------
    ! 
    !----------------------------------------------------------------------
    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)
    !-------------------------------------------------------------------
    !
    !-------------------------------------------------------------------
    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
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
