/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
 * This file is part of the libe-book project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <deque>

#include <librevenge/librevenge.h>

#include "FB2Collector.h"
#include "FB2MetadataContext.h"
#include "FB2Token.h"

namespace libebook
{

class FB2Authors
{
public:
  struct Data
  {
    Data();

    librevenge::RVNGString firstName;
    librevenge::RVNGString middleName;
    librevenge::RVNGString lastName;
    librevenge::RVNGString nickname;
  };

  FB2Authors();

  void setFirstName(const librevenge::RVNGString &name);
  void setMiddleName(const librevenge::RVNGString &name);
  void setLastName(const librevenge::RVNGString &name);
  void setNickname(const librevenge::RVNGString &name);
  void finishAuthor();

  const std::deque<Data> &getAuthors() const;

private:
  std::deque<Data> m_authors;
  Data m_current;
};

}

namespace libebook
{

FB2Authors::Data::Data()
  : firstName()
  , middleName()
  , lastName()
  , nickname()
{
}

FB2Authors::FB2Authors()
  : m_authors()
  , m_current()
{
}

void FB2Authors::setFirstName(const librevenge::RVNGString &name)
{
  m_current.firstName = name;
}

void FB2Authors::setMiddleName(const librevenge::RVNGString &name)
{
  m_current.middleName = name;
}

void FB2Authors::setLastName(const librevenge::RVNGString &name)
{
  m_current.lastName = name;
}

void FB2Authors::setNickname(const librevenge::RVNGString &name)
{
  m_current.nickname = name;
}

void FB2Authors::finishAuthor()
{
  m_authors.push_back(m_current);
  m_current = Data();
}

const std::deque<FB2Authors::Data> &FB2Authors::getAuthors() const
{
  return m_authors;
}

}

namespace libebook
{

FB2AnnotationContext::FB2AnnotationContext(FB2ParserContext *parentContext, const FB2BlockFormat &format)
  : FB2BlockFormatContextBase(parentContext, format)
{
}

FB2XMLParserContext *FB2AnnotationContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2AnnotationContext::startOfElement()
{
  // TODO: implement me
}

void FB2AnnotationContext::endOfElement()
{
  // TODO: implement me
}

void FB2AnnotationContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2AnnotationContext::text(const char *)
{
}

FB2AuthorContext::FB2AuthorContext(FB2ParserContext *parentContext, FB2Authors &authors)
  : FB2ParserContext(parentContext)
  , m_authors(authors)
{
}

FB2XMLParserContext *FB2AuthorContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    case FB2Token::first_name :
      return new FB2FirstNameContext(this, m_authors);
    case FB2Token::middle_name :
      return new FB2MiddleNameContext(this, m_authors);
    case FB2Token::last_name :
      return new FB2LastNameContext(this, m_authors);
    case FB2Token::nickname :
      return new FB2NicknameContext(this, m_authors);
    case FB2Token::email :
    case FB2Token::home_page :
      // ignore
      break;
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2AuthorContext::startOfElement()
{
}

void FB2AuthorContext::endOfElement()
{
  m_authors.finishAuthor();
}

void FB2AuthorContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2AuthorContext::text(const char *)
{
}

FB2BookNameContext::FB2BookNameContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2BookNameContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2BookNameContext::startOfElement()
{
  // TODO: implement me
}

void FB2BookNameContext::endOfElement()
{
  // TODO: implement me
}

void FB2BookNameContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2BookNameContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2BookTitleContext::FB2BookTitleContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2BookTitleContext::element(const FB2TokenData &, const FB2TokenData &)
{
  return 0;
}

void FB2BookTitleContext::startOfElement()
{
}

void FB2BookTitleContext::endOfElement()
{
}

void FB2BookTitleContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2BookTitleContext::text(const char *value)
{
  getCollector()->defineMetadataEntry("dc:subject", value);
}

FB2CityContext::FB2CityContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2CityContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2CityContext::startOfElement()
{
  // TODO: implement me
}

void FB2CityContext::endOfElement()
{
  // TODO: implement me
}

void FB2CityContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2CityContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2CoverpageContext::FB2CoverpageContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2CoverpageContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2CoverpageContext::startOfElement()
{
  // TODO: implement me
}

void FB2CoverpageContext::endOfElement()
{
  // TODO: implement me
}

void FB2CoverpageContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2CoverpageContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2CustomInfoContext::FB2CustomInfoContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
  , m_type()
  , m_text()
{
}

FB2XMLParserContext *FB2CustomInfoContext::element(const FB2TokenData &, const FB2TokenData &)
{
  return 0;
}

void FB2CustomInfoContext::startOfElement()
{
}

void FB2CustomInfoContext::endOfElement()
{
  librevenge::RVNGString info(m_type);
  info.append(": ");
  info.append(m_text);
  // TODO: there might be more than one comment. Must properties be unique?
  getCollector()->defineMetadataEntry("librevenge:comments", info.cstr());
}

void FB2CustomInfoContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    case FB2Token::info_type :
      m_type = value;
    default :
      break;
    }
  }
}

