module cubetools_string
  use gkernel_interfaces

  public :: cubetools_string_split,cubetools_string_concat
  private

contains

  subroutine cubetools_string_split(fullstring,sep,list,error)
    !-------------------------------------------------------------------
    ! Split a string into several substrings given a separator
    ! The output list is allocated to the proper size on return
    !-------------------------------------------------------------------
    character(len=*), intent(in)               :: fullstring
    character(len=*), intent(in)               :: sep   ! Can be of any length, blanks allowed
    character(len=*), intent(out), allocatable :: list(:)
    logical,          intent(inout)            :: error
    !
    character(len=*), parameter :: rname='STRING>SPLIT'
    integer(kind=4) :: lfull,lsep,icha,left,mstring,ier
    !
    lfull = len(fullstring)
    if (lfull.eq.0)  return  ! Leave list unallocated
    !
    lsep = len(sep)
    !
    ! Count number of separators
    mstring = 1
    icha = 1
    do while (icha.le.lfull-lsep+1)
      if (fullstring(icha:icha+lsep-1).eq.sep) then
        mstring = mstring+1
        icha = icha+lsep
      else
        icha = icha+1
      endif
    enddo
    !
    allocate(list(mstring),stat=ier)
    if (failed_allocate(rname,'list',ier,error)) return
    mstring = 1
    left = 1
    icha = 1
    do while (icha.le.lfull-lsep+1)
      if (fullstring(icha:icha+lsep-1).eq.sep) then
        list(mstring) = fullstring(left:icha-1)  ! Can be 0-sized => save blanks
        ! Next
        mstring = mstring+1
        icha = icha+lsep
        left = icha
      else
        icha = icha+1
      endif
    enddo
    ! Last
    list(mstring) = fullstring(left:lfull)  ! Can be 0-sized => save blanks
  end subroutine cubetools_string_split

  subroutine cubetools_string_concat(nl,list,sep,string,error)
    !-------------------------------------------------------------------
    ! From a list of strings, return them concatenated with the given
    ! separator.
    ! If the output string is too short, string is terminated with ..
    !-------------------------------------------------------------------
    integer(kind=4),  intent(in)    :: nl
    character(len=*), intent(in)    :: list(:)
    character(len=*), intent(in)    :: sep
    character(len=*), intent(out)   :: string
    logical,          intent(inout) :: error
    ! Local
    integer(kind=4) :: il,nc,mc,lsep
    !
    lsep = len(sep)
    string = ''
    nc = 0
    mc = len(string)
    do il=1,nl
      if (nc.gt.0) then
        nc = nc+1
        string(nc:nc+lsep-1) = sep
        nc = nc+lsep-1
      endif
      string(nc+1:mc) = list(il)
      nc = nc+len_trim(list(il))
      if (nc.gt.mc) then
        string(mc-1:mc) = '..'
        exit
      endif
    enddo
  end subroutine cubetools_string_concat

end module cubetools_string
