!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubego_topic_types
  use cubetools_parameters
  use cubetools_structure
  use cubetools_keyword_arg
  use cubego_messaging
  !
  public :: nkind,kind_name
  public :: topic_opt_t,topic_user_t, topic_prog_t
  private
  !
  integer(kind=inte_k),  parameter :: kind_l = 6
  integer(kind=inte_k),  parameter :: nkind = 3
  character(len=kind_l), parameter :: kind_name(nkind) = ['signal','noise ','snr   ']
  !
  type topic_opt_t
     type(option_t),      pointer :: option
     type(keyword_arg_t), pointer :: kind
   contains
     procedure :: register => cubego_topic_register
     procedure :: parse    => cubego_topic_parse
  end type topic_opt_t
  !
  type topic_user_t
     character(len=argu_l) :: kind = strg_unk
     logical :: do = .false.
   contains
     procedure :: toprog => cubego_topic_user_toprog     
  end type topic_user_t
  !
  type topic_prog_t
     integer(kind=code_k) :: kind = code_null
     logical :: do = .false.
  end type topic_prog_t
  !
contains
  !
  subroutine cubego_topic_register(topic,name,abstract,error)
    !----------------------------------------------------------------------
    ! Register /MOMENT [signal|noise|snr]
    !----------------------------------------------------------------------
    class(topic_opt_t), intent(out)   :: topic
    character(len=*),   intent(in)    :: name
    character(len=*),   intent(in)    :: abstract
    logical,            intent(inout) :: error
    !
    type(keyword_arg_t) :: keyarg
    character(len=*), parameter :: rname='TOPIC>REGISTER'
    !
    call cubego_message(goseve%trace,rname,'Welcome')
    !
    call cubetools_register_option(&
         name,'[signal|noise|snr]',&
         abstract,&
         strg_id,&
         topic%option,error)
    if (error) return
    call keyarg%register(&
         'KIND',&
         'Signal or Noise or SNR',&
         'Default is Signal. * means Signal',&
         code_arg_optional,&
         kind_name,&
         .not.flexible,&
         topic%kind,&
         error)
    if (error) return
  end subroutine cubego_topic_register
  !
  subroutine cubego_topic_parse(topic,line,user,error)
    use cubetools_parse
    !----------------------------------------------------------------------
    ! 
    !----------------------------------------------------------------------
    class(topic_opt_t), intent(in)    :: topic
    character(len=*),   intent(in)    :: line
    type(topic_user_t), intent(inout) :: user
    logical,            intent(inout) :: error
    !
    integer(kind=4), parameter :: iarg=1
    character(len=*), parameter :: rname='TOPIC>PARSE'
    !
    call cubego_message(goseve%trace,rname,'Welcome')
    !
    call topic%option%present(line,user%do,error)
    if (error) return
    user%kind = strg_star
    if (user%do) then
       call cubetools_getarg(line,topic%option,iarg,user%kind,.not.mandatory,error)
       if (error) return
    endif
  end subroutine cubego_topic_parse
  !
  !---------------------------------------------------------------------
  !
  subroutine cubego_topic_user_toprog(user,prog,error)
    use cubetools_disambiguate
    !----------------------------------------------------------------------
    ! 
    !----------------------------------------------------------------------
    class(topic_user_t), intent(in)    :: user
    type(topic_prog_t),  intent(inout) :: prog
    logical,             intent(inout) :: error
    !
    character(len=kind_l) :: name
    character(len=*), parameter :: rname='TOPIC>USER>TOPROG'
    !
    call cubego_message(goseve%trace,rname,'Welcome')
    !
    prog%do = user%do
    if (user%kind.eq.strg_star) then
       prog%kind = 1 ! Signal
    else if (user%do) then
       call cubetools_disambiguate_strict(user%kind,kind_name,prog%kind,name,error)
       if (error) return
    endif
  end subroutine cubego_topic_user_toprog
end module cubego_topic_types
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubego_show
  use cubetools_structure
  use cubeadm_cubeid_types
  use cubego_messaging
  use cubego_topic_types
  !
  public :: show,cubego_show_command
  private
  !
  type :: show_comm_t
     type(option_t), pointer :: comm
     type(topic_opt_t)       :: moments
     type(topic_opt_t)       :: fit
   contains
     procedure, public :: register => cubego_show_register
     procedure, public :: parse    => cubego_show_parse
     procedure, public :: main     => cubego_show_main
  end type show_comm_t
  type(show_comm_t) :: show
  !
  integer(kind=4), parameter :: icube = 1
  type show_user_t
     type(cubeid_user_t) :: cubeids
     type(topic_user_t)  :: moments
     type(topic_user_t)  :: fit
   contains
     procedure, private :: toprog => cubego_show_user_toprog
  end type show_user_t
  !
  type show_prog_t
     character(len=base_l) :: family
     type(topic_prog_t)    :: moments
     type(topic_prog_t)    :: fit
   contains
     procedure, private :: act => cubego_show_prog_act
  end type show_prog_t
  !
