// 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 WCSSDECORATIONSTYLE_H_
#define WCSSDECORATIONSTYLE_H_

#include <Wt/WBorder>
#include <Wt/WColor>
#include <Wt/WFont>
#include <Wt/WWidget>

namespace Wt {

class DomElement;
class WWebWidget;

/*! \defgroup style Style classes
 *  \brief Collection of classes for markup of widgets.
 *
 * The recommended way to provide style information for your %Wt
 * application is using CSS stylesheets. You may add rules to the
 * inline style sheet using WCssStyleSheet::addRule(), or by linking
 * one or more external stylesheets using WApplication::useStyleSheet().
 *
 * Alternatively, you may also provide style information directly,
 * using WCssDecorationStyle, which you can manipulate for each widget
 * using WWidget::decorationStyle().
 */

/*! \class WCssDecorationStyle Wt/WCssDecorationStyle Wt/WCssDecorationStyle
 *  \brief A style class for a single widget or style sheet rule.
 *
 * You can manipulate the decoration style of a single widget using
 * WWidget::decorationStyle() or you can use a WCssDecorationStyle to
 * add a rule to the inline style sheet using
 * WCssStyleSheet::addRule(const std::string&, const WCssDecorationStyle& style, const std::string&).
 *
 * \if cpp
 * Usage example:
 * \code
 * Wt::WWidget *widget = ...
 * widget->decorationStyle().setCursor(PointingHandCursor);
 * \endcode
 * \endif
 *
 * \ingroup style
 */
class WT_API WCssDecorationStyle
#ifdef WT_TARGET_JAVA
  : WObject
#endif
{
public:
  /*! \brief How a background image must be repeated.
   */
  enum Repeat { RepeatXY,  //!< Repeat horizontally and vertically, default
		RepeatX,   //!< Repeat horizontally
		RepeatY,   //!< Repeat vertically
		NoRepeat   //!< Do not repeat
  };

  /*! \brief Text decoration options
   */
  enum TextDecoration { Underline   = 0x1, //!< Underline
			Overline    = 0x2, //!< Overline
			LineThrough = 0x4, //!< LineThrough
			Blink       = 0x8  //!< Blink
  };

  /*! \brief Creates a default style.
   */
  WCssDecorationStyle();

  /*! \brief Assignment operator.
   */
  WCssDecorationStyle& operator= (const WCssDecorationStyle& other);

  /*! \brief Sets the cursor style.
   */
  void setCursor(Cursor c);

  /*! \brief Returns the cursor style.
   */
  Cursor cursor() const { return cursor_; }

  /*! \brief Sets a custom cursor image URI, with optionally a fallback cursor.
   * 
   * The URI should point to a .cur file (this shoul be a real .cur file, 
   * renaming an .ico is not enough for Internet Explorer).
   */
  void setCursor(std::string cursorImage, Cursor fallback = ArrowCursor);

  /*! \brief Returns the cursor image.
   */
  std::string cursorImage() const { return cursorImage_; }

  /*! \brief Sets the background color.
   */
  void setBackgroundColor(WColor color);

  /*! \brief Returns the background color.
   */
  WColor backgroundColor() const { return backgroundColor_; }

  /*! \brief Sets a background image URL.
   *
   * The image may be placed in a particular location by specifying
   * sides by OR'ing Wt::Side values together, e.g. (Right | Top).
   *
   * \sa setBackgroundImage()
   */
  void setBackgroundImage(const std::string& imageHRef,
			  Repeat repeat = RepeatXY,
			  WFlags<Side> sides = 0);

  /*! \brief Sets a background image URL.
   *
   * The image may be placed in a particular location by specifying
   * sides by OR'ing Wt::Side values together, e.g. (Right | Top).
   *
   * \sa setBackgroundImage()
   */
  void setBackgroundImage(WResource *resource,
			  Repeat repeat = RepeatXY,
			  WFlags<Side> sides = 0);

  /*! \brief Returns the background image URL.
   */
  const std::string& backgroundImage() const { return backgroundImage_; }

  /*! \brief Returns the background image repeat.
   */
  Repeat backgroundImageRepeat() const { return backgroundImageRepeat_; }

  /*! \brief Sets the foreground color.
   */
  void setForegroundColor(WColor color);

  /*! \brief Returns the foreground color.
   */
  WColor foregroundColor() const { return foregroundColor_; }

  /*! \brief Sets the border style.
   *  
   * A border may be placed in a particular location by specifying
   * sides by OR'ing WWidget::Side values together, e.g. (Right | Top).
   */
  void setBorder(WBorder border, WFlags<Side> sides = All);

  /*! \brief Returns the border style.
   */
  WBorder border() const { return border_; }

  /*! \brief Sets the font.
   */
  void setFont(const WFont& font);

  /*! \brief Returns a reference to the font.
   */
  WFont& font() { return font_; }

  /*! \brief Sets the text decoration options.
   *
   * You may logically or together any of the options of the
   * TextDecoration enumeration.
   *
   * The default is 0.
   */
  void setTextDecoration(WFlags<TextDecoration> decoration);

  /*! \brief Returns the text decoration options.
   */
  WFlags<TextDecoration> textDecoration() const { return textDecoration_; }

  std::string cssText();
  void updateDomElement(DomElement& element, bool all);

private:
  WWebWidget               *widget_;
  Cursor                    cursor_;
  std::string               cursorImage_;
  WBorder                   border_;
  WColor                    backgroundColor_;
  WColor	            foregroundColor_;
  std::string	            backgroundImage_;
  WResource                *backgroundImageResource_;
  Repeat	            backgroundImageRepeat_;
  WFlags<Side>              backgroundImageLocation_;
  WFont		            font_;
  WFlags<TextDecoration>    textDecoration_;
  WFlags<Side>              borderPosition_;

  bool		            cursorChanged_;
  bool		            borderChanged_;
  bool		            foregroundColorChanged_;
  bool		            backgroundColorChanged_;
  bool	  	            backgroundImageChanged_;
  bool		            fontChanged_;
  bool                      textDecorationChanged_;

  void changed();
  void backgroundImageResourceChanged();

  void setWebWidget(WWebWidget *widget);
  friend class WWebWidget;
};

W_DECLARE_OPERATORS_FOR_FLAGS(WCssDecorationStyle::TextDecoration)

}

#endif // WCSSDECORATIONSTYLE_H_
