/*******************************************************************************
 * Copyright (c) 2004, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jface.util;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;

/**
 * Contains static methods for performing simple geometric operations
 * on the SWT geometry classes.
 *
 * @since 3.0
 */
public class Geometry {

    /**
     * Prevent this class from being instantiated.
     * 
     * @since 3.0
     */
    private Geometry() {
    	//This is not instantiated
    }

    /**
     * Returns the square of the distance between two points. 
     * <p>This is preferred over the real distance when searching
     * for the closest point, since it avoids square roots.</p>
     * 
     * @param p1 first endpoint
     * @param p2 second endpoint
     * @return the square of the distance between the two points
     * 
     * @since 3.0
     */
    public static int distanceSquared(Point p1, Point p2) {
        int term1 = p1.x - p2.x;
        int term2 = p1.y - p2.y;
        return term1 * term1 + term2 * term2;
    }

    /**
     * Returns the magnitude of the given 2d vector (represented as a Point)
     *  
     * @param p point representing the 2d vector whose magnitude is being computed
     * @return the magnitude of the given 2d vector
     * @since 3.0
     */
    public static double magnitude(Point p) {
        return Math.sqrt(magnitudeSquared(p));
    }

    /**
     * Returns the square of the magnitude of the given 2-space vector (represented
     * using a point)
     * 
     * @param p the point whose magnitude is being computed
     * @return the square of the magnitude of the given vector
     * @since 3.0
     */
    public static int magnitudeSquared(Point p) {
        return p.x * p.x + p.y * p.y;
    }

    /**
     * Returns the dot product of the given vectors (expressed as Points)
     * 
     * @param p1 the first vector
     * @param p2 the second vector
     * @return the dot product of the two vectors
     * @since 3.0
     */
    public static int dotProduct(Point p1, Point p2) {
        return p1.x * p2.x + p1.y * p2.y;
    }

    /**
     * Returns a new point whose coordinates are the minimum of the coordinates of the
     * given points
     * 
     * @param p1 a Point
     * @param p2 a Point
     * @return a new point whose coordinates are the minimum of the coordinates of the
     * given points
     * @since 3.0
     */
    public static Point min(Point p1, Point p2) {
        return new Point(Math.min(p1.x, p2.x), Math.min(p1.y, p2.y));
    }

    /**
     * Returns a new point whose coordinates are the maximum of the coordinates
     * of the given points
     * @param p1 a Point
     * @param p2 a Point
     * @return point a new point whose coordinates are the maximum of the coordinates
     * @since 3.0
     */
    public static Point max(Point p1, Point p2) {
        return new Point(Math.max(p1.x, p2.x), Math.max(p1.y, p2.y));
    }

    /**
     * Returns a vector in the given direction with the given
     * magnitude. Directions are given using SWT direction constants, and
     * the resulting vector is in the screen's coordinate system. That is,
     * the vector (0, 1) is down and the vector (1, 0) is right. 
     * 
     * @param distance magnitude of the vector
     * @param direction one of SWT.TOP, SWT.BOTTOM, SWT.LEFT, or SWT.RIGHT
     * @return a point representing a vector in the given direction with the given magnitude
     * @since 3.0
     */
    public static Point getDirectionVector(int distance, int direction) {
        switch (direction) {
        case SWT.TOP:
            return new Point(0, -distance);
        case SWT.BOTTOM:
            return new Point(0, distance);
        case SWT.LEFT:
            return new Point(-distance, 0);
        case SWT.RIGHT:
            return new Point(distance, 0);
        }

        return new Point(0, 0);
    }

    /**
     * Returns the point in the center of the given rectangle.
     * 
     * @param rect rectangle being computed
     * @return a Point at the center of the given rectangle.
     * @since 3.0
     */
    public static Point centerPoint(Rectangle rect) {
        return new Point(rect.x + rect.width / 2, rect.y + rect.height / 2);
    }

    /**
     * Returns a copy of the given point
     * 
     * @param toCopy point to copy
     * @return a copy of the given point
     */
    public static Point copy(Point toCopy) {
        return new Point(toCopy.x, toCopy.y);
    }
    
    /**
     * Sets result equal to toCopy
     * 
     * @param result object that will be modified
     * @param toCopy object that will be copied
     * @since 3.1
     */
    public static void set(Point result, Point toCopy) {
    	result.x = toCopy.x;
    	result.y = toCopy.y;
    }
    
