module Sass::Script::Value
  # A SassScript object representing a number.
  # SassScript numbers can have decimal values,
  # and can also have units.
  # For example, `12`, `1px`, and `10.45em`
  # are all valid values.
  #
  # Numbers can also have more complex units, such as `1px*em/in`.
  # These cannot be inputted directly in Sass code at the moment.
  class Number < Base
    # The Ruby value of the number.
    #
    # @return [Numeric]
    attr_reader :value

    # A list of units in the numerator of the number.
    # For example, `1px*em/in*cm` would return `["px", "em"]`
    # @return [Array<String>]
    attr_reader :numerator_units

    # A list of units in the denominator of the number.
    # For example, `1px*em/in*cm` would return `["in", "cm"]`
    # @return [Array<String>]
    attr_reader :denominator_units

    # The original representation of this number.
    # For example, although the result of `1px/2px` is `0.5`,
    # the value of `#original` is `"1px/2px"`.
    #
    # This is only non-nil when the original value should be used as the CSS value,
    # as in `font: 1px/2px`.
    #
    # @return [Boolean, nil]
    attr_accessor :original

    def self.precision
      Thread.current[:sass_numeric_precision] || Thread.main[:sass_numeric_precision] || 10
    end

    # Sets the number of digits of precision
    # For example, if this is `3`,
    # `3.1415926` will be printed as `3.142`.
    # The numeric precision is stored as a thread local for thread safety reasons.
    # To set for all threads, be sure to set the precision on the main thread.
    def self.precision=(digits)
      Thread.current[:sass_numeric_precision] = digits.round
      Thread.current[:sass_numeric_precision_factor] = nil
      Thread.current[:sass_numeric_epsilon] = nil
    end

    # the precision factor used in numeric output
    # it is derived from the `precision` method.
    def self.precision_factor
      Thread.current[:sass_numeric_precision_factor] ||= 10.0**precision
    end

    # Used in checking equality of floating point numbers. Any
    # numbers within an `epsilon` of each other are considered functionally equal.
    # The value for epsilon is one tenth of the current numeric precision.
    def self.epsilon
      Thread.current[:sass_numeric_epsilon] ||= 1 / (precision_factor * 10)
    end

    # Used so we don't allocate two new arrays for each new number.
    NO_UNITS = []

    # @param value [Numeric] The value of the number
    # @param numerator_units [::String, Array<::String>] See \{#numerator\_units}
    # @param denominator_units [::String, Array<::String>] See \{#denominator\_units}
    def initialize(value, numerator_units = NO_UNITS, denominator_units = NO_UNITS)
      numerator_units = [numerator_units] if numerator_units.is_a?(::String)
      denominator_units = [denominator_units] if denominator_units.is_a?(::String)
      super(value)
      @numerator_units = numerator_units
      @denominator_units = denominator_units
      @options = nil
      normalize!
    end

    # The SassScript `+` operation.
    # Its functionality depends on the type of its argument:
    #
    # {Number}
    # : Adds the two numbers together, converting units if possible.
    #
    # {Color}
    # : Adds this number to each of the RGB color channels.
    #
    # {Value}
    # : See {Value::Base#plus}.
    #
    # @param other [Value] The right-hand side of the operator
    # @return [Value] The result of the operation
    # @raise [Sass::UnitConversionError] if `other` is a number with incompatible units
    def plus(other)
      if other.is_a? Number
        operate(other, :+)
      elsif other.is_a?(Color)
        other.plus(self)
      else
        super
      end
    end

    # The SassScript binary `-` operation (e.g. `$a - $b`).
    # Its functionality depends on the type of its argument:
    #
    # {Number}
    # : Subtracts this number from the other, converting units if possible.
    #
    # {Value}
    # : See {Value::Base#minus}.
    #
    # @param other [Value] The right-hand side of the operator
    # @return [Value] The result of the operation
    # @raise [Sass::UnitConversionError] if `other` is a number with incompatible units
    def minus(other)
      if other.is_a? Number
        operate(other, :-)
      else
        super
      end
    end

    # The SassScript unary `+` operation (e.g. `+$a`).
    #
    # @return [Number] The value of this number
    def unary_plus
      self
    end

    # The SassScript unary `-` operation (e.g. `-$a`).
    #
    # @return [Number] The negative value of this number
    def unary_minus
      Number.new(-value, @numerator_units, @denominator_units)
    end

    # The SassScript `*` operation.
    # Its functionality depends on the type of its argument:
    #
    # {Number}
    # : Multiplies the two numbers together, converting units appropriately.
    #
    # {Color}
    # : Multiplies each of the RGB color channels by this number.
    #
    # @param other [Number, Color] The right-hand side of the operator
    # @return [Number, Color] The result of the operation
    # @raise [NoMethodError] if `other` is an invalid type
    def times(other)
      if other.is_a? Number
        operate(other, :*)
      elsif other.is_a? Color
        other.times(self)
      else
        raise NoMethodError.new(nil, :times)
      end
    end

    # The SassScript `/` operation.
    # Its functionality depends on the type of its argument:
    #
    # {Number}
    # : Divides this number by the other, converting units appropriately.
    #
    # {Value}
    # : See {Value::Base#div}.
    #
    # @param other [Value] The right-hand side of the operator
    # @return [Value] The result of the operation
    def div(other)
      if other.is_a? Number
        res = operate(other, :/)
        if original && other.original
          res.original = "#{original}/#{other.original}"
        end
        res
      else
        super
      end
    end

    # The SassScript `%` operation.
    #
    # @param other [Number] The right-hand side of the operator
    # @return [Number] This number modulo the other
    # @raise [NoMethodError] if `other` is an invalid type
    # @raise [Sass::UnitConversionError] if `other` has incompatible units
    def mod(other)
      if other.is_a?(Number)
        operate(other, :%)
      else
        raise NoMethodError.new(nil, :mod)
      end
    end

    # The SassScript `==` operation.
    #
    # @param other [Value] The right-hand side of the operator
    # @return [Boolean] Whether this number is equal to the other object
    def eq(other)
      return Bool::FALSE unless other.is_a?(Sass::Script::Value::Number)
      this = self
      begin
        if unitless?
          this = this.coerce(other.numerator_units, other.denominator_units)
        else
          other = other.coerce(@numerator_units, @denominator_units)
        end
      rescue Sass::UnitConversionError
        return Bool::FALSE
      end
      Bool.new(basically_equal?(this.value, other.value))
    end

    def hash
      [value, numerator_units, denominator_units].hash
    end

    # Hash-equality works differently than `==` equality for numbers.
    # Hash-equality must be transitive, so it just compares the exact value,
    # numerator units, and denominator units.
    def eql?(other)
      basically_equal?(value, other.value) && numerator_units == other.numerator_units &&
        denominator_units == other.denominator_units
    end

    # The SassScript `>` operation.
    #
    # @param other [Number] The right-hand side of the operator
    # @return [Boolean] Whether this number is greater than the other
    # @raise [NoMethodError] if `other` is an invalid type
    def gt(other)
      raise NoMethodError.new(nil, :gt) unless other.is_a?(Number)
      operate(other, :>)
    end

    # The SassScript `>=` operation.
    #
    # @param other [Number] The right-hand side of the operator
    # @return [Boolean] Whether this number is greater than or equal to the other
    # @raise [NoMethodError] if `other` is an invalid type
    def gte(other)
      raise NoMethodError.new(nil, :gte) unless other.is_a?(Number)
      operate(other, :>=)
    end

    # The SassScript `<` operation.
    #
    # @param other [Number] The right-hand side of the operator
    # @return [Boolean] Whether this number is less than the other
    # @raise [NoMethodError] if `other` is an invalid type
    def lt(other)
      raise NoMethodError.new(nil, :lt) unless other.is_a?(Number)
      operate(other, :<)
    end

    # The SassScript `<=` operation.
    #
    # @param other [Number] The right-hand side of the operator
    # @return [Boolean] Whether this number is less than or equal to the other
    # @raise [NoMethodError] if `other` is an invalid type
    def lte(other)
      raise NoMethodError.new(nil, :lte) unless other.is_a?(Number)
      operate(other, :<=)
    end

    # @return [String] The CSS representation of this number
    # @raise [Sass::SyntaxError] if this number has units that can't be used in CSS
    #   (e.g. `px*in`)
    def to_s(opts = {})
      return original if original
      raise Sass::SyntaxError.new("#{inspect} isn't a valid CSS value.") unless legal_units?
      inspect
    end

    # Returns a readable representation of this number.
    #
    # This representation is valid CSS (and valid SassScript)
    # as long as there is only one unit.
    #
    # @return [String] The representation
    def inspect(opts = {})
      return original if original

      value = self.class.round(self.value)
      str = value.to_s

      # Ruby will occasionally print in scientific notation if the number is
      # small enough. That's technically valid CSS, but it's not well-supported
      # and confusing.
      str = ("%0.#{self.class.precision}f" % value).gsub(/0*$/, '') if str.include?('e')

      # Sometimes numeric formatting will result in a decimal number with a trailing zero (x.0)
      if str =~ /(.*)\.0$/
        str = $1
      end

      # We omit a leading zero before the decimal point in compressed mode.
      if @options && options[:style] == :compressed
        str.sub!(/^(-)?0\./, '\1.')
      end

      unitless? ? str : "#{str}#{unit_str}"
    end
    alias_method :to_sass, :inspect

    # @return [Integer] The integer value of the number
    # @raise [Sass::SyntaxError] if the number isn't an integer
    def to_i
      super unless int?
      value.to_i
    end

    # @return [Boolean] Whether or not this number is an integer.
    def int?
      basically_equal?(value % 1, 0.0)
    end

    # @return [Boolean] Whether or not this number has no units.
    def unitless?
      @numerator_units.empty? && @denominator_units.empty?
    end

    # Checks whether the number has the numerator unit specified.
    #
    # @example
    #   number = Sass::Script::Value::Number.new(10, "px")
    #   number.is_unit?("px") => true
    #   number.is_unit?(nil) => false
    #
    # @param unit [::String, nil] The unit the number should have or nil if the number
    #   should be unitless.
    # @see Number#unitless? The unitless? method may be more readable.
    def is_unit?(unit)
      if unit
        denominator_units.size == 0 && numerator_units.size == 1 && numerator_units.first == unit
      else
        unitless?
      end
    end

    # @return [Boolean] Whether or not this number has units that can be represented in CSS
    #   (that is, zero or one \{#numerator\_units}).
    def legal_units?
      (@numerator_units.empty? || @numerator_units.size == 1) && @denominator_units.empty?
    end

    # Returns this number converted to other units.
    # The conversion takes into account the relationship between e.g. mm and cm,
    # as well as between e.g. in and cm.
    #
    # If this number has no units, it will simply return itself
    # with the given units.
    #
    # An incompatible coercion, e.g. between px and cm, will raise an error.
    #
    # @param num_units [Array<String>] The numerator units to coerce this number into.
    #   See {\#numerator\_units}
    # @param den_units [Array<String>] The denominator units to coerce this number into.
    #   See {\#denominator\_units}
    # @return [Number] The number with the new units
    # @raise [Sass::UnitConversionError] if the given units are incompatible with the number's
    #   current units
    def coerce(num_units, den_units)
      Number.new(if unitless?
                   value
                 else
                   value * coercion_factor(@numerator_units, num_units) /
                     coercion_factor(@denominator_units, den_units)
                 end, num_units, den_units)
    end

    # @param other [Number] A number to decide if it can be compared with this number.
    # @return [Boolean] Whether or not this number can be compared with the other.
    def comparable_to?(other)
      operate(other, :+)
      true
    rescue Sass::UnitConversionError
      false
    end

    # Returns a human readable representation of the units in this number.
    # For complex units this takes the form of:
    # numerator_unit1 * numerator_unit2 / denominator_unit1 * denominator_unit2
    # @return [String] a string that represents the units in this number
    def unit_str
      rv = @numerator_units.sort.join("*")
      if @denominator_units.any?
        rv << "/"
        rv << @denominator_units.sort.join("*")
      end
      rv
    end

    private

    # @private
    # @see Sass::Script::Number.basically_equal?
    def basically_equal?(num1, num2)
      self.class.basically_equal?(num1, num2)
    end

    # Checks whether two numbers are within an epsilon of each other.
    # @return [Boolean]
    def self.basically_equal?(num1, num2)
      (num1 - num2).abs < epsilon
    end

    # @private
    def self.round(num)
      if num.is_a?(Float) && (num.infinite? || num.nan?)
        num
      elsif basically_equal?(num % 1, 0.0)
        num.round
      else
        ((num * precision_factor).round / precision_factor).to_f
      end
    end

    OPERATIONS = [:+, :-, :<=, :<, :>, :>=, :%]

    def operate(other, operation)
      this = self
      if OPERATIONS.include?(operation)
        if unitless?
          this = this.coerce(other.numerator_units, other.denominator_units)
        else
          other = other.coerce(@numerator_units, @denominator_units)
        end
      end
      # avoid integer division
      value = :/ == operation ? this.value.to_f : this.value
      result = value.send(operation, other.value)

      if result.is_a?(Numeric)
        Number.new(result, *compute_units(this, other, operation))
      else # Boolean op
        Bool.new(result)
      end
    end

    def coercion_factor(from_units, to_units)
      # get a list of unmatched units
      from_units, to_units = sans_common_units(from_units, to_units)

      if from_units.size != to_units.size || !convertable?(from_units | to_units)
        raise Sass::UnitConversionError.new(
          "Incompatible units: '#{from_units.join('*')}' and '#{to_units.join('*')}'.")
      end

      from_units.zip(to_units).inject(1) {|m, p| m * conversion_factor(p[0], p[1])}
    end

    def compute_units(this, other, operation)
      case operation
      when :*
        [this.numerator_units + other.numerator_units,
         this.denominator_units + other.denominator_units]
      when :/
        [this.numerator_units + other.denominator_units,
         this.denominator_units + other.numerator_units]
      else
        [this.numerator_units, this.denominator_units]
      end
    end

    def normalize!
      return if unitless?
      @numerator_units, @denominator_units =
        sans_common_units(@numerator_units, @denominator_units)

      @denominator_units.each_with_index do |d, i|
        next unless convertable?(d) && (u = @numerator_units.find(&method(:convertable?)))
        @value /= conversion_factor(d, u)
        @denominator_units.delete_at(i)
        @numerator_units.delete_at(@numerator_units.index(u))
      end
    end

    # This is the source data for all the unit logic. It's pre-processed to make
    # it efficient to figure out whether a set of units is mutually compatible
    # and what the conversion ratio is between two units.
    #
    # These come from http://www.w3.org/TR/2012/WD-css3-values-20120308/.
    relative_sizes = [
      {
        'in' => Rational(1),
        'cm' => Rational(1, 2.54),
        'pc' => Rational(1, 6),
        'mm' => Rational(1, 25.4),
        'q' => Rational(1, 101.6),
        'pt' => Rational(1, 72),
        'px' => Rational(1, 96)
      },
      {
        'deg'  => Rational(1, 360),
        'grad' => Rational(1, 400),
        'rad'  => Rational(1, 2 * Math::PI),
        'turn' => Rational(1)
      },
      {
        's'  => Rational(1),
        'ms' => Rational(1, 1000)
      },
      {
        'Hz'  => Rational(1),
        'kHz' => Rational(1000)
      },
      {
        'dpi'  => Rational(1),
        'dpcm' => Rational(254, 100),
        'dppx' => Rational(96)
      }
    ]

    # A hash from each known unit to the set of units that it's mutually
    # convertible with.
    MUTUALLY_CONVERTIBLE = {}
    relative_sizes.map do |values|
      set = values.keys.to_set
      values.keys.each {|name| MUTUALLY_CONVERTIBLE[name] = set}
    end

    # A two-dimensional hash from two units to the conversion ratio between
    # them. Multiply `X` by `CONVERSION_TABLE[X][Y]` to convert it to `Y`.
    CONVERSION_TABLE = {}
    relative_sizes.each do |values|
      values.each do |(name1, value1)|
        CONVERSION_TABLE[name1] ||= {}
        values.each do |(name2, value2)|
          value = value1 / value2
          CONVERSION_TABLE[name1][name2] = value.denominator == 1 ? value.to_i : value.to_f
        end
      end
    end

    def conversion_factor(from_unit, to_unit)
      CONVERSION_TABLE[from_unit][to_unit]
    end

    def convertable?(units)
      units = Array(units).to_set
      return true if units.empty?
      return false unless (mutually_convertible = MUTUALLY_CONVERTIBLE[units.first])
      units.subset?(mutually_convertible)
    end

    def sans_common_units(units1, units2)
      units2 = units2.dup
      # Can't just use -, because we want px*px to coerce properly to px*mm
      units1 = units1.map do |u|
        j = units2.index(u)
        next u unless j
        units2.delete_at(j)
        nil
      end
      units1.compact!
      return units1, units2
    end
  end
end
