// This may look like C code, but it's really -*- C++ -*-
/*
 * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
 *
 * See the LICENSE file for terms of use.
 */
#ifndef WCSS_STYLE_SHEET_H_
#define WCSS_STYLE_SHEET_H_

#include <vector>
#include <set>
#include <string>

#include <Wt/WCssDecorationStyle>

namespace Wt {

class WCssRule
{
public:
  WCssRule(const std::string& selector);
  virtual ~WCssRule();

  const std::string& selector() const { return selector_; }

  virtual const std::string declarations() = 0;

private:
  std::string selector_;
};

class WCssDecorationRule : public WCssRule
{
public:
  WCssDecorationRule(const std::string& selector,
		     const WCssDecorationStyle& style);

  WCssDecorationStyle& style() { return style_; }

  const std::string declarations();

private:
  WCssDecorationStyle style_;
};

class WCssOtherRule : public WCssRule
{
public:
  WCssOtherRule(const std::string& selector,
		const WString& declarations);

  const std::string declarations();

private:
  WString declarations_;
};

/*! \class WCssStyleSheet Wt/WCssStyleSheet Wt/WCssStyleSheet
 *  \brief A CSS style sheet.
 *
 * \sa WApplication::styleSheet()
 *
 * \ingroup style
 */
class WT_API WCssStyleSheet
{
public:
  /*! \brief Create a new empty style sheet.
   */
  WCssStyleSheet();

  /*! \brief Destroy a style sheet, and all rules in it.
   */
  ~WCssStyleSheet();

  /*! \brief Add a decoration rule.
   *
   * Add a rule using the CSS selector <i>selector</i>, with styles specified
   * in <i>style</i>.
   *
   * Optionally, you may give a <i>ruleName</i>, which may later be
   * used to check if the rule was already defined.
   *
   * \sa isDefined(const std::string& ruleName).
   */
  void addRule(const std::string& selector, const WCssDecorationStyle& style,
	       const std::string& ruleName = std::string());

  /*! \brief Add a decoration rule.
   *
   * Add a rule using the CSS selector <i>selector</i>, with CSS
   * declarations in <i>declarations</i>. These declarations must be a
   * list separated by semi-colons (;).
   *
   * Optionally, you may give a <i>ruleName</i>, which may later be
   * used to check if the rule was already defined.
   *
   * \sa isDefined(const std::string& ruleName).
   */
  void addRule(const std::string& selector, const WString& declarations,
	       const std::string& ruleName = std::string());
  void addRule(WCssRule *rule,
	       const std::string& ruleName = std::string());
  std::string cssText(bool all);

  /*! \brief Returns if a rule was already defined in this style sheet.
   *
   * Returns whether a rule was added with the given <i>ruleName</i>.
   *
   * \sa addRule()
   */
  bool isDefined(const std::string& ruleName) const;

private:
  std::set<std::string> defined_;
  std::vector<WCssRule * > rules_;

  int rulesAdded_;

  friend class WebRenderer;
};

}

#endif // WCSS_STYLE_SHEET_H_
