/*
 * Copyright 2015-2021 MicroEJ Corp. All rights reserved.
 * This library is provided in source code for use, modification and test, subject to license terms.
 * Any modification of the source code will break MicroEJ Corp. warranties on the whole library.
 */
package ej.mwt.util;

/**
 * Represents a rectangle with a position and a size.
 * <p>
 * For heap optimization the position and size are stored as a <code>short</code> and therefore are limited between
 * <code>-32768</code> and <code>32767</code>.
 */
public class Rectangle implements Outlineable {

    /**
     * Creates a rectangle specifying its bounds.
     *
     * @param x
     *            the x.
     * @param y
     *            the y.
     * @param width
     *            the width.
     * @param height
     *            the height.
     */
    public Rectangle(int x, int y, int width, int height) {
        this.x = (short) x;
        this.y = (short) y;
        this.width = (short) width;
        this.height = (short) height;
    }

    /**
     * Creates a rectangle from the bounds of another rectangle.
     *
     * @param rectangle
     *            the other rectangle.
     */
    public Rectangle(Rectangle rectangle) {
        this.x = rectangle.x;
        this.y = rectangle.y;
        this.width = rectangle.width;
        this.height = rectangle.height;
    }

    /**
     * Gets the x coordinate.
     *
     * @return the x.
     */
    public int getX() {
        return this.x;
    }

    /**
     * Sets the x coordinate.
     *
     * @param x
     *            the x.
     */
    public void setX(int x) {
        this.x = (short) x;
    }

    /**
     * Gets the y coordinate.
     *
     * @return the y.
     */
    public int getY() {
        return this.y;
    }

    /**
     * Sets the y coordinate.
     *
     * @param y
     *            the y.
     */
    public void setY(int y) {
        this.y = (short) y;
    }

    /**
     * Gets the width.
     *
     * @return the width.
     */
    public int getWidth() {
        return this.width;
    }

    /**
     * Sets the width.
     *
     * @param width
     *            the width.
     */
    public void setWidth(int width) {
        this.width = (short) width;
    }

    /**
     * Gets the height.
     *
     * @return the height.
     */
    public int getHeight() {
        return this.height;
    }

    /**
     * Sets the height.
     *
     * @param height
     *            the height.
     */
    public void setHeight(int height) {
        this.height = (short) height;
    }

    /**
     * Sets the position of this rectangle.
     *
     * @param x
     *            the x.
     * @param y
     *            the y.
     */
    public void setPosition(int x, int y) {
        this.x = (short) x;
        this.y = (short) y;
    }

    /**
     * Sets the size of this rectangle.
     *
     * @param width
     *            the width.
     * @param height
     *            the height.
     */
    public void setSize(int width, int height) {
        this.width = (short) width;
        this.height = (short) height;
    }

    /**
     * Sets the bounds of this rectangle.
     *
     * @param x
     *            the x.
     * @param y
     *            the y.
     * @param width
     *            the width.
     * @param height
     *            the height.
     */
    public void setBounds(int x, int y, int width, int height) {
        this.x = (short) x;
        this.y = (short) y;
        this.width = (short) width;
        this.height = (short) height;
    }

    @Override
    public void addOutline(int left, int top, int right, int bottom) {
        this.x -= left;
        this.y -= top;
        this.width += left + right;
        this.height += top + bottom;
        assert (this.width > 0 && this.height > 0);
    }

    @Override
    public void removeOutline(int left, int top, int right, int bottom) {
        this.x += left;
        this.y += top;
        this.width -= left + right;
        this.height -= top + bottom;
    }
}