contains
  !
  subroutine cubego_show_command(line,error)
    use gkernel_interfaces
    !---------------------------------------------------------------------
    !
    !---------------------------------------------------------------------
    character(len=*), intent(in)    :: line
    logical,          intent(inout) :: error
    !
    type(show_user_t) :: user
    character(len=*),parameter :: rname='SHOW>COMMAND'
    !
    call cubego_message(goseve%trace,rname,'Welcome')
    !
    call show%parse(line,user,error)
    if (error) return
    call show%main(user,error)
    if (error) return
    ! Force insertion in SIC stack ! *** JP Why?
    if (sic_lire().eq.0) call sic_insert(line)
  end subroutine cubego_show_command
  !
  !----------------------------------------------------------------------
  !
  subroutine cubego_show_register(show,error)
    use cubedag_allflags
    !---------------------------------------------------------------------
    ! 
    !---------------------------------------------------------------------
    class(show_comm_t), intent(inout) :: show
    logical,            intent(inout) :: error
    !
    type(cubeid_arg_t) :: cubearg
    character(len=*), parameter :: comm_abstract = &
         'Show combinations of cubes belonging to the same family'
    character(len=*), parameter :: comm_help = &
         strg_id
    character(len=*), parameter :: rname='SHOW>REGISTER'
    !
    call cubego_message(goseve%trace,rname,'Welcome')
    !
    call cubetools_register_command(&
         'SHOW','[familyid]',&
         comm_abstract,&
         comm_help,&
         cubego_show_command,&
         show%comm,error)
    if (error) return
    call cubearg%register( &
         'FAMILY', &
         'Family id to be showed',  &
         strg_id,&
         code_arg_optional,  &
         [flag_any], &
         error)
    if (error) return
    !
    call show%moments%register('MOMENTS',&
         'Show cube moments',error)
    if (error) return
    call show%fit%register('FIT',&
         'Show cube gaussian fit',error)
    if (error) return
  end subroutine cubego_show_register
  !
  subroutine cubego_show_parse(show,line,user,error)
    !---------------------------------------------------------------------
    !
    !---------------------------------------------------------------------
    class(show_comm_t), intent(in)    :: show
    character(len=*),   intent(in)    :: line
    class(show_user_t), intent(inout) :: user
    logical,            intent(inout) :: error
    !
    character(len=*), parameter :: rname='SHOW>PARSE'
    !
    call cubego_message(goseve%trace,rname,'Welcome')
    !
    call cubeadm_cubeid_parse(line,show%comm,user%cubeids,error)
    if (error) return
    call show%moments%parse(line,user%moments,error)
    if (error) return
    call show%fit%parse(line,user%fit,error)
    if (error) return
  end subroutine cubego_show_parse
  !
  subroutine cubego_show_main(show,user,error)
    use cubeadm_timing
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(show_comm_t), intent(in)    :: show
    type(show_user_t),  intent(inout) :: user
    logical,            intent(inout) :: error
    !
    type(show_prog_t) :: prog
    character(len=*), parameter :: rname='SHOW>MAIN'
    !
    call cubego_message(goseve%trace,rname,'Welcome')
    !
    call user%toprog(show,prog,error)
    if (error) return
    call cubeadm_timing_prepro2process()
    call prog%act(error)
    if (error) return
    call cubeadm_timing_process2postpro()
  end subroutine cubego_show_main
  !
  !----------------------------------------------------------------------
  !
  subroutine cubego_show_user_toprog(user,comm,prog,error)
    use cubetools_user2prog
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(show_user_t), intent(in)    :: user
    type(show_comm_t),  intent(in)    :: comm    
    type(show_prog_t),  intent(out)   :: prog
    logical,            intent(inout) :: error
    !
    character(len=*), parameter :: rname='SHOW>USER>TOPROG'
    !
    call cubego_message(goseve%trace,rname,'Welcome')
    !
    prog%family = user%cubeids%cube(icube)%family
    call user%moments%toprog(prog%moments,error)
    if (error) return
    call user%fit%toprog(prog%fit,error)
    if (error) return
    !
    if (user%fit%do.and.user%moments%do) then
      call cubego_message(seve%e,rname,'Only one topic supported at a time (/MOMENTS OR /FIT)')
      error = .true.
      return 
    endif
  end subroutine cubego_show_user_toprog
  !
  !----------------------------------------------------------------------
  !  
  subroutine cubego_show_prog_act(prog,error)
    use gkernel_interfaces
    !----------------------------------------------------------------------
    ! Execute commands
    !----------------------------------------------------------------------
    class(show_prog_t), intent(inout) :: prog
    logical,            intent(inout) :: error
    !
    character(len=mess_l) :: exec
    character(len=*), parameter :: rname='SHOW>PROG>ACT'
    !
    write (exec,'(2a)') 'let name ',prog%family
    call exec_program(trim(exec))    
    if (prog%moments%do) then
       if ((0.lt.prog%moments%kind).and.(prog%moments%kind.le.nkind)) then
          call exec_program('@ show-moments.cube '//trim(kind_name(prog%moments%kind)))
       else
          call cubego_message(seve%e,rname,'prog%moments%kind outside authorized range')
          error = .true.
          return
       endif
    else if (prog%fit%do) then
       if ((0.lt.prog%fit%kind).and.(prog%fit%kind.le.nkind)) then
          call exec_program('@ show-fit.cube '//trim(kind_name(prog%fit%kind)))
       else
          call cubego_message(seve%e,rname,'prog%fit%kind outside authorized range')
          error = .true.
          return
       endif
    else
       call cubego_message(seve%e,rname,'Need at least one action')
       error = .true.
       return
    endif
    call exec_program('let name ""')
  end subroutine cubego_show_prog_act
end module cubego_show
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
