import {
    SColor,
    SPainter,
    SPath2D,
    SPoint,
    SPolygonUtil,
    SRect
} from "@persagy-web/draw/lib";
import { SMouseEvent } from "@persagy-web/base/lib";
import { SGraphItem } from "@persagy-web/graph/lib";
import {Zone} from "@persagy-web/big/lib/types/floor/Zone";
import {ItemColor, ItemOrder, Transparency} from "@persagy-web/big/lib";

/**
 * 业务空间item
 *
 * @author  郝建龙
 */
export class SZoneItem extends SGraphItem {
    /** 空间所有数据  */
    data: Zone;
    /** 空间轮廓线坐标list  */
    readonly pointArr: SPoint[][][] = [];
    /** X坐标最小值  */
    private minX = Number.MAX_SAFE_INTEGER;
    /** X坐标最大值  */
    private maxX = Number.MIN_SAFE_INTEGER;
    /** Y坐标最小值  */
    private minY = Number.MAX_SAFE_INTEGER;
    /** Y坐标最大值  */
    private maxY = Number.MIN_SAFE_INTEGER;
    /** path    */
    private pathList: SPath2D[] = [];
    /** 点击位置坐标  */
    private clickPoint: SPoint | undefined;
    /** 选中时的颜色  */
    private selectColor: SColor = ItemColor.selectColor;
    /** 不可选时的颜色  */
    private unselectColor: SColor = ItemColor.zoneUnselectColor;
    /** 高亮状态    */
    private _highLightFlag: boolean = false;
    get highLightFlag(): boolean {
        return this._highLightFlag;
    } // Get highLightFlag
    set highLightFlag(value: boolean) {
        this._highLightFlag = value;
        this.update();
    } // Set highLightFlag
    /** 透明度 */
    _transparency: number = 20;
    get transparency(): number {
        return this._transparency;
    } // Get transparency
    set transparency(value: number) {
        this._transparency = value;
        this.update();
    } // Set transparency
    /** 受影响状态   */
    _isInfected: boolean = false;
    get isInfected(): boolean {
        return this._isInfected;
    } // Get isInfected
    set isInfected(value: boolean) {
        this._isInfected = value;
        this.update();
    } // Set isInfected
    /** 受影响的业务空间填充颜色    */
    private infectedColor: SColor = ItemColor.zoneInfectedColor;
    /** 受影响的业务空间边框颜色    */
    private infectedBorder: SColor = ItemColor.zoneInfectedBorder;

    /**
     * 构造函数
     *
     * @param parent    指向父对象
     * @param data      空间数据
     */
    constructor(parent: SGraphItem | null, data: Zone) {
        super(parent);
        this.data = data;
        this.zOrder = ItemOrder.zoneOrder;
        this.highLightFlag = data.HighLightFlag || false;
        this.transparency = data.Transparency || 20;
        this.isInfected = data.Infected || false;
        if (
            this.data.OutLine.length &&
            this.data.OutLine[0] &&
            this.data.OutLine[0].length
        ) {
            let tempArr = this.data.OutLine;
            this.minX = tempArr[0][0][0].X;
            this.maxX = this.minX;
            this.minY = -tempArr[0][0][0].Y;
            this.maxY = this.minY;
            // 处理轮廓点数组,同时计算最大最小值
            this.pointArr = tempArr.map((t): SPoint[][] => {
                let sPath = new SPath2D();
                let tempArr = t.map((it): SPoint[] => {
                    let array = it.map(
                        (item): SPoint => {
                            let x = item.X,
                                y = -item.Y;
                            if (x < this.minX) {
                                this.minX = x;
                            }
                            if (y < this.minY) {
                                this.minY = y;
                            }
                            if (x > this.maxX) {
                                this.maxX = x;
                            }
                            if (y > this.maxY) {
                                this.maxY = y;
                            }
                            return new SPoint(x, y);
                        }
                    );
                    sPath.polygon(array);
                    return array;
                });
                this.pathList.push(sPath);
                return tempArr;
            });
        }
    } // Constructor

    /**
     * Item对象边界区域
     *
     * @return SRect
     */
    boundingRect(): SRect {
        return new SRect(
            this.minX,
            this.minY,
            this.maxX - this.minX,
            this.maxY - this.minY
        );
    } // Function boundingRect()

    /**
     * 鼠标单击事件
     *
     * @param   event   事件参数
     * @return  boolean
     */
    onMouseDown(event: SMouseEvent): boolean {
        if (this.selectable) {
            this.selected = !this.selected;
            this.clickPoint = new SPoint(event.x, event.y);
        }
        this.$emit("click", event);
        return true;
    } // Function onMouseDown()

    /**
     * 鼠标抬起事件
     *
     * @param   event   事件参数
     * @return  boolean
     */
    onMouseUp(event: SMouseEvent): boolean {
        return false;
    } // Function onMouseUp()

    /**
     * 判断点是否在区域内
     *
     * @param x
     * @param y
     */
    contains(x: number, y: number): boolean {
        // return true;
        for (let j = 0; j < this.pointArr.length; j++) {
            let arr = this.pointArr[j];
            if (arr.length < 1 || !SPolygonUtil.pointIn(x, y, arr[0])) {
                continue;
            }
            if (arr.length == 1) {
                return true;
            }
            let flag = false;
            for (let i = 1; i < arr.length; i++) {
                if (SPolygonUtil.pointIn(x, y, arr[i])) {
                    flag = true;
                    break;
                }
            }
            if (flag) {
                continue;
            }
            return true;
        }
        return false;
    } // Function contains()

    /**
     * Item绘制操作
     *
     * @param   painter painter对象
     * @param   rect    绘制区域
     */
    onDraw(painter: SPainter, rect?: SRect): void {
        painter.pen.color = SColor.Transparent;
        if (!this.selectable) {
            painter.brush.color = this.unselectColor;
        } else {
            if (this.selected) {
                painter.brush.color = this.selectColor;
            } else if (this.highLightFlag) {
                painter.brush.color = new SColor(this.data.Color);
            } else if (this.isInfected) {
                painter.brush.color = this.infectedColor;
                // painter.pen.color = this.infectedBorder;
            } else {
                painter.brush.color = new SColor(
                    `${this.data.Color}${Transparency[this.transparency]}`
                );
            }
        }
        painter.pen.lineWidth = painter.toPx(1);
        this.pathList.forEach((t): void => {
            painter.drawPath(t);
        });
        painter.brush.color = SColor.Black;
        painter.font.size = painter.toPx(10);
        if (this.clickPoint) {
            painter.drawText(
                this.data.RoomLocalName,
                this.clickPoint.x,
                this.clickPoint.y
            );
        }
    } // Function onDraw()
} // Class ZoneItem
