class OperaWatir::Element
  include Deprecated

  #
  # Gets the attribute called name.
  #
  # @param  [String, Symbol] name  The name of the attribute to get.
  # @return [String]               The value of the attribute.
  #

  def attr(name)
    node.getAttribute(name.to_s) || ''
  end

  #
  # Check the existence of the attribute on the element.
  #
  # @return [Boolean] True if the attribute exists on the element,
  #                   false otherwise.
  #

  def attr?(name)
    !node.getAttribute(name.to_s).nil?
  end

  def method_missing(name, *args, &blk)
    if !block_given? && args.empty?
      attr(name)
    else
      super
    end
  end

  #
  # Gets the text content of the element.
  #
  # @return [String] The text content.
  #

  def text
    if node.tag_name =~ /input|textarea|select/i
      node.value.strip
    else
      node.getText.strip
    end
  end

  #
  # Checks whether the text content of the element contains the given
  # string In the compatibility layer as the preferred way of doing
  # this is.
  #
  #   elm.text.should include('My string')
  #
  # @param [String]  String to search for.
  # @param [Boolean] True if the element's text contains str, false
  #                  otherwise.
  #

  def verify_contains(str)
    text.include?(str)
  end

  alias_method :verify_contains?, :verify_contains

  alias_method :caption, :text

  #
  # Clicks on the top left of the element, or the given x, y offset.
  # Asserts whether element is enabled first.
  #
  # @param [optional, Fixnum] x The offset from the left of the
  #   element
  # @param [optional, Fixnum] y The offset from the top of the element
  #

  def click(x=1, y=1)
    assert_enabled!
    node.click(x.to_i, y.to_i)
  end

  alias_method :click_no_wait, :click_async

  #
  # Focuses the element
  #

  def focus
    fire_event :focus
  end

  #
  # Submits a form, or the form the elment is contained in.
  #

  def submit
    assert_exists
    node.submit
  end

  #
  # Clears a text input or textarea of any text.
  #

  def clear
    assert_enabled!
    click
    node.clear
  end

  #
  # If passed a value it will type text into the element, otherwise it
  # will check a radio button or checkbox.
  #
  # @param [String] value  (Optional.) Text to type.
  #

  def set(value=nil)
    if value
      self.text = value
    else
      assert_enabled
      click_async
    end
  end

  #
  # Gets the href of an `<a>` element, or the url attribute of any
  # other element.
  #
  # @return [String] An href or the @url attribute.
  #

  def url
    attr(tag_name == 'A' ? :href : :url)
  end

  #
  # Gets the selected `<option>` elements in a `<select>` element.
  #
  # @return [Collection] a collection of the selected
  #                                  `<option>`s
  #

  def selected_options
    options(:selected?, true)
  end

  #
  # On checkboxes, radio buttons, and option elements returns whether
  # the element is checked/selected. On a select element, when passed
  # an value it checks whether the selected option contains the given
  # text.
  #
  # @param  [String]  value (Optional.) Text the selected option should
  #                         contain.
  # @return [Boolean]       True if the element is selected/selected
  #                         option contains value, false otherwise.
  #

  def selected?(value=nil)
    if option.nil?
      selected_options.text.include?(value)
    else
      node.isSelected
    end
  end

  alias_method :set?, :checked?

  #
  # For `<select>` elements returns either 'select-one' for
  # `<select>`s where only a single `<option>` can be selected, or
  # 'select-multiple' otherwise.  For non-`<select>` elements returns
  # the `type` attribute.
  #

  def type
    if tag_name == 'SELECT'
      attr(:multiple) == 'multiple' ? 'select-multiple' : 'select-one'
    else
      attr(:type)
    end
  end

  #
  # Gets the colspan attribute as an integer.
  #
  # @return [Fixnum] The colspan.
  #

  def colspan
    attr(:colspan).to_i
  end


  # Opera-specific
  def compare_hash(other)
    visual_hash == other.visual_hash
  end
  deprecated :compare_hash, 'element.visual_hash'

  alias_method :get_hash, :visual_hash
  deprecated :get_hash, 'element.visual_hash'

private

  def assert_enabled!
    raise OperaWatir::Exceptions::ObjectDisabledException if disabled?
  end

end