!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubesimulate_tuning
  use cubetools_parameters
  use cubetools_structure
  use cubesyntax_keyval_types
  use cubesimulate_messaging
  !
  public :: tuning_comm_t,tuning_prog_t
  public :: tuning_comm,tuning_prog
  private
  !
  type :: tuning_comm_t
     type(option_t), pointer  :: comm
     type(keyval_strg_comm_t) :: line
     type(keyvalunit_dble_comm_t) :: freq
   contains
     procedure, public  :: register => cubesimulate_tuning_comm_register
     procedure, private :: parse    => cubesimulate_tuning_comm_parse
     procedure, private :: main     => cubesimulate_tuning_comm_main
  end type tuning_comm_t
  type(tuning_comm_t), target :: tuning_comm
  !
  type tuning_user_t
     logical :: dolist = .false.
     type(keyval_strg_user_t) :: line
     type(keyvalunit_dble_user_t) :: freq
   contains
     procedure, private :: toprog => cubesimulate_tuning_user_toprog
  end type tuning_user_t
  !
  type tuning_prog_t
     character(len=line_l) :: line = '13CO(1-0)'   ! 
     real(kind=coor_k)     :: freq = 110201.3543d0 ! Signal Frequency
     real(kind=coor_k)     :: fima = 0d0           ! Image  Frequency
     real(kind=coor_k)     :: wave = 0d0           ! Signal Wavelength
   contains
     procedure, public  :: list   => cubesimulate_tuning_prog_list
     procedure, private :: header => cubesimulate_tuning_prog_header
  end type tuning_prog_t
  type(tuning_prog_t), target :: tuning_prog
  !
