module Atom

  class Author < Element
    element :name
    element :uri, :rfc2396
    element :email
  end

  class Category < Element
    attribute :scheme, :rfc2396_full
    attribute :term
  end

  class Content < Element
    attribute :src, :rfc2396_attr
    attribute :type

    def select attrs
      case attrs['type']
        when nil, 'text': [:nonhtml]
        when 'html': [:ishtml]
        when 'xhtml': [XhtmlConstruct]
        else log :InvalidTextType; []
      end
    end
  end

  class XhtmlConstruct < Element
  end

  class TextConstruct < DiscriminatedUnion
    attribute :type

    def select attrs
      case attrs['type']
        when nil, 'text': [:nonhtml]
        when 'html': [:ishtml]
        when 'xhtml': [XhtmlConstruct]
        else log :InvalidTextType; []
      end
    end
  end

  class Generator < Element
    attribute :uri, :rfc2396_attr
    attribute :version
  end

  class Link < Element
    attribute :href, :rfc2396, :xmlbase
    attribute :hreflang
    attribute :length
    attribute :rel, :rfc2396_rel
    attribute :type
  end

  class Entry < Element
    element :author, Author
    element :category, Category
    element :content, Content
    element :contributor
    element :id, :rfc2396
    element :link, Link
    element :published, :rfc3339
    element :summary, TextConstruct
    element :title, TextConstruct, :nonblank
    element :updated, :rfc3339
  end

  class Feed < Element
    def initialize *args
       super
       @links = []
    end

    element :author, Author
    element :entry, Entry
    element :generator, Generator
    element :icon, :rfc2396
    element :id, :rfc2396
    element :link, Link
    element :logo, :rfc2396
    element :rights, TextConstruct
    element :subtitle, TextConstruct
    element :title, TextConstruct
    element :updated, :rfc3339

    def start_element uri, localname, qname, attrs
      if localname == 'link' and Xmlns[uri] == :atom
        copy = attrs.dup; copy['href'] = nil
        log :DuplicateAtomLink if @links.include? copy
        @links.push copy
      end
    end
  end

end


class Root < Element
  element :feed, Atom::Feed
  element :entry, Atom::Entry
end
