require 'element'
require 'rules'
require 'xmlns'
require 'module/anon'

class Listener
  attr_accessor :xmlbase, :name

  def initialize source
    @name = "<root>"
    @stack = [[Root.new(self,@name,{})]]
    parser = REXML::Parsers::SAX2Parser.new source
    parser.listen self
    parser.parse
  end

  def log *args
    STDERR.puts *args.inspect
  end

  def start_prefix_mapping prefix, uri
    prefix = Xmlns[uri]
    require "module/#{prefix}" if prefix
  end

  def method_missing symbol, *args
    @stack[-1].each {|handler| handler.send(symbol, *args)}
  end

  def start_element uri, localname, qname, attributes
    method_missing :start_element, uri, localname, qname, attributes

    list = []
    @stack[-1].each do |e|
      e.children.push qname
      e.element_rules(uri, localname, qname, attributes).each do |rule|
        list.push e.new_rule(rule,localname,attributes)
      end
    end

    attributes.each do |attr,value|
      if attr.split(':')[0] != 'xmlns':
        list.each do |e|
          e.attribute_rules(attr).each do |rule|
            e.new_rule(rule,attr,nil).validate value
          end
        end
      end
    end

    @stack.push list
  end

  def end_element *args
    method_missing :end_element, *args
    @stack.pop
  end
end