void FB2CustomInfoContext::text(const char *value)
{
  m_text = value;
}

FB2DateContext::FB2DateContext(FB2ParserContext *const parentContext, const char *const name)
  : FB2ParserContext(parentContext)
  , m_name(name)
{
}

FB2XMLParserContext *FB2DateContext::element(const FB2TokenData &, const FB2TokenData &)
{
  return 0;
}

void FB2DateContext::startOfElement()
{
}

void FB2DateContext::endOfElement()
{
}

void FB2DateContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: should we use the computer-readable date from attribute, if
  // present?
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    case FB2Token::value :
      break;
    default :
      break;
    }
  }
}

void FB2DateContext::text(const char *value)
{
  getCollector()->defineMetadataEntry(m_name, value);
}

FB2DescriptionContext::FB2DescriptionContext(FB2ParserContext *const parentContext, FB2Collector *const collector)
  : FB2ParserContext(parentContext, collector)
{
}

FB2XMLParserContext *FB2DescriptionContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    case FB2Token::title_info :
      return new FB2TitleInfoContext(this);
    case FB2Token::src_title_info :
      // not interesting -> skip
      break;
    case FB2Token::document_info :
      return new TextInfoContext(this);
    case FB2Token::publish_info :
      return new FB2PublishInfoContext(this);
    case FB2Token::custom_info :
      return new FB2CustomInfoContext(this);
    case FB2Token::output :
      return new FB2OutputContext(this);
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2DescriptionContext::startOfElement()
{
}

void FB2DescriptionContext::endOfElement()
{
}

void FB2DescriptionContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2DescriptionContext::text(const char *)
{
}

TextInfoContext::TextInfoContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
  , m_authors(new FB2Authors())
{
}

TextInfoContext::~TextInfoContext()
{
  delete m_authors;
}

FB2XMLParserContext *TextInfoContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    case FB2Token::author :
      return new FB2AuthorContext(this, *m_authors);
    case FB2Token::date :
      return new FB2DateContext(this, "dcterms:issued");
    case FB2Token::src_url :
      return new FB2SrcUrlContext(this);
    case FB2Token::version :
      return new FB2VersionContext(this);
    case FB2Token::history :
      return new FB2HistoryContext(this);
    case FB2Token::id :
    case FB2Token::program_used :
    // ignore
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void TextInfoContext::startOfElement()
{
}

void TextInfoContext::endOfElement()
{
  // TODO: handle authors
}

void TextInfoContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void TextInfoContext::text(const char *)
{
}

FB2EmailContext::FB2EmailContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2EmailContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2EmailContext::startOfElement()
{
  // TODO: implement me
}

void FB2EmailContext::endOfElement()
{
  // TODO: implement me
}

void FB2EmailContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2EmailContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2FirstNameContext::FB2FirstNameContext(FB2ParserContext *parentContext, FB2Authors &authors)
  : FB2ParserContext(parentContext)
  , m_authors(authors)
{
}

