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

#include <Wt/WDllDefs.h>

namespace Wt {

class WPointF;

/*! \class WRectF Wt/WRectF Wt/WRectF
 *  \brief A value class that defines a rectangle.
 *
 * The rectangle is defined by a top-left point and a width and height.
 *
 * \ingroup painting
 */
class WT_API WRectF
{
public:
  /*! \brief Default constructor.
   *
   * Constructs a \p null rectangle.
   * 
   * \sa isNull()
   */
  WRectF();

  /*! \brief Creates a rectangle.
   *
   * Constructs a rectangle with top left point (\p x, \p y)
   * and size \p width x \p height.
   */
  WRectF(double x, double y, double width, double height);

  /*! \brief Creates a rectangle.
   *
   * Constructs a rectangle from the two points \p topLeft and
   * \p bottomRight.
   *
   * If you want to create a rectangle from two arbitrary corner
   * points, you can use this constructor too, but should call
   * normalized() afterwords.
   */
  WRectF(const WPointF& topLeft, const WPointF& bottomRight);

#ifdef WT_TARGET_JAVA
  /*! \brief Internal assign method. 
   */
  WRectF& operator= (const WRectF& rhs);
#endif // WT_TARGET_JAVA

  /*! \brief Comparison operator.
   */
  bool operator== (const WRectF& rhs) const;
  bool operator!= (const WRectF& rhs) const;

  /*! \brief Checks for a <i>null</i> rectangle.
   *
   * \sa WRectF()
   */
  bool isNull() const;

  /*! \brief Determines whether or not this rectangle is empty. 
   *
   * A rectangle is empty if its width and height are zero.
   */
  bool isEmpty() const;

  /*! \brief Sets the X-position of the left side.
   *
   * The right side of the rectangle does not move, and as a result,
   * the rectangle may be resized.
   */
  void setX(double x);

  /*! \brief Sets the Y-position of the top side.
   *
   * The bottom side of the rectangle does not move, and as a result,
   * the rectangle may be resized.
   */
  void setY(double y);

  /*! \brief Sets the width.
   *
   * The right side of the rectangle may move, but this does not
   * affect the left side.
   */
  void setWidth(double width) { width_ = width; }

  /*! \brief Sets the Y-position of the top side.
   *
   * The bottom side of the rectangle may move, but this does not
   * affect the Y position of the top side.
   */
  void setHeight(double height) { height_ = height; }

  /*! \brief Returns the X-position (left side offset).
   *
   * This is equivalent to left().
   *
   * \sa y(), left()
   */
  double x() const { return x_; }

  /*! \brief Returns the Y-position (top side offset).
   *
   * This is equivalent to top().
   *
   * \sa x(), top()
   */
  double y() const { return y_; }

  /*! \brief Returns the width.
   *
   * \sa height()
   */
  double width() const { return width_; }

  /*! \brief Returns the height.
   *
   * \sa width()
   */
  double height() const { return height_; }

  /*! \brief Returns the X position (left side offset).
   *
   * \sa x(), right()
   */
  double left() const { return x_; }

  /*! \brief Returns the Y position (top side offset).
   *
   * \sa y(), bottom()
   */
  double top() const { return y_; }

  /*! \brief Returns the the right side offset.
   *
   * \sa left()
   */
  double right() const { return x_ + width_; }

  /*! \brief Returns the bottom side offset.
   *
   * \sa top()
   */
  double bottom() const { return y_ + height_; }

  /*! \brief Returns the top left point.
   *
   * \sa left(), top()
   */
  WPointF topLeft() const;

  /*! \brief Returns the top right point.
   *
   * \sa right(), top()
   */
  WPointF topRight() const;

  /*! \brief Returns the center point.
   */
  WPointF center() const;

  /*! \brief Returns the bottom left point.
   *
   * \sa left(), bottom()
   */
  WPointF bottomLeft() const;

  /*! \brief Returns the bottom right point.
   *
   * \sa right(), bottom()
   */
  WPointF bottomRight() const;

  /*! \brief Tests if a rectangle contains a point.
   */
  bool contains(const WPointF& p) const;

  /*! \brief Tests if a rectangle contains a point.
   */
  bool contains(double x, double y) const;

  /*! \brief Tests if two rectangles intersect.
   */
  bool intersects(const WRectF& other) const;

  /*! \brief Makes the union of to rectangles.
   */
  WRectF united(const WRectF& other) const;

  /*! \brief Returns a normalized rectangle.
   *
   * A normalized rectangle has a positive width and height.
   */
  WRectF normalized() const;

private:
  double x_, y_, width_, height_;
};

}

#endif // WRECTF_H_
