import { SHAPES } from '../../const';
import { Point } from '../../math';

/**
 * The Rounded Rectangle object is an area that has nice rounded corners, as indicated by its
 * top-left corner point (x, y) and by its width and its height and its radius.
 */
export default class RoundedRectangle {

    x: number;
    y: number;
    width: number;
    height: number;

    /**
     * @member {number}
     * @default 20
     */
    radius: number;
    type: number;
    /**
     * @param {number} [x=0] - The X coordinate of the upper-left corner of the rounded rectangle
     * @param {number} [y=0] - The Y coordinate of the upper-left corner of the rounded rectangle
     * @param {number} [width=0] - The overall width of this rounded rectangle
     * @param {number} [height=0] - The overall height of this rounded rectangle
     * @param {number} [radius=20] - Controls the radius of the rounded corners
     */
    constructor(
        x: number = 0,
        y: number = 0,
        width: number = 0,
        height: number = 0,
        radius: number = 20
    ) {
        this.x = x;

        this.y = y;

        this.width = width;

        this.height = height;
        //计算最大圆角
        let max = (width < height ? width : height) / 2;
        //小于0取反
        radius = radius < 0 ? -radius : radius;
        //大于max取max
        radius = radius > max ? max : radius;

        //等于最大圆角时额外处理下，否则有点重合
        if (radius == max) radius -= 0.0000000001

        this.radius = radius;

        this.type = SHAPES.RREC;
    }

    /**
     * Creates a clone of this Rounded Rectangle
     *
     * @return {RoundedRectangle} a copy of the rounded rectangle
     */
    clone(): RoundedRectangle {
        return new RoundedRectangle(this.x, this.y, this.width, this.height, this.radius);
    }

    /**
     * Checks whether the x and y coordinates given are contained within this ellipse
     *
     * @param {Point} point - The  point to test
     * @return {boolean} Whether the x/y coords are within this ellipse
     */
    isPointIn(point: Point): boolean {
        var x = point.x;
        var y = point.y;
        if (this.width <= 0 || this.height <= 0) {
            return false;
        }
        if (x >= this.x && x <= this.x + this.width) {
            if (y >= this.y && y <= this.y + this.height) {
                if ((y >= this.y + this.radius && y <= this.y + this.height - this.radius)
                    || (x >= this.x + this.radius && x <= this.x + this.width - this.radius)) {
                    return true;
                }
                let dx = x - (this.x + this.radius);
                let dy = y - (this.y + this.radius);
                const radius2 = this.radius * this.radius;

                if ((dx * dx) + (dy * dy) <= radius2) {
                    return true;
                }
                dx = x - (this.x + this.width - this.radius);
                if ((dx * dx) + (dy * dy) <= radius2) {
                    return true;
                }
                dy = y - (this.y + this.height - this.radius);
                if ((dx * dx) + (dy * dy) <= radius2) {
                    return true;
                }
                dx = x - (this.x + this.radius);
                if ((dx * dx) + (dy * dy) <= radius2) {
                    return true;
                }
            }
        }

        return false;
    }
}
