=begin
= WebUnit::HtmlElem
  Copyright(C) 2001 yuichi TAKAHASHI
  $Id: htmlelem.rb,v 1.1.1.1 2003/01/21 11:50:40 yuichi Exp $
=end

module WebUnit

  class HtmlElem

    attr_reader :tag, :data, :attrs, :children, :array, :name

    def initialize( tag, ah={} )
      @children = []
      @tag = tag
      @attrs = ah
      @data = ''
      @array = []
      @name = ah['name'] if ah
    end

    def append( data )
      if data.is_a?( HtmlElem )
        @children << data
      else
        @data  << data
      end
      @array << data
    end

    def extract
      data = ''
      @array.each do |e|
        if e.is_a?( String )
          data << " #{e} "
        elsif e.is_a?( HtmlElem )
          data << e.extract
        end
      end
      data.squeeze( ' ' ).strip
    end

    def inspect
      return "<#toplevel>" if @tag == nil
      as = ''
      attrs.each{ |k,v| as << " #{k}=#{v}" }
      "<#{@tag+as}>:#{data}:"
    end

=begin
--- HtmlElem#find(tag)
      return an Array of HtmlElems, which have ((|tag|)).
=end

    def find( tag )
      a = []
      a.push self if @tag == tag
      @children.each do |c|
        a = a + c.find( tag )
      end
      a
    end

=begin
--- HtmlElem#search(data)
      return an Array of HtmlElems, which have ((|data|)).
=end

    def search( data )
      a = []
      a.push self if @data == data
      @children.each do |c|
        a = a + c.search( data )
      end
      a
    end

=begin
--- HtmlElem#readlink(str)
      return a Response, gotten with reading a Link have ((|str|)).
      raise ElemNotFound exception, when no Links found.
=end

    def readlink( str )
      self.find( 'a' ).each do |link|
        return link.read if link.data == str
      end
      raise ElemNotFound, "no Links have '#{str}' as data."
    end

=begin
--- HtmlElem#has?(elem)
      return true, when self have ((|elem|)) as child.
      otherwise, return false.
      ((|elem|)) should be a HtmlElem or a String.
=end

    def has?( elem )
      if elem.kind_of?( HtmlElem )
        @children.include?( elem )
      elsif elem.instance_of?( String )
        @array.include?( elem )
      else
        false
      end
    end

=begin
--- HtmlElem#print(indent='') -- FOR TEST USE ONLY
     print tree structure, from self to lower.
=end

    def print( indent='' ) # not tested :-(
      puts indent + inspect
      @children.each do |c|
        c.print( indent + '  ' )
      end
    end

  end # class HtmlElem

end # module WebUnit
