// 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 Utility 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 <i>null</i> rectangle.
   *
   * \sa isNull()
   */
  WRectF();

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

  /*! \brief Construct a rectangle.
   *
   * Constructs a rectangle from the two points <i>topLeft</i> and
   * <i>bottomRight</i>.
   */
  WRectF(const WPointF& topLeft, const WPointF& bottomRight);

  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 Changes 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 Changes 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 Changes the width.
   *
   * The right side of the rectangle may move, but does not change the X
   * position of the left side.
   */
  void setWidth(double width) { width_ = width; }

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

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

  /*! \brief Returns the Y-position of the top side.
   *
   * 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 of the left side.
   *
   * \sa x(), right()
   */
  double left() const { return x_; }

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

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

  /*! \brief Returns the Y position of the bottom side.
   *
   * \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 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_
