module cubetools_datasize
  use cubetools_parameters
  use cubetools_messaging
  !
  integer(kind=4), parameter :: size_k = 4
  !
  real(kind=size_k), parameter :: kiB=1.024e3    ! Number of bytes in 1 kiB (1024**1)
  real(kind=size_k), parameter :: MiB=1.048576e6 ! Number of bytes in 1 MiB (1024**2)
  real(kind=size_k), parameter :: GiB=1.07374e9  ! Number of bytes in 1 GiB (1024**3)
  !
  integer(kind=4), parameter :: ikiB = 1
  integer(kind=4), parameter :: iMiB = 2
  integer(kind=4), parameter :: iGiB = 3
  !
  integer(kind=4), parameter :: ndataunit = 3
  character(len=*), parameter :: dataunit(ndataunit) =  ['kiB','MiB','GiB']
  real(kind=size_k), parameter :: dataconv(ndataunit) = [ kiB,  MiB,  GiB]
  !
  public :: size_k,kiB,MiB,GiB,dataunit,ikiB,iMiB,iGiB
  public :: cubetools_datasize_user2prog
  private
  !
contains
  subroutine cubetools_datasize_user2prog(user,unit,defsize,prog,error)
    use cubetools_disambiguate
    !------------------------------------------------------------------------
    ! Transforms an user size from user unit to a value in bytes
    !------------------------------------------------------------------------
    character(len=*),  intent(in)    :: user
    character(len=*),  intent(in)    :: unit
    real(kind=size_k), intent(in)    :: defsize
    real(kind=size_k), intent(inout) :: prog
    logical,           intent(inout) :: error
    !
    integer(kind=4) :: nc,ikey
    character(len=argu_l) :: key
    real(kind=size_k) :: tmp
    character(len=*), parameter :: rname='DATASIZE>USER2PROG'
    !
    call cubetools_message(toolseve%trace,rname,'Welcome')
    !
    select case(user)
    case (strg_unk)
       call cubetools_message(seve%e,rname,'String is unknown, maybe&
            & uninitialized?')
       error = .true.
       return
    case (strg_star)
       prog = defsize
    case (strg_equal)
       return
    case default
       nc = len_trim(user)
       call sic_math_real(user,nc,tmp,error)
       if (error) then
          call cubetools_message(seve%e,rname,'Cannot convert '//trim(user)//' to a data size' )
          return
       endif
       if (tmp.le.0) then
          call cubetools_message(seve%e,rname,'Data size must be positive' )
          error = .true.
          return
       endif
       call cubetools_disambiguate_strict(unit,dataunit,ikey,key,error)
       if (error) return
       prog = tmp*dataconv(ikey)
    end select
  end subroutine cubetools_datasize_user2prog
end module cubetools_datasize
