!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubemain_baseline_cubes_types
  use cube_types
  use cubetools_structure
  use cubetopology_cuberegion_types
  use cubeadm_cubeid_types
  use cubeadm_cubeprod_types
  use cubemain_messaging
  !
  public :: baseline_cubes_comm_t,baseline_cubes_user_t,baseline_cubes_prog_t
  private
  !
  type baseline_cubes_comm_t
     type(option_t), pointer     :: comm
     type(cuberegion_comm_t)     :: region
     type(cubeid_arg_t), pointer :: cube
     type(cube_prod_t),  pointer :: base
     type(cube_prod_t),  pointer :: line
   contains
     procedure, public :: register => cubemain_baseline_cubes_comm_register
     procedure, public :: parse    => cubemain_baseline_cubes_comm_parse
  end type baseline_cubes_comm_t
  !
  type baseline_cubes_user_t
     type(cuberegion_user_t) :: region
     type(cubeid_user_t)     :: cubeids
   contains
     procedure, public :: toprog => cubemain_baseline_cubes_user_toprog
     procedure, public :: list   => cubemain_baseline_cubes_user_list
  end type baseline_cubes_user_t
  !
  type baseline_cubes_prog_t
     type(cuberegion_prog_t) :: region ! Cube region of interest
     type(cube_t), pointer   :: cube   ! Input cube
     type(cube_t), pointer   :: base   ! Output baseline
     type(cube_t), pointer   :: line   ! Output baselined cube
   contains
     procedure, public :: header => cubemain_baseline_cubes_prog_header
     procedure, public :: list   => cubemain_baseline_cubes_prog_list
  end type baseline_cubes_prog_t
  !
contains
  !
  subroutine cubemain_baseline_cubes_comm_register(comm,exec,error)
    use cubedag_allflags
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(baseline_cubes_comm_t), intent(inout) :: comm
    external                                    :: exec
    logical,                      intent(inout) :: error
    !
    type(cubeid_arg_t) :: incube
    type(cube_prod_t)  :: oucube
    character(len=*), parameter :: comm_abstract='Subtract a baseline from a cube'
    character(len=*), parameter :: comm_help=&
      'Three algorithms are available to compute a baseline:&
      & /MEDIAN, /WAVELET and /POLYNOMIAL. Only one of these three&
      & can be given at a time. If no algorithm option is given&
      & BASELINE defaults to /MEDIAN.'
    character(len=*), parameter :: rname='BASELINE>CUBES>REGISTER'
    !
    call cubemain_message(mainseve%trace,rname,'Welcome')
    !
    call cubetools_register_command(&
         'BASELINE','[cubeid]',&
         comm_abstract,&
         comm_help,&
         exec,&
         comm%comm,&
         error)
    if (error) return
    call incube%register(&
         'CUBE',&
         'Input cube',&
         strg_id,&
         code_arg_optional,&
         [flag_cube],&
         code_read,&
         code_access_speset,&
         comm%cube,&
         error)
    if (error) return
    !
    ! Products
    call oucube%register(&
         'BASE',&
         'Baseline cube',&
         strg_id,&
         [flag_baseline,flag_base],&
         comm%base,&
         error)
    if (error)  return
    call oucube%register(&
         'LINE',&
         'Baseline subtracted cube',&
         strg_id,&
         [flag_baseline,flag_line,flag_cube],&
         comm%line,&
         error)
    if (error)  return
  end subroutine cubemain_baseline_cubes_comm_register
  !
  subroutine cubemain_baseline_cubes_comm_parse(comm,line,user,error)
    !----------------------------------------------------------------------
    ! 
    !----------------------------------------------------------------------
    class(baseline_cubes_comm_t), intent(inout) :: comm
    character(len=*),             intent(in)    :: line
    type(baseline_cubes_user_t),  intent(out)   :: user
    logical,                      intent(inout) :: error
    !
    character(len=*), parameter :: rname='BASELINE>CUBES>COMM>PARSE'
    !
    call cubemain_message(mainseve%trace,rname,'Welcome')
    !
    call cubeadm_cubeid_parse(line,comm%comm,user%cubeids,error)
    if (error) return
!***JP:
!!$    call comm%region%parse(line,user%region,error)
!!$    if (error) return
  end subroutine cubemain_baseline_cubes_comm_parse
  !
  !------------------------------------------------------------------------
  !
  subroutine cubemain_baseline_cubes_user_toprog(user,comm,prog,error)
    use cubeadm_get
    !----------------------------------------------------------------------
    ! 
    !----------------------------------------------------------------------
    class(baseline_cubes_user_t), intent(inout) :: user ! ***JP: why inout?
    type(baseline_cubes_comm_t),  intent(in)    :: comm
    type(baseline_cubes_prog_t),  intent(inout) :: prog
    logical,                      intent(inout) :: error
    !
    character(len=*), parameter :: rname='BASELINE>CUBES>USER>TOPROG'
    !
    call cubeadm_cubeid_get_header(comm%cube,user%cubeids,prog%cube,error)
    if (error) return
    call user%region%toprog(prog%cube,prog%region,error)
    if (error) return
  end subroutine cubemain_baseline_cubes_user_toprog
  !
  subroutine cubemain_baseline_cubes_user_list(user,error)
    !----------------------------------------------------------------------
    ! Mostly for debugging purpose
    !----------------------------------------------------------------------
    class(baseline_cubes_user_t), intent(in)    :: user 
    logical,                      intent(inout) :: error
    !
    character(len=mess_l) :: mess
    character(len=*), parameter :: rname='BASELINE>CUBES>USER>LIST'
    !
    call cubemain_message(mainseve%trace,rname,'Welcome')
    !
    ! *** JP: To be written
    call cubemain_message(seve%r,rname,mess)
  end subroutine cubemain_baseline_cubes_user_list
  !
  !------------------------------------------------------------------------
  !
  subroutine cubemain_baseline_cubes_prog_header(prog,comm,error)
    use cubeadm_clone
    !-------------------------------------------------------------------
    !
    !-------------------------------------------------------------------
    class(baseline_cubes_prog_t), intent(inout) :: prog
    type(baseline_cubes_comm_t),  intent(in)    :: comm
    logical,                      intent(inout) :: error
    !
    character(len=*), parameter :: rname='BASELINE>CUBES>PROG>HEADER'
    !
    call cubemain_message(mainseve%trace,rname,'Welcome')
    !
    call cubeadm_clone_header(comm%base,prog%cube,prog%region,prog%base,error)
    if (error) return
    call cubeadm_clone_header(comm%line,prog%cube,prog%region,prog%line,error)
    if (error) return
  end subroutine cubemain_baseline_cubes_prog_header
  !
  subroutine cubemain_baseline_cubes_prog_list(prog,error)
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    class(baseline_cubes_prog_t), intent(in)    :: prog
    logical,                      intent(inout) :: error
    !
    character(len=*), parameter :: rname='BASELINE>CUBES>PROG>LIST'
    !
    call cubemain_message(mainseve%trace,rname,'Welcome')
    !
    call prog%region%list(error)
    if (error) return
  end subroutine cubemain_baseline_cubes_prog_list
end module cubemain_baseline_cubes_types
! 
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
