import { Constructor } from '@angular/material/core/common-behaviors/constructor';
import * as PIXI from 'pixi.js';
import { Point, Rectangle, Graphics, Container } from 'pixi.js';
import { WorkingAreaComponent } from '../working-area.component';

/**
 * 安信形状
 */
export class AxShape extends Graphics {
    assetData: any;
    pointTexture: PIXI.Texture = PIXI.Texture.from('assets/images/handle-main.png');
    workingArea: WorkingAreaComponent;
    // 允许选择
    allowSelect = true;
    // 允许编辑
    allowEdit = true;
    // 是否显示名称
    showName = true;
    // 边框
    border: PIXI.Graphics = new PIXI.Graphics();
    // 鼠标位置
    mousePosition: PIXI.Point;
    // 鼠标拖动
    mouseDragging: boolean;

    constructor(assetData: any, workingArea: WorkingAreaComponent) {
        super();
        this.border.visible = false;
        this.addChild(this.border);
        this.assetData = assetData;
        this.workingArea = workingArea;
        this.workingArea.backgroundImage.addChild(this);
        this.zIndex = 200;
        this.interactive = true;
        // this.buttonMode = true;
        this
            .on('pointerdown', event => {
                event.stopPropagation();
                if (this.allowSelect
                    && event.data.button === 0) {
                    this.workingArea.select(this);
                }
                if (this.allowEdit) {
                    this.mouseDragging = true;
                    this.mousePosition = new PIXI.Point(event.data.global.x, event.data.global.y);
                }
            })
            .on('pointerup', event => {
                this.mouseDragging = false;
            })
            .on('pointerupoutside', event => {
                this.mouseDragging = false;
            })
            .on('pointermove', event => {
                if (this.mouseDragging) {
                    this.workingArea.selection.all().forEach(item => {
                        const x = event.data.global.x - this.mousePosition.x;
                        const y = event.data.global.y - this.mousePosition.y;
                        item.x += x * (1 / this.workingArea.camera2D.scale.x);
                        item.y += y * (1 / this.workingArea.camera2D.scale.y);
                        item.assetData.Point = new PIXI.Point(item.x, item.y);
                        this.workingArea.canvasData.isChange = true;
                    });
                    this.mousePosition = new PIXI.Point(event.data.global.x, event.data.global.y);
                }
            })
            .on('rightclick', event => {
                this.border.visible = false;
            });
    }
    redraw(): void {

    }

    refresh(): void {

    }
    public setItemScale(scale: number) {

    }

    public showBorder() {
        this.border.visible = true;
    }
    /**
     * 隐藏边框
     */
    public hideBorder() {
        this.border.visible = false;
    }
    /**
 * 设置点显示状态
 * @param value 显示状态
 */
    public setPointVisiable(value: boolean) {

    }
    /**
   *
   * @param rect 画边框
   */
    public drawBorder(scale: number) {
        scale = this.assetData.FixedSize ? 1 : scale;
        this.border.clear();
        const rect = this.getLocalBounds();
        const p1 = new PIXI.Point(rect.left, rect.top);
        const p2 = new PIXI.Point(rect.right, rect.top);
        const p3 = new PIXI.Point(rect.right, rect.bottom);
        const p4 = new PIXI.Point(rect.left, rect.bottom);

        this.border.lineStyle(scale * 1, 0x00a8ff);

        const spaceLength = scale * 1;
        const lineLenght = rect.width + 0.5 + 0.5;
        const dashLength = scale * (lineLenght + spaceLength - Math.floor((rect.width + rect.height) / 2 / 4.1)) / Math.floor((rect.width + rect.height) / 2 / 4.1);
        this.drawDash(this.border, p1.x - 0.5 * scale, p1.y, p2.x + 0.5 * scale, p2.y, dashLength, spaceLength);
        this.drawDash(this.border, p2.x, p2.y - 0.5 * scale, p3.x, p3.y + 0.5 * scale, dashLength, spaceLength);
        this.drawDash(this.border, p3.x + 0.5 * scale, p3.y, p4.x - 0.5 * scale, p4.y, dashLength, spaceLength);
        this.drawDash(this.border, p4.x, p4.y + 0.5 * scale, p1.x, p1.y - 0.5 * scale, dashLength, spaceLength);

        this.border.lineStyle(0, 0x0000ff);
        // this.border.beginFill(0x00ff00,0.1);
        this.border.moveTo(p1.x, p1.y);
        this.border.lineTo(p2.x, p2.y);
        this.border.lineTo(p3.x, p4.y);
        this.border.lineTo(p4.x, p4.y);
        this.border.closePath();
        // this.border.endFill();
    }
    // 画虚线
    drawDash(target, x1, y1, x2, y2, dashLength = 5, spaceLength = 1) {
        const x = x2 - x1;
        const y = y2 - y1;
        let hyp = Math.sqrt((x) * (x) + (y) * (y));
        const units = hyp / (dashLength + spaceLength);
        const dashSpaceRatio = dashLength / (dashLength + spaceLength);
        const dashX = (x / units) * dashSpaceRatio;
        const spaceX = (x / units) - dashX;
        const dashY = (y / units) * dashSpaceRatio;
        const spaceY = (y / units) - dashY;

        target.moveTo(x1, y1);

        while (hyp > 0) {
            x1 += dashX;
            y1 += dashY;
            hyp -= dashLength;
            if (hyp < 0) {
                x1 = x2;
                y1 = y2;
            }
            target.lineTo(x1, y1);
            x1 += spaceX;
            y1 += spaceY;
            target.moveTo(x1, y1);
            hyp -= spaceLength;
        }
        target.moveTo(x2, y2);
    }
    // 计算多边形重心
    public calculatePolygonGravityCenter(points: PIXI.Point[]) {
        let area = 0.0; // 多边形面积
        let gravityLat = 0.0; // 重心点 latitude
        let gravityLng = 0.0; // 重心点 longitude
        points.forEach((item, index) => {
            // 1
            const lat = item.x;
            const lng = item.y;
            const nextLat = points[(index + 1) % points.length].x;
            const nextLng = points[(index + 1) % points.length].y;
            // 2
            const tempArea = (nextLat * lng - nextLng * lat) / 2.0;
            // 3
            area += tempArea;
            // 4
            gravityLat += tempArea * (lat + nextLat) / 3;
            gravityLng += tempArea * (lng + nextLng) / 3;
        });
        // 5
        gravityLat = gravityLat / area;
        gravityLng = gravityLng / area;

        return new PIXI.Point(gravityLat, gravityLng);
    }
    // 计算线段中点坐标
    public getLineCenter(point1: PIXI.Point, point2: PIXI.Point) {
        return new PIXI.Point((point1.x + point2.x) / 2, (point1.y + point2.y) / 2);
    }
}