/*
    Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
    и других спецификаций для функционирования компактных приложений на языке
    Java (мидлетов) в среде программного обеспечения Малик Эмулятор.

    Copyright © 2016–2017, 2019–2022 Малик Разработчик

    Это свободная программа: вы можете перераспространять ее и/или изменять
    ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она будет полезной,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <https://www.gnu.org/licenses/>.
*/

package malik.emulator.media.graphics;

import malik.emulator.util.*;

public final class RectangularRegion extends Object implements Rectangle
{
    private final int left;
    private final int top;
    private final int width;
    private final int height;

    public RectangularRegion(int left, int top, int width, int height) {
        this.left = left;
        this.top = top;
        this.width = width;
        this.height = height;
    }

    public RectangularRegion(Rectangle region) {
        if(region == null)
        {
            this.left = 0;
            this.top = 0;
            this.width = 0;
            this.height = 0;
            return;
        }
        this.left = region.getLeft();
        this.top = region.getTop();
        this.width = region.getWidth();
        this.height = region.getHeight();
    }

    public boolean equals(Object anot) {
        RectangularRegion r;
        return anot == this || anot instanceof RectangularRegion && left == (r = (RectangularRegion) anot).left && top == r.top && width == r.width && height == r.height;
    }

    public int hashCode() {
        int l = left;
        int t = top;
        int w = width;
        int h = height;
        t = t << 0x08 | t >>> 0x18;
        w = w << 0x10 | w >>> 0x10;
        h = h << 0x18 | h >>> 0x08;
        return l ^ t ^ w ^ h;
    }

    public String toString() {
        return (new StringBuilder()).append("Прямоугольная область[отступ=").append(left).append(":").append(top).append(", размер=").append(width).append("×").append(height).append("]").toString();
    }

    public int getLeft() {
        return left;
    }

    public int getTop() {
        return top;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public boolean intersectsWith(int left, int top, int width, int height) {
        int aLeft = this.left;
        int aTop = this.top;
        int aRight = aLeft + this.width;
        int aBottom = aTop + this.height;
        int bLeft = left;
        int bTop = top;
        int bRight = bLeft + width;
        int bBottom = bTop + height;
        return aLeft < bRight && aTop < bBottom && aRight > bLeft && aBottom > bTop;
    }

    public boolean intersectsWith(Rectangle region) {
        if(region == null)
        {
            throw new NullPointerException("RectangularRegion.intersectsWith: аргумент region равен нулевой ссылке.");
        }
        return intersectsWith(region.getLeft(), region.getTop(), region.getWidth(), region.getHeight());
    }

    public RectangularRegion intersection(int left, int top, int width, int height) {
        boolean f = true;
        int tmp;
        int l = this.left;
        int t = this.top;
        int r = l + this.width;
        int b = t + this.height;
        if(l < left)
        {
            l = left;
            f = false;
        }
        if(t < top)
        {
            t = top;
            f = false;
        }
        if(r > (tmp = left + width))
        {
            r = tmp;
            f = false;
        }
        if(b > (tmp = top + height))
        {
            b = tmp;
            f = false;
        }
        return f ? this : new RectangularRegion(l, t, r - l, b - t);
    }

    public RectangularRegion intersection(Rectangle region) {
        if(region == null)
        {
            throw new NullPointerException("RectangularRegion.intersection: аргумент region равен нулевой ссылке.");
        }
        return intersection(region.getLeft(), region.getTop(), region.getWidth(), region.getHeight());
    }

    public RectangularRegion union(int left, int top, int width, int height) {
        boolean f = true;
        int tmp;
        int l = this.left;
        int t = this.top;
        int r = l + this.width;
        int b = t + this.height;
        if(l > left)
        {
            l = left;
            f = false;
        }
        if(t > top)
        {
            t = top;
            f = false;
        }
        if(r < (tmp = left + width))
        {
            r = tmp;
            f = false;
        }
        if(b < (tmp = top + height))
        {
            b = tmp;
            f = false;
        }
        return f ? this : new RectangularRegion(l, t, r - l, b - t);
    }

    public RectangularRegion union(Rectangle region) {
        if(region == null)
        {
            throw new NullPointerException("RectangularRegion.union: аргумент region равен нулевой ссылке.");
        }
        return union(region.getLeft(), region.getTop(), region.getWidth(), region.getHeight());
    }
}
