!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubemain_template_tab
  use cube_types
  use cubemain_messaging
  use cubetools_structure
  use cubeadm_cubeid_types
  !
  public :: cubemain_template_tab_command
  private
  !
  integer(kind=4), parameter :: icube = 1 
  type(option_t), pointer :: template
  !
  type template_user_t
     type(cubeid_user_t)   :: incube
  end type template_user_t
  type template_prog_t
     type(cube_t) :: cube
     ! type(cube_t) :: template
  end type template_prog_t
  !
contains
  !
  subroutine cubemain_template_tab_command(opt,line,error)
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    type(option_t),pointer, intent(in)    :: opt
    character(len=*),       intent(in)    :: line
    logical,                intent(inout) :: error
    !
    type(template_user_t) :: user
    type(template_prog_t) :: prog
    character(len=*), parameter :: rname='TEMPLATE>COMMAND'
    !
    call cubemain_message(mainseve%trace,rname,'Welcome')
    !
    template => opt
    call cubemain_template_tab_parse(line,user,error)
    if (error) return
    call cubemain_template_tab_main(user,prog,error)
    if (error) continue
  end subroutine cubemain_template_tab_command
  !
  subroutine cubemain_template_tab_parse(line,user,error)
    use cubetools_parse
    !----------------------------------------------------------------------
    ! TEMPLATE cubname
    ! 1. /RANGE vfirst vlast
    !----------------------------------------------------------------------
    character(len=*),      intent(in)    :: line
    type(template_user_t), intent(out)   :: user
    logical,               intent(inout) :: error
    !
    integer(kind=4), parameter :: irange = 1
    character(len=*), parameter :: rname='TEMPLATE>PARSE'
    !
    call cubemain_message(mainseve%trace,rname,'Welcome')
    !
    call cubeadm_cubeid_parse(line,template,user%incube,error)
    if (error) return
  end subroutine cubemain_template_tab_parse
  !
  subroutine cubemain_template_tab_main(user,prog,error)
    use cubeadm_timing
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    type(template_user_t), intent(in)    :: user
    type(template_prog_t), intent(inout) :: prog
    logical,               intent(inout) :: error
    !
    character(len=*), parameter :: rname='TEMPLATE>MAIN'
    !
    call cubemain_message(mainseve%trace,rname,'Welcome')
    !
    ! VVV What is code tab?
    ! call cubeadm_cubeid_get_header(template,icube,user%incube,code_table_speset,code_read,prog%cube,error)
    ! if (error) return
    call cubemain_template_tab_header(user,prog,error)
    if (error) return
    call cubeadm_timing_prepro2process()
    call cubemain_template_tab_data(prog,error)
    if (error) return
    call cubeadm_timing_process2postpro()
  end subroutine cubemain_template_tab_main
  !
  subroutine cubemain_template_tab_header(user,prog,error)
    use cubeadm_clone
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    type(template_user_t), intent(in)    :: user
    type(template_prog_t), intent(inout) :: prog
    logical,               intent(inout) :: error
    !
    character(len=*), parameter :: rname='TEMPLATE>HEADER'
    !
    call cubemain_message(mainseve%trace,rname,'Welcome')
    !
    ! ZZZ call cubeadm_clone_header(prog%cube,flag_template,prog%template,error)
    if (error) return
  end subroutine cubemain_template_tab_header
  !
  subroutine cubemain_template_tab_data(prog,error)
    use cubeadm_opened
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    type(template_prog_t), intent(inout) :: prog
    logical,               intent(inout) :: error
    !
    character(len=*), parameter :: rname='TEMPLATE>DATA'
    type(cubeadm_iterator_t) :: iter
    !
    call cubemain_message(mainseve%trace,rname,'Welcome')
    !
    call cubeadm_datainit_all(iter,error)
    if (error) return
    !$OMP PARALLEL DEFAULT(none) SHARED(prog,error) FIRSTPRIVATE(iter)
    !$OMP SINGLE
    do while (cubeadm_dataiterate_all(iter,error))
       if (error)  exit
       !$OMP TASK
       if (.not.error)  &
         call cubemain_template_tab_spectrum_loop(prog,iter%first,iter%last,error)
       !$OMP END TASK
    enddo ! ie
    !$OMP END SINGLE
    !$OMP END PARALLEL
  end subroutine cubemain_template_tab_data
  !
  subroutine cubemain_template_tab_spectrum_loop(prog,first,last,error)
    use cubeadm_entryloop
    use cubemain_spectrum
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    type(template_prog_t), intent(inout) :: prog
    integer(kind=entr_k),  intent(in)    :: first
    integer(kind=entr_k),  intent(in)    :: last
    logical,               intent(inout) :: error
    !
    character(len=*), parameter :: rname='TEMPLATE>SPECTRUM>LOOP'
    integer(kind=entr_k) :: ie
    type(spectrum_t) :: inspec,ouspec
    !
    call cubemain_spectrum_init(prog%cube,inspec,error)
    if (error) goto 10
    call cubemain_spectrum_reallocate(prog%cube%head%arr%n%c,'template',ouspec,error)
    if (error) goto 10
    !
    print *,'first,last = ',first,last
    do ie=first,last
      call cubeadm_entryloop_iterate(ie,error)
      if (error)  goto 10
      call cubemain_template_tab_spectrum(prog,ie,inspec,ouspec,error)
      if (error)  goto 10
    enddo
    !
10  continue
    call cubemain_spectrum_free(ouspec,error)
    if (error)  continue
    call cubemain_spectrum_free(inspec,error)
    if (error)  continue
  end subroutine cubemain_template_tab_spectrum_loop
  !
  subroutine cubemain_template_tab_spectrum(prog,ie,inspec,ouspec,error)
    use cubemain_spectrum
    !----------------------------------------------------------------------
    !
    !----------------------------------------------------------------------
    type(template_prog_t), intent(inout) :: prog
    integer(kind=entr_k),  intent(in)    :: ie
    type(spectrum_t),      intent(inout) :: inspec  ! Working buffer
    type(spectrum_t),      intent(inout) :: ouspec  ! Working buffer
    logical,               intent(inout) :: error
    !
    integer(kind=chan_k) :: ic
    character(len=*), parameter :: rname='TEMPLATE>SPECTRUM'
    !
    call cubemain_spectrum_get(prog%cube,ie,inspec,error)
    if (error)  return
    do ic=1,prog%cube%head%arr%n%c
      ouspec%t(ic) = inspec%t(ic)
    enddo ! ic
    print *,ouspec%t(1),ouspec%t(prog%cube%head%arr%n%c)
    ! call cubemain_spectrum_put(prog%template,ie,ouspec,error)
    ! if (error)  return
  end subroutine cubemain_template_tab_spectrum
end module cubemain_template_tab
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