    /**
     * Sets result equal to toCopy
     * 
     * @param result object that will be modified
     * @param toCopy object that will be copied
     * @since 3.1
     */
    public static void set(Rectangle result, Rectangle toCopy) {
    	result.x = toCopy.x;
    	result.y = toCopy.y;
    	result.width = toCopy.width;
    	result.height = toCopy.height;
    }

    /**
     * Adds two points as 2d vectors. Returns a new point whose coordinates are
     * the sum of the original two points.
     * 
     * @param point1 the first point (not null)
     * @param point2 the second point (not null)
     * @return a new point whose coordinates are the sum of the given points
     * @since 3.0
     */
    public static Point add(Point point1, Point point2) {
        return new Point(point1.x + point2.x, point1.y + point2.y);
    }
    
    /**
     * Divides both coordinates of the given point by the given scalar. 
     * 
     * @since 3.1 
     *
     * @param toDivide point to divide
     * @param scalar denominator
     * @return a new Point whose coordinates are equal to the original point divided by the scalar
     */
    public static Point divide(Point toDivide, int scalar) {
        return new Point(toDivide.x / scalar, toDivide.y / scalar);
    }
    

    /**
     * Performs vector subtraction on two points. Returns a new point equal to
     * (point1 - point2).
     * 
     * @param point1 initial point
     * @param point2 vector to subtract
     * @return the difference (point1 - point2)
     * @since 3.0
     */
    public static Point subtract(Point point1, Point point2) {
        return new Point(point1.x - point2.x, point1.y - point2.y);
    }

    /**
     * Swaps the X and Y coordinates of the given point.
     * 
     * @param toFlip modifies this point
     * @since 3.1
     */
    public static void flipXY(Point toFlip) {
    	int temp = toFlip.x;
    	toFlip.x = toFlip.y;
    	toFlip.y = temp;
    }

    /**
     * Swaps the X and Y coordinates of the given rectangle, along with the height and width.
     * 
     * @param toFlip modifies this rectangle
     * @since 3.1
     */
    public static void flipXY(Rectangle toFlip) {
    	int temp = toFlip.x;
    	toFlip.x = toFlip.y;
    	toFlip.y = temp;
    	
    	temp = toFlip.width;
    	toFlip.width = toFlip.height;
    	toFlip.height = temp;
    }
    
    /**
     * Returns the height or width of the given rectangle.
     * 
     * @param toMeasure rectangle to measure
     * @param width returns the width if true, and the height if false
     * @return the width or height of the given rectangle
     * @since 3.0
     */
    public static int getDimension(Rectangle toMeasure, boolean width) {
        if (width) {
            return toMeasure.width;
        }
		return toMeasure.height;
    }

    /**
     * Returns the x or y coordinates of the given point.
     * 
     * @param toMeasure point being measured
     * @param width if true, returns x. Otherwise, returns y.
     * @return the x or y coordinate
     * @since 3.1
     */
    public static int getCoordinate(Point toMeasure, boolean width) {
    	return width ? toMeasure.x : toMeasure.y;
    }
    
    /**
     * Returns the x or y coordinates of the given rectangle.
     * 
     * @param toMeasure rectangle being measured
     * @param width if true, returns x. Otherwise, returns y.
     * @return the x or y coordinate
     * @since 3.1
     */
    public static int getCoordinate(Rectangle toMeasure, boolean width) {
    	return width ? toMeasure.x : toMeasure.y;
    }
    
    /**
     * Sets one dimension of the given rectangle. Modifies the given rectangle.
     * 
     * @param toSet rectangle to modify
     * @param width if true, the width is modified. If false, the height is modified.
     * @param newCoordinate new value of the width or height
     * @since 3.1
     */
    public static void setDimension(Rectangle toSet, boolean width, int newCoordinate) {
    	if (width) {
    		toSet.width = newCoordinate;
    	} else {
    		toSet.height = newCoordinate;
    	}
    }

    /**
     * Sets one coordinate of the given rectangle. Modifies the given rectangle.
     * 
     * @param toSet rectangle to modify
     * @param width if true, the x coordinate is modified. If false, the y coordinate is modified.
     * @param newCoordinate new value of the x or y coordinates
     * @since 3.1
     */
    public static void setCoordinate(Rectangle toSet, boolean width, int newCoordinate) {
    	if (width) {
    		toSet.x = newCoordinate;
    	} else {
    		toSet.y = newCoordinate;
    	}
    }
    
