# frozen_string_literal: true

require_relative 'subset'

module TTFunk
  class SubsetCollection
    def initialize(original)
      @original = original
      @subsets = [Subset.for(@original, :mac_roman)]
    end

    def [](subset)
      @subsets[subset]
    end

    # +characters+ should be an array of UTF-16 characters
    def use(characters)
      characters.each do |char|
        covered = false
        @subsets.each_with_index do |subset, _i|
          next unless subset.covers?(char)

          subset.use(char)
          covered = true
          break
        end

        unless covered
          @subsets << Subset.for(@original, :unicode_8bit)
          @subsets.last.use(char)
        end
      end
    end

    # +characters+ should be an array of UTF-16 characters. Returns
    # an array of subset chunks, where each chunk is another array of
    # two elements. The first element is the subset number, and the
    # second element is the string of characters to render with that
    # font subset. The strings will be encoded for their subset font,
    # and so may not look (in the raw) like what was passed in, but
    # they will render correctly with the indicated subset font.
    def encode(characters)
      return [] if characters.empty?

      # TODO: probably would be more optimal to nix the #use method,
      # and merge it into this one, so it can be done in a single
      # pass instead of two passes.
      use(characters)

      parts = []
      current_subset = 0
      current_char = 0
      char = characters[current_char]

      loop do
        while @subsets[current_subset].includes?(char)
          char = @subsets[current_subset].from_unicode(char)

          if parts.empty? || parts.last[0] != current_subset
            encoded_char = char.chr
            if encoded_char.respond_to?(:force_encoding)
              encoded_char.force_encoding('ASCII-8BIT')
            end
            parts << [current_subset, encoded_char]
          else
            parts.last[1] << char
          end

          current_char += 1
          return parts if current_char >= characters.length

          char = characters[current_char]
        end

        current_subset = (current_subset + 1) % @subsets.length
      end
    end
  end
end
