module EPUB
  module Publication
    class Package
      class Guide
        include Inspector::PublicationModel
        attr_accessor :package, :references

        def initialize
          Reference::TYPES.each do |type|
            variable_name = '@' + type.gsub('-', '_')
            instance_variable_set variable_name, nil
          end
          @references = []
        end

        def <<(reference)
          reference.guide = self
          references << reference
        end

        class Reference
          TYPES = %w[cover title-page toc index glossary acknowledgements bibliography colophon copyright-page dedication epigraph foreword loi lot notes preface text]
          attr_accessor :guide,
                        :type, :title
          attr_reader :href

          def href=(iri)
            @href = iri.kind_of?(Addressable::URI) ? iri : Addressable::URI.parse(iri)
          end

          def item
            return @item if @item

            request_uri = href.request_uri
            @item = @guide.package.manifest.items.find {|item|
              item.href.request_uri == request_uri
            }
          end
        end

        Reference::TYPES.each do |type|
          method_name = type.gsub('-', '_')
          define_method method_name do
            var = instance_variable_get "@#{method_name}"
            return var if var

            var = references.find {|ref| ref.type == type}
            instance_variable_set "@#{method_name}", var
          end
        end
      end
    end
  end
end
