export class PolygonAxiosSystem extends FYGE.Container {
    systemContainer: FYGE.Container;
    orginX: number; //原点坐标X，默认0
    orginY: number; //原点坐标Y，默认0
    axiosLineNum: number; //坐标轴个数,默认3
    axiosNodeNum: number; //坐标节点个数（包含原点），默认4个节点
    step: number; //坐标轴的步长，默认40
    rotationDeg: number; //整个坐标系统的旋转角度，单位度，如果不传基准轴水平右；默认0
    labels: any; //坐标轴名称
    style: any; //坐标系统样式
    drawShapeObeject:any;//根据属性绘制的图形
    /**默认样式
     *  style = {
            gridStyle: {
                color: 0x666666,
                width: 1,
            },
            shapeStyle: {
                color: 0x999999,
                width: 5,
            },
            labelStyle: {
                color: "#666666",
                size: 24,
            },
        };
     */
    /**
     * 
     * @param x 原点坐标X
     * @param y 原点坐标y
     * @param axiosLineNum 坐标轴个数,默认3
     * @param axiosNodeNum 坐标节点个数（包含原点），默认4个节点
     * @param step 坐标轴的步长，默认40
     * @param rotationDeg 整个坐标系统的旋转角度，单位度，如果不传基准轴水平右；默认0
     * @param labels 坐标轴名称，默认无
     * @param style 坐标系统样式
     */
    constructor(
        x = 0,
        y = 0,
        axiosLineNum = 3,
        axiosNodeNum = 4,
        step = 40,
        rotationDeg = 0,
        labels = [],
        style = null
    ) {
        super();
        this.orginX = x;
        this.orginY = y;
        this.axiosLineNum = axiosLineNum;
        this.axiosNodeNum = axiosNodeNum;
        this.step = step;
        this.rotationDeg = rotationDeg;
        this.labels = labels;
        let defaultStyle = {
            gridStyle: {
                color: 0xb46e42,
                width: 1,
            },
            shapeStyle: {
                color: 0x95d176,
                alpha: 0.8,
            },
            labelStyle: {
                color: "#7c3c23",
                size: 24,
            },
        };
        this.style = {
            ...defaultStyle,
            ...style,
        };
        this.initUi();
    }
    async initUi() {
        this.position.set(this.orginX,this.orginY);
        var coordsArr = this.computeAxiosCoords();
      
        //绘制三角形
        for (let i = 0; i < this.axiosNodeNum; i++) {
            var shapeCoords = [];
            coordsArr.forEach((el) => {
                shapeCoords.push([el[i][0], el[i][1]]);
            });
            this.drawAxiosShape(shapeCoords);
        }
       //绘制轴线
        for(let i =0 ;i<coordsArr.length-1;i++){
            this.drawAxiosShape(coordsArr[i]);
            if(this.labels.length === this.axiosLineNum ){
                this.drawAxiosLabel(coordsArr[i],i);
            }
        }
    }
    /**
     *
     * @param points 一个坐标轴上所有节点坐标
     * @param index 第几个坐标轴，从0开始
     * @returns
     */
    drawAxiosLabel(points, index) {
        if (this.labels.length === 0) return;
        let text = this.getText(
            this.labels[index],
            this.style.labelStyle.size,
            this.style.labelStyle.color
        );
        let coordsArr = JSON.parse(JSON.stringify(points));
        let len = coordsArr.length;
        let dx = coordsArr[1][0] - coordsArr[0][0];
        let dy = coordsArr[1][1] - coordsArr[0][1];
        let x = coordsArr[len - 1][0];
        let y = coordsArr[len - 1][1];
        let coords = [x, y];
        if (dx < 0) {
            coords[0] = coords[0] - text.textWidth;
        }
        if (dy < 0) {
            coords[1] = coords[1] - text.textHeight;
        }
        this.addChild(text).position.set(coords[0], coords[1]);
    }
    /**
     *
     * @param points
     * @param isDrawGrid 是否是绘制坐标格网，不是就是根据实际值绘制图形。
     * @param isLineShape 实际值如果相差很大，一个很大，另外都为0，就绘制线。
     */
    drawAxiosShape(points, isDrawGrid = true) {
        var data = [];
        points.forEach(el => {
            data.push([Number(el[0].toFixed(2)),Number(el[1]).toFixed(2)])
        });
        points = data;
        let shape = null;
        if (!isDrawGrid) {
            var polygonData = [];
            points.forEach(el => {
                polygonData.push(Number(el[0]),Number(el[1]))
            });
            shape = new FYGE.Graphics();
            shape.beginFill(this.style.shapeStyle.color,this.style.shapeStyle.alpha);
            shape.drawPolygon(polygonData)
        } else {
            shape = new FYGE.Shape();
            shape.beginStroke(
                this.style.gridStyle.color,
                this.style.gridStyle.width
            );
            shape.moveTo(points[0][0], points[0][1]);
            points.forEach((el, index) => {
                if (index !== 0) {
                    shape.lineTo(el[0], el[1]);
                }
            });
            shape.endStroke();
        }
        this.addChild(shape);
        return shape;
    }
    computeAxiosCoords() {
        let baseCoordsArr = [];
        //计算基准轴上的坐标，
        for (let j = 0; j < this.axiosNodeNum; j++) {
            let x = j * this.step;
            let y = 0;
            baseCoordsArr[j] = [x, y];
        }
        //计算基准轴上坐标集合经过旋转后的得到的坐标集合
        //@ts-ignore
        let coordsArr = new Array(this.axiosLineNum).fill([]);
        const vectorArr = this.computeVectorArr();
        for (let i = 0; i < vectorArr.length; i++) {
            let rotationRatio = vectorArr[i]; //旋转系数;
            let coords = [];
            baseCoordsArr.forEach((el) => {
                let x =
                    el[0] * rotationRatio[0][0] + el[1] * rotationRatio[0][1];
                let y =
                    el[0] * rotationRatio[1][0] + el[1] * rotationRatio[1][1];
                coords.push([x, y]);
            });
            coordsArr[i] = coords;
        }
        //所有坐标加上原点坐标
        coordsArr.forEach((el) => {
            el.forEach((item) => {
                item[0] = item[0] ;
                item[1] = item[1] ;
            });
        });
        return coordsArr;
    }
    //计算每个坐标轴相对于基准轴的旋转矢量
    computeVectorArr() {
        //@ts-ignore
        let vectorArr = new Array(this.axiosLineNum).fill([]);
        let stepDeg = 360 / this.axiosLineNum;
        for (let i = 0; i < this.axiosLineNum + 1; i++) {
            let deg = ((i * stepDeg + this.rotationDeg) / 180) * Math.PI;
            vectorArr[i] = [
                [Number(Math.cos(deg).toFixed(5)), Number(-Math.sin(deg).toFixed(5))],
                [Number(Math.sin(deg).toFixed(5)), Number(Math.cos(deg).toFixed(5))],
            ];
        }
        return vectorArr;
    }
    computeRotationVector() {
        let deg = (180 / 180) * Math.PI;
        let rotationVector = [
            [Math.cos(deg), -Math.sin(deg)],
            [Math.sin(deg), Math.cos(deg)],
        ];
        return rotationVector;
    }
    updateData(str) {
        var strArr = str.split(",");
        if (strArr.length !== this.axiosLineNum) {
            console.log("传参个数与坐标轴线条数不一致");
            return;
        }
        this.drawShapeObeject && this.removeChild(this.drawShapeObeject)
        strArr = this.getAddedData(strArr);
        strArr = this.computeInputData(strArr);
        var points = [];
        strArr.forEach((el) => {
            points.push([Number(el), 0]);
        });
        const vectorArr = this.computeVectorArr();
        let coords = [];
        for (let i = 0; i < vectorArr.length - 1; i++) {
            let rotationRatio = vectorArr[i]; //旋转系数;
            let el = points[i];
            let x = el[0] * rotationRatio[0][0] + el[1] * rotationRatio[0][1];
            let y = el[0] * rotationRatio[1][0] + el[1] * rotationRatio[1][1];
            coords.push([x, y]);
        }
        coords.push(coords[0]);
        this.drawShapeObeject = this.drawAxiosShape(coords,false);
    }
    //对坐标数据进行处理，防止数据超限
    computeInputData(inputData) {
        var result = [];
        let len = this.step * (this.axiosNodeNum - 1) - 5; //坐标轴的长度
        inputData.forEach((el) => {
            var ratio = 1 - 100 / (Number(el) + 100);
            result.push(len * ratio);
        });

        return result;
    }
    /**
     * 判断否有小与15的数，有的话所有数都加20，防止数据太小绘不出来
     * @param inputData 输入数据
     */
    getAddedData(inputData) {
        var isNeedAdd = false;
        inputData.forEach((el) => {
            if (Number(el) < 15) {
                isNeedAdd = true;
            }
        });
        let data = [];
        if (!isNeedAdd) {
            return inputData;
        } else {
            inputData.forEach((el) => {
                data.push(Number(el) + 15);
            });
        }
        return data;
    }
    getMaxData(inputData) {
        let max = 0;
        inputData.forEach((el) => {
            if (Number(el) > max) {
                max = Number(el);
            }
        });
        return max;
    }
    getText(
        txt: string,
        size: number,
        color: string = "#eee",
        align: FYGE.TEXT_ALIGN = FYGE.TEXT_ALIGN.LEFT,
        textWidth: number = 0,
        x: number = 0,
        y: number = 0
    ): FYGE.TextField {
        var text = new FYGE.TextField();
        text.fillColor = color;
        text.size = size;
        text.textWidth = textWidth;
        text.textAlign = align;
        text.x = x;
        text.y = y;
        text.text = txt;
        text.bold = true;
        return text;
    }
}