FB2XMLParserContext *FB2FirstNameContext::element(const FB2TokenData &, const FB2TokenData &)
{
  return 0;
}

void FB2FirstNameContext::startOfElement()
{
}

void FB2FirstNameContext::endOfElement()
{
}

void FB2FirstNameContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2FirstNameContext::text(const char *value)
{
  const librevenge::RVNGString str(value);
  m_authors.setFirstName(str);
}

FB2GenreContext::FB2GenreContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2GenreContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2GenreContext::startOfElement()
{
  // TODO: implement me
}

void FB2GenreContext::endOfElement()
{
  // TODO: implement me
}

void FB2GenreContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2GenreContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2HistoryContext::FB2HistoryContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2HistoryContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2HistoryContext::startOfElement()
{
  // TODO: implement me
}

void FB2HistoryContext::endOfElement()
{
  // TODO: implement me
}

void FB2HistoryContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2HistoryContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2HomePageContext::FB2HomePageContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2HomePageContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2HomePageContext::startOfElement()
{
  // TODO: implement me
}

void FB2HomePageContext::endOfElement()
{
  // TODO: implement me
}

void FB2HomePageContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2HomePageContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2IdContext::FB2IdContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2IdContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2IdContext::startOfElement()
{
  // TODO: implement me
}

void FB2IdContext::endOfElement()
{
  // TODO: implement me
}

void FB2IdContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2IdContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2IsbnContext::FB2IsbnContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2IsbnContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2IsbnContext::startOfElement()
{
  // TODO: implement me
}

void FB2IsbnContext::endOfElement()
{
  // TODO: implement me
}

void FB2IsbnContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2IsbnContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2KeywordsContext::FB2KeywordsContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2KeywordsContext::element(const FB2TokenData &, const FB2TokenData &)
{
  return 0;
}

void FB2KeywordsContext::startOfElement()
{
}

void FB2KeywordsContext::endOfElement()
{
}

void FB2KeywordsContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2KeywordsContext::text(const char *value)
{
  getCollector()->defineMetadataEntry("meta:keyword", value);
}

FB2LangContext::FB2LangContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2LangContext::element(const FB2TokenData &, const FB2TokenData &)
{
  return 0;
}

void FB2LangContext::startOfElement()
{
}

void FB2LangContext::endOfElement()
{
}

void FB2LangContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2LangContext::text(const char *value)
{
  getCollector()->defineMetadataEntry("dc:language", value);
}

FB2LastNameContext::FB2LastNameContext(FB2ParserContext *parentContext, FB2Authors &authors)
  : FB2ParserContext(parentContext)
  , m_authors(authors)
{
}

FB2XMLParserContext *FB2LastNameContext::element(const FB2TokenData &, const FB2TokenData &)
{
  return 0;
}

void FB2LastNameContext::startOfElement()
{
}

void FB2LastNameContext::endOfElement()
{
}

void FB2LastNameContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2LastNameContext::text(const char *value)
{
  const librevenge::RVNGString str(value);
  m_authors.setLastName(str);
}

FB2MiddleNameContext::FB2MiddleNameContext(FB2ParserContext *parentContext, FB2Authors &authors)
  : FB2ParserContext(parentContext)
  , m_authors(authors)
{
}

FB2XMLParserContext *FB2MiddleNameContext::element(const FB2TokenData &, const FB2TokenData &)
{
  return 0;
}

void FB2MiddleNameContext::startOfElement()
{
}

void FB2MiddleNameContext::endOfElement()
{
}

void FB2MiddleNameContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2MiddleNameContext::text(const char *value)
{
  const librevenge::RVNGString str(value);
  m_authors.setMiddleName(str);
}

FB2NicknameContext::FB2NicknameContext(FB2ParserContext *parentContext, FB2Authors &authors)
  : FB2ParserContext(parentContext)
  , m_authors(authors)
{
}

