/*
** Module   : Rectangle.java
** Abstract : store the screen coordinates of a rectangle 
**
** Copyright (c) 2009, Golden Code Development Corporation.
**
** -#- -I- --Date-- -----------------------Description------------------------
** 001 GES 20090126 Store the screen coordinates of a rectangle.
*/

/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU Affero General Public License for more details.
**
** You should have received a copy of the GNU Affero General Public License
** along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.goldencode.harness.test;

/**
 * Represent the screen coordinates and extent of a rectangle in terms of
 * character positions (points) in the terminal (coordinate space). Every
 * character position on a terminal screen can be checked for inclusion or
 * exclusion from this rectangle.
 * <p>
 * The screen's origin (0, 0) is defined as the upper left corner. The points
 * given to define a rectangle do so in an inclusive manner. In other words,
 * the rectangle itself is considered to include all points that define the
 * boundary of the rectangle.
 */
public class Rectangle
{
   /** Left side X coordinate. */
   private final int left;
   
   /** Top Y coordinate. */
   private final int top;
   
   /** Right side X coordinate. */
   private final int right;
   
   /** Bottom Y coordinate. */
   private final int bottom;
   
   /**
    * Create an instance given explicit coordinates from the upper left and
    * lower right corners. It is possible to define a rectangle that is a
    * single point.
    *
    * @param    left
    *           Left side X coordinate.
    * @param    top
    *           Upper Y coordinate.
    * @param    right
    *           Right side X coordinate.
    * @param    bottom
    *           Lower Y coordinate.
    */
   public Rectangle(int left, int top, int right, int bottom)
   {
      this.left   = (left <= right) ? left   : right;
      this.top    = (top <= bottom) ? top    : bottom;
      this.right  = (right >= left) ? right  : left;
      this.bottom = (bottom >= top) ? bottom : top;
   }
   
   /**
    * Copy constructor.
    *
    * @param    other
    *           The rectangle on which to base the new instance.
    */
   public Rectangle(Rectangle other)
   {
      this.left   = other.left;
      this.top    = other.top;
      this.right  = other.right;
      this.bottom = other.bottom;
   }
   
   /**
    * Get the left X coordinate.
    *
    * @return   The coordinate.
    */
   public int getLeft()
   {
      return left;
   }
   
   /**
    * Get the top Y coordinate.
    *
    * @return   The coordinate.
    */
   public int getTop()
   {
      return top;
   }
   
   /**
    * Get the right X coordinate.
    *
    * @return   The coordinate.
    */
   public int getRight()
   {
      return right;
   }
   
   /**
    * Get the bottom Y coordinate.
    *
    * @return   The coordinate.
    */
   public int getBottom()
   {
      return bottom;
   }
   
   /**
    * Get the width of the rectangle.
    *
    * @return   The width.
    */
   public int getWidth()
   {
      return (right - left) + 1;
   }
   
   /**
    * Get the height of the rectangle.
    *
    * @return   The height.
    */
   public int getHeight()
   {
      return (bottom - top) + 1;
   }
   
   /**
    * Report if a given point is excluded in the rectangle. Note that the
    * rectangle is inclusive of its boundary.
    *
    * @param    x
    *           Horizontal coordinate.
    * @param    y
    *           Vertical coordinate.
    *
    * @return   <code>true</code> if the point is positioned outside (and not
    *           on the boundary line) of the rectangle.
    */
   public boolean isExcluded(int x, int y)
   {
      return (x < left || x > right || y < top || y > bottom);
   }
   
   /**
    * Report if a given rectangle is included in this rectangle. Note that the
    * rectangle is inclusive of its boundary.
    *
    * @param    rect
    *           The coordinates of the rectangle to check.
    *
    * @return   <code>true</code> if the given rectangle is completely
    *           contained within this rectangle.
    */
   public boolean contains(Rectangle rect)
   {
      return (rect.left >= left  && rect.right  <= right  &&
              rect.top  >= top   && rect.bottom <= bottom);
   }
   
   /**
    * Report if a given point is included in the rectangle. Note that the
    * rectangle is inclusive of its boundary.
    *
    * @param    x
    *           Horizontal coordinate.
    * @param    y
    *           Vertical coordinate.
    *
    * @return   <code>true</code> if the point is positioned inside or on the
    *           boundary line of the rectangle.
    */
   public boolean isIncluded(int x, int y)
   {
      return (x >= left && x <= right && y >= top && y <= bottom);
   }
}
