001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.ade.galleries.client.preview.util;
029
030import org.opencms.ade.galleries.shared.CmsPoint;
031
032/**
033 * Axis-aligned rectangle in 2D space.<p>
034 */
035public class CmsRectangle {
036
037    /** x coordinate of left side of the rectangle. */
038    private double m_left;
039
040    /** y coordinate of the top side of the rectangle. */
041    private double m_top;
042
043    /** The width. */
044    private double m_width;
045
046    /** The height. */
047    private double m_height;
048
049    /**
050     * Hidden default constructor.<p>
051     */
052    protected CmsRectangle() {
053        // do nothing
054    }
055
056    /**
057     * Creates a new rectangle given its left, top coordinates and its width and height.<p>
058     *
059     * @param left the left side
060     * @param top the top side
061     * @param width the width
062     * @param height the height
063     *
064     * @return the new rectangel
065     */
066    public static CmsRectangle fromLeftTopWidthHeight(double left, double top, double width, double height) {
067
068        CmsRectangle result = new CmsRectangle();
069        result.m_left = left;
070        result.m_top = top;
071        result.m_width = width;
072        result.m_height = height;
073        return result;
074    }
075
076    /**
077     * Creates a new rectangle from its top left and bottom right corner points.<p>
078     *
079     * @param topLeft the top left corner
080     * @param bottomRight the bottom right corner
081     * @return the new rectangle
082     */
083    public static CmsRectangle fromPoints(CmsPoint topLeft, CmsPoint bottomRight) {
084
085        CmsRectangle result = new CmsRectangle();
086        result.m_left = topLeft.getX();
087        result.m_top = topLeft.getY();
088        result.m_width = bottomRight.getX() - topLeft.getX();
089        result.m_height = bottomRight.getY() - topLeft.getY();
090        return result;
091    }
092
093    /**
094     * Helper method to constrain a number inside a given interval.<p>
095     *
096     * If the number is inside the given range, it will be returned unchanged, otherwise either the maximum
097     * or minimum of the range is returned depending on on which side the value lies.
098     *
099     * @param min the minimum value
100     * @param size the difference between maximum and minimum value
101     * @param h the number to constrain
102     *
103     * @return the constrained value
104     */
105    private static double constrainNum(double min, double size, double h) {
106
107        if (h < min) {
108            return min;
109        }
110        if (h >= (min + size)) {
111            return (min + size) - 1;
112        }
113        return h;
114    }
115
116    /**
117     * Constrains a point to this rectangle.<p>
118     *
119     * If any of the coordinates of the point lie in the projection of this rectangle on the corresponding axis, that coordinate
120     * in the result will be unchanged, otherwise it will be either the maximum or the minimum depending on on which side the original
121     * coordinate is located.
122     *
123     * @param point the point to constrain
124     *
125     * @return the constrained point
126     */
127    public CmsPoint constrain(CmsPoint point) {
128
129        return new CmsPoint(constrainNum(m_left, m_width, point.getX()), constrainNum(m_top, m_height, point.getY()));
130    }
131
132    /**
133     * Checks if this rectangle contains a given point.<p>
134     *
135     * @param point the point to check
136     *
137     * @return true if the point is contained in the rectangle
138     */
139    public boolean contains(CmsPoint point) {
140
141        return (point.getX() >= m_left)
142            && (point.getX() < (m_left + m_width))
143            && (point.getY() >= m_top)
144            && (point.getY() < (m_top + m_height));
145    }
146
147    /**
148     * Gets the bottom right corner.<p>
149     *
150     * @return the bottom right corner
151     */
152    public CmsPoint getBottomRight() {
153
154        return new CmsPoint(m_left + m_width, m_top + m_height);
155    }
156
157    /**
158     * Gets the top left corner.<p>
159     *
160     * @return the top left corner
161     */
162    public CmsPoint getTopLeft() {
163
164        return new CmsPoint(m_left, m_top);
165    }
166
167}