contains
  !
  subroutine cubesimulate_tuning_command(line,error)
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    character(len=*), intent(in)    :: line
    logical,          intent(inout) :: error
    !
    type(tuning_user_t) :: user
    character(len=*), parameter :: rname='TUNING>COMMAND'
    !
    call cubesimulate_message(simulateseve%trace,rname,'Welcome')
    !
    call tuning_comm%parse(line,user,error)
    if (error) return
    call tuning_comm%main(user,tuning_prog,error)
    if (error) continue
  end subroutine cubesimulate_tuning_command
  !
  !----------------------------------------------------------------------
  !
  subroutine cubesimulate_tuning_comm_register(comm,error)
    use cubetools_unit
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(tuning_comm_t), intent(inout) :: comm
    logical,              intent(inout) :: error
    !
    character(len=*), parameter :: rname='TUNING>COMM>REGISTER'
    !
    call cubesimulate_message(simulateseve%trace,rname,'Welcome')
    !
    ! Syntax
    call cubetools_register_command(&
         'TUNING','',&
         'Set or list the receiver tuning',&
         'Without options, list the current line label, rest frequency,&
         & image frequency, and wavelength. Use /LINE and /FREQUENCY to&
         & update the stored tuning state.',&
         cubesimulate_tuning_command,&
         comm%comm,&
         error)
    if (error) return
    call comm%line%register(&
         'LINE',&
         'Observed line label',&
         'Set the stored observed-line label. The label is&
         & informational only and does not change /FREQUENCY.',&
         tuning_prog%line,&
         'Observed line label.',&
         error)
    if (error) return
    call comm%freq%register(&
         'FREQUENCY',&
         'Rest frequency of the observed line',&
         'Set the rest frequency used to derive the image&
         & frequency and wavelength. The current image-frequency rule is&
         & rest frequency minus 8000 MHz. The value must stay > 0 after&
         & unit conversion.',&
         tuning_prog%freq,&
         code_unit_freq,&
         strg_emp,&
         error)
    if (error) return
  end subroutine cubesimulate_tuning_comm_register
  !
  subroutine cubesimulate_tuning_comm_parse(comm,line,user,error)
    !----------------------------------------------------------------------
    ! TUNING
    !----------------------------------------------------------------------
    class(tuning_comm_t), intent(in)    :: comm
    character(len=*),     intent(in)    :: line
    type(tuning_user_t),  intent(out)   :: user
    logical,              intent(inout) :: error
    !
    character(len=*), parameter :: rname='TUNING>COMM>PARSE'
    !
    call cubesimulate_message(simulateseve%trace,rname,'Welcome')
    !
    if (cubetools_nopt().eq.0) then
       user%dolist = .true.
    else
       user%dolist = .false.
       call comm%line%parse(line,user%line,error)
       if (error) return
       call comm%freq%parse(line,user%freq,error)
       if (error) return
    endif
  end subroutine cubesimulate_tuning_comm_parse
  !
  subroutine cubesimulate_tuning_comm_main(comm,user,prog,error) 
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(tuning_comm_t), intent(in)    :: comm
    type(tuning_user_t),  intent(inout) :: user
    type(tuning_prog_t),  intent(inout) :: prog
    logical,              intent(inout) :: error
    !
    character(len=*), parameter :: rname='TUNING>COMM>MAIN'
    !
    call cubesimulate_message(simulateseve%trace,rname,'Welcome')
    !
    if (user%dolist) then
       call prog%header(comm,error)
       if (error) return
       call prog%list(comm,error)
       if (error) return
    else
       call user%toprog(comm,prog,error)
       if (error) return
       call prog%header(comm,error)
       if (error) return
    endif
  end subroutine cubesimulate_tuning_comm_main
  !
  !------------------------------------------------------------------------
  !
  subroutine cubesimulate_tuning_user_toprog(user,comm,prog,error)
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(tuning_user_t), intent(in)    :: user
    type(tuning_comm_t),  intent(in)    :: comm    
    type(tuning_prog_t),  intent(out)   :: prog
    logical,              intent(inout) :: error
    !
    character(len=*), parameter :: rname='TUNING>USER>TOPROG'
    !
    call cubesimulate_message(simulateseve%trace,rname,'Welcome')
    !
    call user%line%toprog(comm%line,prog%line,error)
    if (error) return
    call user%freq%toprog(comm%freq,prog%freq,error)
    if (error) return
  end subroutine cubesimulate_tuning_user_toprog
  !
  !------------------------------------------------------------------------
  !
  subroutine cubesimulate_tuning_prog_header(prog,comm,error)
    use phys_const
    !----------------------------------------------------------------------
    ! 
    !----------------------------------------------------------------------
    class(tuning_prog_t), intent(inout) :: prog
    type(tuning_comm_t),  intent(in)    :: comm
    logical,              intent(inout) :: error
    !
    character(len=*), parameter :: rname='TUNING>PROG>HEADER'
    !
    call cubesimulate_message(simulateseve%trace,rname,'Welcome')
    !
    if (prog%freq.gt.0) then
       prog%fima = prog%freq-8000d0 !***JP: Needs a better definition that depends on LSB/USB tuning
       prog%wave = clight/prog%freq
    else
       call cubesimulate_message(seve%e,rname,'Negative or zero valued frequency')
       error = .true.
       return
    endif
  end subroutine cubesimulate_tuning_prog_header
  !
  subroutine cubesimulate_tuning_prog_list(prog,comm,error)
    use cubetools_unit
    !----------------------------------------------------------------------
    ! 
    !----------------------------------------------------------------------
    class(tuning_prog_t), intent(inout) :: prog
    type(tuning_comm_t),  intent(in)    :: comm
    logical,              intent(inout) :: error
    !
    type(keyvalunit_list_t) :: keyvalunit
    type(keyval_strg_prog_t) :: keyval_strg
    type(keyvalunit_dble_prog_t) :: keyvalunit_dble
    character(len=*), parameter :: rname='TUNING>PROG>LIST'
    !
    call cubesimulate_message(simulateseve%trace,rname,'Welcome')
    !
    call cubesimulate_message(seve%r,rname,blankstr)
    call cubesimulate_message(seve%r,rname,'Tuning')
    !
    call keyval_strg%list(comm%line,prog%line,error)
    if (error) return
    call keyvalunit_dble%list(comm%freq,prog%freq,error)
    if (error) return
    call keyvalunit%list('IMAGE FREQ',prog%fima,code_unit_freq,error)
    if (error) return
    call keyvalunit%list('WAVELENGTH',prog%wave,code_unit_wave,error)
    if (error) return
  end subroutine cubesimulate_tuning_prog_list
end module cubesimulate_tuning
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
