# This file was automatically generated by running:
#
#   scripts/generate_grapheme_properties.cr
#
# DO NOT EDIT

struct String::Grapheme
  # :nodoc:
  #
  # The Grapheme Cluster Break Property values
  # http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Break_Property_Values
  enum Property
    Start
    Any
    <%- props.keys.each do |key| -%>
          <%= key %>
    <%- end -%>

    ExtendedPlusZeroWidth

    # returns the Unicode property value (see `Codepoints` constants below)
    # of the given code point
    def self.from(char : Char)
      r = char.ord
      # run a binary search
      f = 0
      t = Grapheme.codepoints.size
      while t > f
        mid = (f + t) // 2
        cp = Grapheme.codepoints[mid]
        if r < cp[0]
          t = mid
          next
        end
        if r > cp[1]
          f = mid + 1
          next
        end
        return cp[2]
      end
      Property::Any
    end
  end

  # Maps code point ranges to their properties. In the context of this package,
  # any code point that is not contained may map to `Property::Any`. The code point
  # ranges in this slice are numerically sorted.
  #
  # These ranges were taken from
  # http://www.unicode.org/Public/<%= Unicode::VERSION %>/ucd/auxiliary/GraphemeBreakProperty.txt
  # as well as
  # http://www.unicode.org/Public/<%= Unicode::VERSION %>/ucd/emoji/emoji-data.txt
  # ("Extended_Pictographic" only). See
  # https://www.unicode.org/license.html for the Unicode license agreement.
  @@codepoints : Array(Tuple(Int32, Int32, Property))?

  # :nodoc:
  protected def self.codepoints
    @@codepoints||= begin
      data = Array(Tuple(Int32, Int32, Property)).new(<%= props_data.size %>)
      <%- props_data.each do |range| -%>
        put(data, <%= sprintf("0x%04X", range.low) %>, <%= sprintf("0x%04X", range.high) %>, Property::<%= range.prop %>)
      <%- end -%>
      data
    end
  end

  private def self.put(array : Array, *values) : Nil
    array << values
  end
end