FB2XMLParserContext *FB2NicknameContext::element(const FB2TokenData &, const FB2TokenData &)
{
  return 0;
}

void FB2NicknameContext::startOfElement()
{
}

void FB2NicknameContext::endOfElement()
{
}

void FB2NicknameContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2NicknameContext::text(const char *value)
{
  const librevenge::RVNGString str(value);
  m_authors.setNickname(str);
}

FB2OutputContext::FB2OutputContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2OutputContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2OutputContext::startOfElement()
{
  // TODO: implement me
}

void FB2OutputContext::endOfElement()
{
  // TODO: implement me
}

void FB2OutputContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2OutputContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2OutputDocumentClassContext::FB2OutputDocumentClassContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2OutputDocumentClassContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2OutputDocumentClassContext::startOfElement()
{
  // TODO: implement me
}

void FB2OutputDocumentClassContext::endOfElement()
{
  // TODO: implement me
}

void FB2OutputDocumentClassContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2OutputDocumentClassContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2PartContext::FB2PartContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2PartContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2PartContext::startOfElement()
{
  // TODO: implement me
}

void FB2PartContext::endOfElement()
{
  // TODO: implement me
}

void FB2PartContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2PartContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2ProgramUsedContext::FB2ProgramUsedContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2ProgramUsedContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2ProgramUsedContext::startOfElement()
{
  // TODO: implement me
}

void FB2ProgramUsedContext::endOfElement()
{
  // TODO: implement me
}

void FB2ProgramUsedContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2ProgramUsedContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2PublisherContext::FB2PublisherContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2PublisherContext::element(const FB2TokenData &, const FB2TokenData &)
{
  return 0;
}

void FB2PublisherContext::startOfElement()
{
}

void FB2PublisherContext::endOfElement()
{
}

void FB2PublisherContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2PublisherContext::text(const char *value)
{
  getCollector()->defineMetadataEntry("dc:publisher", value);
}

FB2PublishInfoContext::FB2PublishInfoContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2PublishInfoContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    case FB2Token::publisher :
      return new FB2PublisherContext(this);
    case FB2Token::book_name :
    case FB2Token::city :
    case FB2Token::isbn :
    case FB2Token::sequence :
    case FB2Token::year :
      // ignore
      break;
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2PublishInfoContext::startOfElement()
{
}

void FB2PublishInfoContext::endOfElement()
{
}

void FB2PublishInfoContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2PublishInfoContext::text(const char *)
{
}

FB2SequenceContext::FB2SequenceContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2SequenceContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2SequenceContext::startOfElement()
{
  // TODO: implement me
}

void FB2SequenceContext::endOfElement()
{
  // TODO: implement me
}

void FB2SequenceContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2SequenceContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2SrcLangContext::FB2SrcLangContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2SrcLangContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2SrcLangContext::startOfElement()
{
  // TODO: implement me
}

void FB2SrcLangContext::endOfElement()
{
  // TODO: implement me
}

void FB2SrcLangContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2SrcLangContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2SrcOcrContext::FB2SrcOcrContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2SrcOcrContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2SrcOcrContext::startOfElement()
{
  // TODO: implement me
}

void FB2SrcOcrContext::endOfElement()
{
  // TODO: implement me
}

void FB2SrcOcrContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2SrcOcrContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2SrcTitleInfoContext::FB2SrcTitleInfoContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2SrcTitleInfoContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2SrcTitleInfoContext::startOfElement()
{
  // TODO: implement me
}

void FB2SrcTitleInfoContext::endOfElement()
{
  // TODO: implement me
}

void FB2SrcTitleInfoContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2SrcTitleInfoContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2SrcUrlContext::FB2SrcUrlContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2SrcUrlContext::element(const FB2TokenData &, const FB2TokenData &)
{
  return 0;
}

void FB2SrcUrlContext::startOfElement()
{
}

