app/models/coupdoeil/popover/options_set.rb



# frozen_string_literal: true

module Coupdoeil
  class Popover
    class OptionsSet
      ORDERED_OPTIONS = [
        Option::Offset,
        Option::Placement,
        Option::Animation,
        Option::OpeningDelay,
        Option::Cache,
        Option::Loading,
        Option::Trigger,
      ].freeze

      OPTION_NAMES = ORDERED_OPTIONS.map(&:key)

      attr_reader :options

      def dup = OptionsSet.new(options.deep_dup)
      def preload? = options[:loading].to_s == "preload"
      def custom_animation? = options[:animation].to_s == "custom"
      def to_h = options

      def initialize(options = {})
        options.assert_valid_keys(OPTION_NAMES)

        @options = options
      end

      def merge(options_set)
        OptionsSet.new(options.merge(options_set.options))
      end

      if Rails.env.local?
        def validate!
          ORDERED_OPTIONS.map do |option|
            next unless options.key?(option.key)

            value = options[option.key]
            option.new(value).validate!
          end
        end
      else
        def validate! = nil # no-op
      end

      def to_base36
        @to_base36 ||= begin
          shift = 0
          ORDERED_OPTIONS.reverse.sum do |option|
            bits = option.into_bits(options[option.key])
            result = bits << shift
            shift += option.bit_size
            result
          end.to_s(36).freeze
        end
      end
    end
  end
end