# frozen_string_literal: true module Vedeu module Cursors # Crudely corrects out of range values. # # @api private # class Coordinate extend Forwardable def_delegators :coordinate, :d, :bd, :bdn, :d_dn # Return a new instance of Vedeu::Cursors::Coordinate. # # @param attributes [Hash Fixnum|String|Symbol>] # @option attributes geometry [Vedeu::Geometries::Geometry] # @option attributes type [Symbol] # @option attributes offset [Fixnum] # @return [Vedeu::Cursors::Coordinate] def initialize(attributes = {}) defaults.merge!(attributes).each do |key, value| instance_variable_set("@#{key}", value) end end # Returns the maximum coordinate for an area. # # @example # # d = 2 # # d_dn = 4 # represents width or height # dn # => 6 # # @return [Fixnum] def dn_position return 0 if d_dn <= 0 d + d_dn end alias xn dn_position alias yn dn_position # Returns the coordinate for a given index. # # @example # # d_range = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13] # position # => 4 # position(-2) # => 4 # position(2) # => 6 # position(15) # => 13 # # @return [Fixnum] def d_position Vedeu::Point.coerce(value: position, min: bd, max: bdn).value end alias x d_position alias y d_position protected # @!attribute [r] geometry # @return [Vedeu::Geometries::Geometry] attr_reader :geometry # @!attribute [r] offset # @return [Fixnum] attr_reader :offset # @!attribute [r] type # @return [Symbol] attr_reader :type private # @macro raise_invalid_syntax # @return [Vedeu::XCoordinate|Vedeu::YCoordinate] def coordinate @_coordinate ||= case type when :x then Vedeu::XCoordinate.new(geometry) when :y then Vedeu::YCoordinate.new(geometry) else raise Vedeu::Error::InvalidSyntax, 'Coordinate type not given, cannot continue.' end end # Returns the maximum index for an area. # # @example # # d_dn = 3 # dn_index # => 2 # # @return [Fixnum] def dn_index return 0 if d_dn < 1 d_dn - 1 end # Returns an array with all coordinates from d to dn. # # @example # # d_dn = 10 # # d = 4 # # dn = 14 # d_range # => [4, 5, 6, 7, 8, 9, 10, 11, 12, 13] # # @return [Array] def d_range (d...dn_position).to_a end # @macro defaults_method def defaults { geometry: nil, offset: nil, type: :x, } end # Return the position respective of the offset. # # @return [Fixnum] def position if offset <= 0 d elsif offset > dn_index dn_position else d_range[offset] end end end # Coordinate end # Cursors end # Vedeu