module units_m
  use fdf_prec, only: dp

  implicit none
  
  public :: inquire_unit
  private

  integer, parameter :: nu = 9
  integer :: iu
      character(8) :: dimm(nu)
      character(10) :: name(nu)
      real(dp) :: unit(nu)

      data (dimm(iu), name(iu), unit(iu), iu=1, 3) / &
          'mass    ', 'g         ', 1.d-3, &
          'mass    ', 'kg        ', 1.d0, &
          'mass    ', 'amu       ', 1.66054d-27 /

      data (dimm(iu), name(iu), unit(iu), iu=4, 9) / &
          'length  ', 'm         ', 1.d0, &
          'length  ', 'cm        ', 1.d-2, &
          'length  ', 'nm        ', 1.d-9, &
          'length  ', 'ly        ', 9.46d15, &
          'length  ', 'parsec    ', 30.9d15, &
          'length  ', 'bohr      ', 0.529177d-10 /


CONTAINS

  subroutine inquire_unit(unit_str, stat, phys_dim, unit_name, unit_value)
    use fdf_utils, only: leqi
    use fdf_prec, only: dp

    character(len=*), intent(in)   :: unit_str
    character(len=*), intent(out)  :: phys_dim
    character(len=*), intent(out)  :: unit_name
    real(dp), intent(out)          :: unit_value
    integer, intent(out)           :: stat

    integer           :: idx_colon, iu, idx
    logical           :: phys_dim_specified, match
    
    idx_colon = index(unit_str,":")
    if (idx_colon /= 0) then
       ! spec includes dimension prefix
       phys_dim = unit_str(1:idx_colon-1)
       unit_name = unit_str(idx_colon+1:)
       phys_dim_specified = .true.
    else
       phys_dim = ""
       unit_name = unit_str
       phys_dim_specified = .false.
    endif

    stat = 0
    idx = 0

    do iu= 1, nu
         match = .false.
         if (leqi(name(iu), unit_name)) then
            if (phys_dim_specified) then
               if (leqi(dimm(iu), phys_dim)) then
                  match = .true.
               endif
            else
               match = .true.
            endif
         endif
         if (match) then
            if (idx /= 0) then  ! ambiguous
               stat = 1
               RETURN
            endif
            idx = iu
         endif
      enddo
      
      if (idx == 0) then
         stat = -1    ! not found
      else
         phys_dim = trim(dimm(idx))
         unit_value = unit(idx)
      endif
      
    end subroutine inquire_unit
    
  end module units_m