    /**
     * Sets one coordinate of the given point. Modifies the given point.
     * 
     * @param toSet point to modify
     * @param width if true, the x coordinate is modified. If false, the y coordinate is modified.
     * @param newCoordinate new value of the x or y coordinates
     * @since 3.1
     */
    public static void setCoordinate(Point toSet, boolean width, int newCoordinate) {
    	if (width) {
    		toSet.x = newCoordinate;
    	} else {
    		toSet.y = newCoordinate;
    	}
    }
    
    /**
     * Returns the distance of the given point from a particular side of the given rectangle.
     * Returns negative values for points outside the rectangle.
     * 
     * @param rectangle a bounding rectangle
     * @param testPoint a point to test
     * @param edgeOfInterest side of the rectangle to test against
     * @return the distance of the given point from the given edge of the rectangle
     * @since 3.0
     */
    public static int getDistanceFromEdge(Rectangle rectangle, Point testPoint,
            int edgeOfInterest) {
        switch (edgeOfInterest) {
        case SWT.TOP:
            return testPoint.y - rectangle.y;
        case SWT.BOTTOM:
            return rectangle.y + rectangle.height - testPoint.y;
        case SWT.LEFT:
            return testPoint.x - rectangle.x;
        case SWT.RIGHT:
            return rectangle.x + rectangle.width - testPoint.x;
        }

        return 0;
    }

    /**
     * Extrudes the given edge inward by the given distance. That is, if one side of the rectangle
     * was sliced off with a given thickness, this returns the rectangle that forms the slice. Note
     * that the returned rectangle will be inside the given rectangle if size > 0.
     * 
     * @param toExtrude the rectangle to extrude. The resulting rectangle will share three sides
     * with this rectangle.
     * @param size distance to extrude. A negative size will extrude outwards (that is, the resulting
     * rectangle will overlap the original iff this is positive). 
     * @param orientation the side to extrude.  One of SWT.LEFT, SWT.RIGHT, SWT.TOP, or SWT.BOTTOM. The 
     * resulting rectangle will always share this side with the original rectangle.
     * @return a rectangle formed by extruding the given side of the rectangle by the given distance.
     * @since 3.0
     */
    public static Rectangle getExtrudedEdge(Rectangle toExtrude, int size,
            int orientation) {
        Rectangle bounds = new Rectangle(toExtrude.x, toExtrude.y,
                toExtrude.width, toExtrude.height);

        if (!isHorizontal(orientation)) {
            bounds.width = size;
        } else {
            bounds.height = size;
        }

        switch (orientation) {
        case SWT.RIGHT:
            bounds.x = toExtrude.x + toExtrude.width - bounds.width;
            break;
        case SWT.BOTTOM:
            bounds.y = toExtrude.y + toExtrude.height - bounds.height;
            break;
        }

        normalize(bounds);

        return bounds;
    }

    /**
     * Returns the opposite of the given direction. That is, returns SWT.LEFT if
     * given SWT.RIGHT and visa-versa.
     * 
     * @param swtDirectionConstant one of SWT.LEFT, SWT.RIGHT, SWT.TOP, or SWT.BOTTOM
     * @return one of SWT.LEFT, SWT.RIGHT, SWT.TOP, or SWT.BOTTOM
     * @since 3.0
     */
    public static int getOppositeSide(int swtDirectionConstant) {
        switch (swtDirectionConstant) {
        case SWT.TOP:
            return SWT.BOTTOM;
        case SWT.BOTTOM:
            return SWT.TOP;
        case SWT.LEFT:
            return SWT.RIGHT;
        case SWT.RIGHT:
            return SWT.LEFT;
        }

        return swtDirectionConstant;
    }

    /**
     * Converts the given boolean into an SWT orientation constant.
     * 
     * @param horizontal if true, returns SWT.HORIZONTAL. If false, returns SWT.VERTICAL 
     * @return SWT.HORIZONTAL or SWT.VERTICAL.
     * @since 3.0
     */
    public static int getSwtHorizontalOrVerticalConstant(boolean horizontal) {
        if (horizontal) {
            return SWT.HORIZONTAL;
        }
		return SWT.VERTICAL;
    }

    /**
     * Returns true iff the given SWT side constant corresponds to a horizontal side
     * of a rectangle. That is, returns true for the top and bottom but false for the
     * left and right.
     * 
     * @param swtSideConstant one of SWT.TOP, SWT.BOTTOM, SWT.LEFT, or SWT.RIGHT
     * @return true iff the given side is horizontal.
     * @since 3.0
     */
    public static boolean isHorizontal(int swtSideConstant) {
        return !(swtSideConstant == SWT.LEFT || swtSideConstant == SWT.RIGHT);
    }

