/* -*- 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/.
 */

#ifndef FB2PARSERCONTEXT_H_INCLUDED
#define FB2PARSERCONTEXT_H_INCLUDED

#include "FB2XMLParserContext.h"
#include "FB2Style.h"

namespace libebook
{

class FB2Collector;

/** Base class for all contexts.
  */
class FB2ParserContext : public FB2XMLParserContext
{
  // no copying
  FB2ParserContext(const FB2ParserContext &other);
  FB2ParserContext &operator=(const FB2ParserContext &other);

public:
  /** Create a new context with @c parentContext as parent.
    *
    * @param[in] parentContext A parent context.
    * @param[in] collector A collector for the context's content.
    */
  explicit FB2ParserContext(FB2ParserContext *parentContext, FB2Collector *collector = 0);

  virtual FB2XMLParserContext *leaveContext() const;

  /** Get the collector.
    *
    * @return The collector.
    */
  FB2Collector *getCollector() const;

  /** Get the parent context.
    *
    * @return The parent context.
    */
  FB2ParserContext *getParentContext() const;

private:
  FB2Collector *const m_collector;
  FB2ParserContext *const m_parentContext;
};

/** Base class for non-leaf element contexts.
  *
  * It provides empty implementations for functions that are typically
  * not needed for processing non-leaf elements.
  */
class FB2NodeContextBase : public FB2ParserContext
{
public:
  explicit FB2NodeContextBase(FB2ParserContext *parentContext, FB2Collector *collector = 0);

private:
  virtual void startOfElement();
  virtual void endOfAttributes();
  virtual void text(const char *value);
};

/** Base class for leaf data element contexts.
  *
  * It provides empty implementations for functions that are typically
  * not needed for processing leaf data elements (i.e., empty elements
  * that only have attributes).
  *
  * @note The parser inserts an artificial endOfElement() call for empty
  * elements.
  */
class FB2DataContextBase : public FB2ParserContext
{
public:
  explicit FB2DataContextBase(FB2ParserContext *parentContext);

private:
  virtual FB2XMLParserContext *element(const FB2TokenData &name, const FB2TokenData &ns);
  virtual void startOfElement();
  virtual void endOfAttributes();
  virtual void text(const char *value);
};

/** Base class for leaf textual element contexts.
  *
  * It provides empty implementations for functions that are typically
  * not needed for processing leaf textual elements.
  */
class FB2TextContextBase : public FB2ParserContext
{
public:
  explicit FB2TextContextBase(FB2ParserContext *parentContext);

private:
  virtual FB2XMLParserContext *element(const FB2TokenData &name, const FB2TokenData &ns);
  virtual void startOfElement();
  virtual void endOfElement();
  virtual void attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value);
  virtual void endOfAttributes();
};

/** Context for skipping element hierarchies.
  */
class FB2SkipElementContext : public FB2ParserContext
{
public:
  explicit FB2SkipElementContext(FB2ParserContext *parentContext);

private:
  virtual FB2XMLParserContext *leaveContext() const;

  virtual FB2XMLParserContext *element(const FB2TokenData &name, const FB2TokenData &ns);
  virtual void startOfElement();
  virtual void endOfElement();
  virtual void attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value);
  virtual void endOfAttributes();
  virtual void text(const char *value);

private:
  unsigned m_level;
};

class FB2StyleContextBase : public FB2ParserContext
{
public:
  FB2StyleContextBase(FB2ParserContext *parentContext, const FB2Style &style);

protected:
  FB2Style &getStyle();
  FB2TextFormat &getTextFormat();

  virtual FB2XMLParserContext *element(const FB2TokenData &name, const FB2TokenData &ns);
  virtual void endOfElement();
  virtual void attribute(const FB2TokenData &name, const FB2TokenData *ns, const char *value);
  virtual void endOfAttributes();
  virtual void text(const char *value);

private:
  FB2Style m_style;
};

class FB2BlockFormatContextBase : public FB2NodeContextBase
{
public:
  FB2BlockFormatContextBase(FB2ParserContext *parentContext, const FB2BlockFormat &format);

  FB2BlockFormat &getBlockFormat();
  const FB2BlockFormat &getBlockFormat() const;

  void setLang(const char *lang);

private:
  FB2BlockFormat m_format;
};

}

#endif // FB2PARSERCONTEXT_H_INCLUDED

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