!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
module cubetools_progstruct_types
  use cubetools_parameters
  use cubesyntax_messaging
  !
  public :: progstruct_t
  private
  !
  type progstruct_t
     character(len=varn_l) :: name = strg_unk
   contains
     procedure, public :: init     => cubetools_progstruct_init
     procedure, public :: reinit   => cubetools_progstruct_reinit
     procedure, public :: recreate => cubetools_progstruct_recreate
  end type progstruct_t
  !
contains
  !
  subroutine cubetools_progstruct_init(struct,name,error)
    use gkernel_interfaces
    !-------------------------------------------------------------------
    !
    !-------------------------------------------------------------------
    class(progstruct_t), intent(inout) :: struct
    character(len=*),    intent(in)    :: name
    logical,             intent(inout) :: error
    !
    character(len=*), parameter :: rname='CUBETOOLS>PROGSTRUCT>INIT'
    !
    call cubesyntax_message(syntaxseve%trace,rname,'Welcome')
    !
    call sic_defstructure(cubetools_progstruct_remove_trailing(name),global,error)
    if (error) return
    struct%name = cubetools_progstruct_remove_trailing(name)//'%'
  end subroutine cubetools_progstruct_init
  !
  subroutine cubetools_progstruct_reinit(struct,name,error)
    use gkernel_interfaces
    !-------------------------------------------------------------------
    !
    !-------------------------------------------------------------------
    class(progstruct_t), intent(inout) :: struct
    character(len=*),    intent(in)    :: name
    logical,             intent(inout) :: error
    !
    character(len=*), parameter :: rname='CUBETOOLS>PROGSTRUCT>REINIT'
    !
    call cubesyntax_message(syntaxseve%trace,rname,'Welcome')
    !
    if (sic_varexist(name)) then
       call cubesyntax_message(syntaxseve%others,rname,&
            name//' prog structure already exists => Remove it')
       call sic_delvariable(name,.false.,error)
       if (error) return
    endif
    call struct%init(name,error)
    if (error) return
  end subroutine cubetools_progstruct_reinit
  !
  subroutine cubetools_progstruct_recreate(struct,subname,substruct,error)
    use gkernel_interfaces
    !-------------------------------------------------------------------
    ! Check if the "struct" SIC structure exists. If it doesn't, return.
    ! Else check if "name" SIC structure dependant on "struct" exists.
    ! If it does, erase it, and then recreate it.
    !-------------------------------------------------------------------
    class(progstruct_t), intent(in)    :: struct
    character(len=*),    intent(in)    :: subname
    type(progstruct_t),  intent(inout) :: substruct
    logical,             intent(inout) :: error
    !
    character(len=varn_l) :: name
    character(len=*), parameter :: rname='CUBETOOLS>PROGSTRUCT>RECREATE'
    !
    call cubesyntax_message(syntaxseve%trace,rname,'Welcome')
    !
    if (.not.sic_varexist(cubetools_progstruct_remove_trailing(struct%name))) then
       call cubesyntax_message(seve%e,rname,&
            cubetools_progstruct_remove_trailing(struct%name)//' prog structure does not exist yet')
       error = .true.
       return
    endif
    name = trim(struct%name)//cubetools_progstruct_remove_trailing(subname)
    if (sic_varexist(name)) then
       call cubesyntax_message(syntaxseve%others,rname,&
            name//' prog structure already exists => Remove it')
       call sic_delvariable(name,.false.,error)
       if (error) return
    endif
    call substruct%init(name,error)
    if (error) return
  end subroutine cubetools_progstruct_recreate
  !
  function cubetools_progstruct_remove_trailing(name) result(trimname)
    !-------------------------------------------------------------------
    ! Check if name ends in a %. If it does, remove it .
    !-------------------------------------------------------------------
    character(len=*), intent(in)   :: name
    character(len=:), allocatable  :: trimname
    !
    integer(kind=4) :: length
    character(len=*), parameter :: rname='CUBETOOLS>PROGSTRUCT>REMOVE>TRAILING'
    !
    call cubesyntax_message(syntaxseve%trace,rname,'Welcome')
    !
    ! *** JP Shouldn't we allocate the string trimname?
    length = len_trim(name)
    if (name(length:length).eq.'%') then
       trimname = name(1:length-1)
    else
       trimname = trim(name)
    endif
  end function cubetools_progstruct_remove_trailing
end module cubetools_progstruct_types
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