void FB2SrcUrlContext::endOfElement()
{
}

void FB2SrcUrlContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2SrcUrlContext::text(const char *value)
{
  getCollector()->defineMetadataEntry("dc:source", value);
}

FB2TitleInfoContext::FB2TitleInfoContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
  , m_authors(new FB2Authors())
{
}

FB2TitleInfoContext::~FB2TitleInfoContext()
{
  delete m_authors;
}

FB2XMLParserContext *FB2TitleInfoContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    case FB2Token::author :
      return new FB2AuthorContext(this, *m_authors);
    case FB2Token::book_title :
      return new FB2BookTitleContext(this);
    case FB2Token::keywords :
      return new FB2KeywordsContext(this);
    case FB2Token::date :
      return new FB2DateContext(this, "meta:creation-date");
    case FB2Token::coverpage :
      return new FB2CoverpageContext(this);
    case FB2Token::lang :
      return new FB2LangContext(this);
    case FB2Token::annotation :
    case FB2Token::genre :
    case FB2Token::sequence :
    case FB2Token::src_lang :
    case FB2Token::translator :
      // ignore
      break;
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2TitleInfoContext::startOfElement()
{
}

void FB2TitleInfoContext::endOfElement()
{
  typedef std::deque<FB2Authors::Data> Authors_t;
  const Authors_t authors = m_authors->getAuthors();
  librevenge::RVNGString authorsStr;
  for (Authors_t::const_iterator it = authors.begin(); it != authors.end(); ++it)
  {
    librevenge::RVNGString author;
    if (it->firstName.len() != 0)
    {
      author = it->firstName;
      if (it->middleName.len() != 0)
      {
        author.append(' ');
        author.append(it->middleName);
      }
      author.append(' ');
      author.append(it->lastName);
    }
    else
    {
      author = it->nickname;
    }

    // TODO: it would be better to push authors separately, if it's
    // possible
    if (author.len() != 0)
    {
      if (authorsStr.len() != 0)
        authorsStr.append(", ");
      authorsStr.append(author);
    }
  }

  if (authorsStr.len() != 0)
    getCollector()->defineMetadataEntry("meta:initial-creator", authorsStr.cstr());
}

void FB2TitleInfoContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2TitleInfoContext::text(const char *)
{
}

FB2TranslatorContext::FB2TranslatorContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2TranslatorContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2TranslatorContext::startOfElement()
{
  // TODO: implement me
}

void FB2TranslatorContext::endOfElement()
{
  // TODO: implement me
}

void FB2TranslatorContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2TranslatorContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

FB2VersionContext::FB2VersionContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2VersionContext::element(const FB2TokenData &, const FB2TokenData &)
{
  return 0;
}

void FB2VersionContext::startOfElement()
{
}

void FB2VersionContext::endOfElement()
{
}

void FB2VersionContext::attribute(const FB2TokenData &, const FB2TokenData *, const char *)
{
}

void FB2VersionContext::text(const char *value)
{
  getCollector()->defineMetadataEntry("librevenge:version-number", value);
}

FB2YearContext::FB2YearContext(FB2ParserContext *parentContext)
  : FB2ParserContext(parentContext)
{
}

FB2XMLParserContext *FB2YearContext::element(const FB2TokenData &name, const FB2TokenData &ns)
{
  // TODO: implement me
  if (FB2Token::NS_FICTIONBOOK == getFB2TokenID(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }

  return new FB2SkipElementContext(this);
}

void FB2YearContext::startOfElement()
{
  // TODO: implement me
}

void FB2YearContext::endOfElement()
{
  // TODO: implement me
}

void FB2YearContext::attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value)
{
  // TODO: implement me
  (void) value;
  if (FB2_NO_NAMESPACE(ns))
  {
    switch (getFB2TokenID(name))
    {
    default :
      break;
    }
  }
}

void FB2YearContext::text(const char *value)
{
  // TODO: implement me
  librevenge::RVNGString str(value);
  (void) str;
}

}

/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