    /**
     * Moves the given rectangle by the given delta.
     * 
     * @param rect rectangle to move (will be modified)
     * @param delta direction vector to move the rectangle by
     * @since 3.0
     */
    public static void moveRectangle(Rectangle rect, Point delta) {
        rect.x += delta.x;
        rect.y += delta.y;
    }

    /**
     * Moves each edge of the given rectangle outward by the given amount. Negative values
     * cause the rectangle to contract. Does not allow the rectangle's width or height to be
     * reduced below zero.
     *  
     * @param rect normalized rectangle to modify
     * @param left distance to move the left edge outward (negative values move the edge inward)
     * @param right distance to move the right edge outward (negative values move the edge inward) 
     * @param top distance to move the top edge outward (negative values move the edge inward)
     * @param bottom distance to move the bottom edge outward (negative values move the edge inward)
     * @since 3.1
     */
    public static void expand(Rectangle rect, int left, int right, int top, int bottom) {
        rect.x -= left;
        rect.width = Math.max(0, rect.width + left + right);
        rect.y -= top;
        rect.height = Math.max(0, rect.height + top + bottom);
    }
    
    /**
     * Normalizes the given rectangle. That is, any rectangle with
     * negative width or height becomes a rectangle with positive
     * width or height that extends to the upper-left of the original
     * rectangle. 
     * 
     * @param rect rectangle to modify
     * @since 3.0
     */
    public static void normalize(Rectangle rect) {
        if (rect.width < 0) {
            rect.width = -rect.width;
            rect.x -= rect.width;
        }

        if (rect.height < 0) {
            rect.height = -rect.height;
            rect.y -= rect.height;
        }
    }

    /**
     * Converts the given rectangle from display coordinates to the local coordinate system 
     * of the given object into display coordinates.
     * 
     * @param coordinateSystem local coordinate system being converted to
     * @param toConvert rectangle to convert
     * @return a rectangle in control coordinates
     * @since 3.0
     */
    public static Rectangle toControl(Control coordinateSystem,
            Rectangle toConvert) {
    	return(coordinateSystem.getDisplay().map
    			(null,coordinateSystem,toConvert));
    }

    /**
     * Converts the given rectangle from the local coordinate system of the given object
     * into display coordinates.
     * 
     * @param coordinateSystem local coordinate system being converted from
     * @param toConvert rectangle to convert
     * @return a rectangle in display coordinates
     * @since 3.0
     */
    public static Rectangle toDisplay(Control coordinateSystem,
            Rectangle toConvert) {
    	return(coordinateSystem.getDisplay().map
    			(coordinateSystem,null,toConvert));   

    }

    /**
     * Determines where the given point lies with respect to the given rectangle.
     * Returns a combination of SWT.LEFT, SWT.RIGHT, SWT.TOP, and SWT.BOTTOM, combined
     * with bitwise or (for example, returns SWT.TOP | SWT.LEFT if the point is to the
     * upper-left of the rectangle). Returns 0 if the point lies within the rectangle.
     * Positions are in screen coordinates (ie: a point is to the upper-left of the
     * rectangle if its x and y coordinates are smaller than any point in the rectangle)
     *  
     * @param boundary normalized boundary rectangle 
     * @param toTest point whose relative position to the rectangle is being computed
     * @return one of SWT.LEFT | SWT.TOP, SWT.TOP, SWT.RIGHT | SWT.TOP, SWT.LEFT, 0,
     * SWT.RIGHT, SWT.LEFT | SWT.BOTTOM, SWT.BOTTOM, SWT.RIGHT | SWT.BOTTOM
     * @since 3.0
     */
    public static int getRelativePosition(Rectangle boundary, Point toTest) {
        int result = 0;

        if (toTest.x < boundary.x) {
            result |= SWT.LEFT;
        } else if (toTest.x >= boundary.x + boundary.width) {
            result |= SWT.RIGHT;
        }

        if (toTest.y < boundary.y) {
            result |= SWT.TOP;
        } else if (toTest.y >= boundary.y + boundary.height) {
            result |= SWT.BOTTOM;
        }

        return result;
    }

    /**
     * Returns the distance from the point to the nearest edge of the given
     * rectangle. Returns negative values if the point lies outside the rectangle.
     * 
     * @param boundary rectangle to test
     * @param toTest point to test
     * @return the distance between the given point and the nearest edge of the rectangle.
     * Returns positive values for points inside the rectangle and negative values for points
     * outside the rectangle.
     * @since 3.1
     */
    public static int getDistanceFrom(Rectangle boundary, Point toTest) {
        int side = getClosestSide(boundary, toTest);
        return getDistanceFromEdge(boundary, toTest, side);
    }
    
    /**
     * Returns the edge of the given rectangle is closest to the given
     * point.
     * 
     * @param boundary rectangle to test
     * @param toTest point to compare
     * @return one of SWT.LEFT, SWT.RIGHT, SWT.TOP, or SWT.BOTTOM
     * 
     * @since 3.0
     */
    public static int getClosestSide(Rectangle boundary, Point toTest) {
        int[] sides = new int[] { SWT.LEFT, SWT.RIGHT, SWT.TOP, SWT.BOTTOM };

        int closestSide = SWT.LEFT;
        int closestDistance = Integer.MAX_VALUE;

        for (int idx = 0; idx < sides.length; idx++) {
            int side = sides[idx];

            int distance = getDistanceFromEdge(boundary, toTest, side);

            if (distance < closestDistance) {
                closestDistance = distance;
                closestSide = side;
            }
        }

        return closestSide;
    }

    /**
     * Returns a copy of the given rectangle
     * 
     * @param toCopy rectangle to copy
     * @return a copy of the given rectangle
     * @since 3.0
     */
    public static Rectangle copy(Rectangle toCopy) {
        return new Rectangle(toCopy.x, toCopy.y, toCopy.width, toCopy.height);
    }

    /**
     * Returns the size of the rectangle, as a Point
     * 
     * @param rectangle rectangle whose size is being computed
     * @return the size of the given rectangle
     * @since 3.0
     */
    public static Point getSize(Rectangle rectangle) {
        return new Point(rectangle.width, rectangle.height);
    }

    /**
     * Sets the size of the given rectangle to the given size
     * 
     * @param rectangle rectangle to modify
     * @param newSize new size of the rectangle
     * @since 3.0
     */
    public static void setSize(Rectangle rectangle, Point newSize) {
        rectangle.width = newSize.x;
        rectangle.height = newSize.y;
    }

    /**
     * Sets the x,y position of the given rectangle. For a normalized
     * rectangle (a rectangle with positive width and height), this will
     * be the upper-left corner of the rectangle. 
     * 
     * @param rectangle rectangle to modify
     * @param newSize new size of the rectangle
     * 
     * @since 3.0
     */
    public static void setLocation(Rectangle rectangle, Point newSize) {
        rectangle.width = newSize.x;
        rectangle.height = newSize.y;
    }

    /**
     * Returns the x,y position of the given rectangle. For normalized rectangles
     * (rectangles with positive width and height), this is the upper-left
     * corner of the rectangle.
     * 
     * @param toQuery rectangle to query
     * @return a Point containing the x,y position of the rectangle
     * 
     * @since 3.0
     */
    public static Point getLocation(Rectangle toQuery) {
        return new Point(toQuery.x, toQuery.y);
    }

    /**
     * Returns a new rectangle with the given position and dimensions, expressed
     * as points.
     * 
     * @param position the (x,y) position of the rectangle
     * @param size the size of the new rectangle, where (x,y) -> (width, height)
     * @return a new Rectangle with the given position and size
     * 
     * @since 3.0
     */
    public static Rectangle createRectangle(Point position, Point size) {
        return new Rectangle(position.x, position.y, size.x, size.y);
    }
    
    /**
	 * Repositions the 'inner' rectangle to lie completely within the bounds of the 'outer'
	 * rectangle if possible. One use for this is to ensure that, when setting a control's bounds,
	 * that they will always lie within its parent's client area (to avoid clipping).
	 * 
	 * @param inner The 'inner' rectangle to be repositioned (should be smaller than the 'outer' rectangle)
	 * @param outer The 'outer' rectangle
	 */
	public static void moveInside(Rectangle inner, Rectangle outer) {
		// adjust X
		if (inner.x < outer.x)
			inner.x = outer.x;
		if ((inner.x + inner.width) > (outer.x + outer.width)) {
			inner.x -= (inner.x + inner.width) - (outer.x + outer.width);
		}

		// Adjust Y
		if (inner.y < outer.y)
			inner.y = outer.y;
		if ((inner.y + inner.height) > (outer.y + outer.height)) {
			inner.y -= (inner.y + inner.height) - (outer.y + outer.height);
		}
	}
    
}
