import { Tool } from "../Tool";
import { PathData } from "../interface/PathData";
import { RES } from "../../../module/RES";

//画背景图
export function drawBg(paths: PathData[], lattices?: number[]) {
    // var bg = new FYGE.Container();
    // bg.addChild(drawShape(paths));
    var bg = drawShape(paths);
    //画格子,由于都一样的长宽
    var texture: FYGE.Texture = RES.getRes("rectLat.png")
    for (var m = 0; m < lattices.length; m++) {
        if (lattices[m]) {
            var rc = Tool.indexToRc(m);
            // if ((!(rc[0] % 2) && !(rc[1] % 2)) || (rc[0] % 2 && rc[1] % 2)) {
            let p = Tool.getPositionByIndex(m);
            let img = new FYGE.Sprite(texture);
            img.x = p[0] - texture.width / 2;
            img.y = p[1] - texture.height / 2;
            img.width = 78;
            img.height = 78;
            bg.addChild(img)
            // }
        }
    }
    bg.updateShape()//只有这样之后bounds才是正确的，注意引擎有时间修改
    //缓存掉
    var bounds = bg.getLocalBounds();
    let w: number = bounds.width;
    let h: number = bounds.height;
    let x: number = bounds.x;
    let y: number = bounds.y;
    var _dCanvas: HTMLCanvasElement = FYGE.createCanvas();
    _dCanvas.width = w;
    _dCanvas.height = h;
    var _dRender = new FYGE.CanvasRenderer(_dCanvas.getContext("2d"), w, h);
    bg.transform.updateLocalMatrix();
    var tempMatrix = new FYGE.Matrix()
    tempMatrix.copy(bg.transform.localMatrix);
    tempMatrix.invert();
    tempMatrix.tx -= x;
    tempMatrix.ty -= y;
    _dRender.render(bg, null, tempMatrix);
    var c = new FYGE.Container();
    c.addChild(new FYGE.Sprite(FYGE.Texture.fromCanvas(_dCanvas)))
        .position.set(x, y)
    return c
}
export function drawShape(paths: PathData[]): FYGE.Shape {
    var shape = new FYGE.Shape();
    shape.beginFill(0x111937, 1);//指令中有beginPath,会中断之前绘制得路径，会导致clip只有最后一段poly有效
    for (var i = 0; i < paths.length; i++) {
        var path = paths[i];
        drawPoly(shape, path)
        //画洞了
        for (var j = 0; j < path.holes.length; j++) {
            var hole = path.holes[j];
            drawPoly(shape, hole)
        }
        //最终绘制
        shape.endFill()
    }
    return shape
}
//画多边形路径
export function drawPoly(shape: FYGE.Shape, path: PathData) {
    var firstFrom;
    for (var j = 0; j < path.points.length; j += 2) {
        //当前点

        var p = [path.points[j], path.points[j + 1]]
        //上一个点
        var lastIndex = j == 0 ? path.points.length - 2 : j - 2;
        var pl = [path.points[lastIndex], path.points[lastIndex + 1]]
        //下一个点
        var nextIndex = j == path.points.length - 2 ? 0 : j + 2
        var pn = [path.points[nextIndex], path.points[nextIndex + 1]]

        //算两个点
        var from: number[], to: number[];
        //x相同 同一列
        if (Math.abs(p[0] - pl[0]) < 0.1) {
            var d = p[1] - pl[1] < 0 ? 1 : -1
            from = [p[0], p[1] + d * Tool.radius];
            var dt = p[0] - pn[0] < 0 ? 1 : -1
            to = [p[0] + dt * Tool.radius, p[1]]
        }
        //y相同，同一行
        else {
            var d = p[0] - pl[0] < 0 ? 1 : -1
            from = [p[0] + d * Tool.radius, p[1]]
            var dt = p[1] - pn[1] < 0 ? 1 : -1
            to = [p[0], p[1] + dt * Tool.radius]
        }

        if (j == 0) {
            //第一个点，需要moveTo
            shape.moveTo(from[0], from[1]);
            shape.quadraticCurveTo(p[0], p[1], to[0], to[1]);
            firstFrom = [from[0], from[1]]
        }
        else {
            shape.lineTo(from[0], from[1]);
            shape.quadraticCurveTo(p[0], p[1], to[0], to[1]);
        }
    }
    //连回第一个点
    shape.lineTo(firstFrom[0], firstFrom[1]);
}

const dis = {
    "l": -Tool.width / 2,
    "r": Tool.width / 2,
    "u": -Tool.height / 2,
    "d": Tool.height / 2,
}

/**
 * 生成格子背景的路径
 * @param lattices
 */
export function generateMapBg(lattices: number[]): PathData[] {
    // lattices = [
    //     0, 0, 0, 0, 0, 0, 0, 0, 0,
    //     0, 0, 1, 1, 1, 1, 1, 0, 0,
    //     0, 0, 1, 0, 1, 0, 1, 0, 0,
    //     0, 0, 1, 0, 1, 0, 1, 0, 0,
    //     0, 0, 1, 0, 1, 0, 1, 0, 0,
    //     0, 0, 1, 0, 1, 0, 1, 0, 0,
    //     0, 0, 1, 1, 1, 1, 1, 0, 0,
    //     0, 0, 0, 0, 0, 0, 0, 0, 0,
    //     0, 0, 0, 0, 0, 0, 0, 0, 0,
    // ]
    var vertexs = getVertexs(lattices);
    var paths: PathData[] = [];
    //先遍历，找到第一个有元素的，然后延一个点一直遍历，直到一个圈的路径
    //怎么把洞给标出来，
    for (var i = 0; i < vertexs.length; i++) {
        //周围至少右一个
        // console.log(vertexs)
        if (vertexs[i].indexOf(1) > -1) {
            var p = Tool.getPositionByIndex10(i)
            //判断是否在groups内
            var group = judgeInGroups(i, paths, vertexs[i])
            if (group) {
                //如果时内部的点，要考虑洞
                if (group.indexs10.indexOf(i) < 0) {
                    //判断是否是洞,周围至少一个0
                    if (vertexs[i].indexOf(0) > -1) {
                        //判断是否在洞内
                        var hole = judgeOnGroups(i, group.holes, vertexs[i]);
                        if (hole) {
                            if (hole.indexs10.indexOf(i) < 0) {
                                // hole.indexs10.push(i)
                            }
                        } else {
                            group.holes.push(beenLoop(i, vertexs))
                        }
                    } else {
                        // group.indexs10.push(i);
                    }
                }
            } else {
                paths.push(beenLoop(i, vertexs))
            }
        }
    }
    return paths
}

/**
 * 判断点是否在多边形内
 * @param point
 * @param points
 */
function isPointIn(point: number[], points: number[]): boolean {
    var x = point[0];
    var y = point[1];
    let inside = false;
    const length = points.length / 2;
    for (let i = 0, j = length - 1; i < length; j = i++) {
        const xi = points[i * 2];
        const yi = points[(i * 2) + 1];
        const xj = points[j * 2];
        const yj = points[(j * 2) + 1];
        const intersect = ((yi > y) !== (yj > y)) && (x < ((xj - xi) * ((y - yi) / (yj - yi))) + xi);
        if (intersect) {
            inside = !inside;
        }
    }
    return inside;
}

function judgeInGroups(index: number, groups: PathData[], vertex: number[]): PathData {
    var p = Tool.getPositionByIndex10(index)
    for (var i = 0; i < groups.length; i++) {
        var group = groups[i];
        if (isPointIn(p, group.points)) {
            if (group.indexs10.indexOf(index) == -1) {
                return group
            }
        }
    }

    var groupsArr: PathData[] = [];
    for (var i = 0; i < groups.length; i++) {
        var group = groups[i];
        //还要判断是否可能是下一个的起点
        if (group.indexs10.indexOf(index) > -1) {
            groupsArr.push(group)
        }
    }
    if (groupsArr.length >= 2) {
        //如果超过2,肯定不为null
        return groupsArr[1]
    } else {
        for (var i = 0; i < groupsArr.length; i++) {
            var g = groupsArr[i]
            var obj = statisticalFieldNumber(g.indexs10);
            //有些组
            if (obj[index] >= 2) {
                return g
            }
            //1个时，
            else {
                //暂时只考虑一种情况
                if (vertex[0] && vertex[2] && !vertex[1] && !vertex[3]) {
                    return null
                } else {
                    return g
                }
            }
        }
    }
    return null;
}
//判断是否在某个路径上
function judgeOnGroups(index: number, groups: PathData[], vertex: number[]): PathData {
    var groupsArr: PathData[] = [];
    for (var i = 0; i < groups.length; i++) {
        var group = groups[i];
        //还要判断是否可能是下一个的起点
        if (group.indexs10.indexOf(index) > -1) {
            groupsArr.push(group)
        }
    }
    if (groupsArr.length >= 2) {
        //如果超过2,肯定不为null
        return groupsArr[1]
    } else {
        for (var i = 0; i < groupsArr.length; i++) {
            var g = groupsArr[i]
            var obj = statisticalFieldNumber(g.indexs10);
            //有些组
            if (obj[index] >= 2) {
                return g
            }
            //1个时，
            else {
                //暂时只考虑一种情况
                if (vertex[0] && vertex[2] && !vertex[1] && !vertex[3]) {
                    return null
                } else {
                    return g
                }
            }
        }
    }
    return null
}


/**
 * 返回各种元素的个数
 *  var  arr = [0,1,2,3,4,5,6,0,0];
 * console.log(statisticalFieldNumber(arr));
 * {0: 3, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1}
 * @param arr
 */
function statisticalFieldNumber(arr: any[]) {
    return arr.reduce(function (prev, next) {
        prev[next] = (prev[next] + 1) || 1;
        return prev;
    }, {});
}


//遍历连接
function beenLoop(index: number, vertexs: number[][]): PathData {
    //记录所有遍历过的索引
    var group: PathData = {
        indexs: [],
        points: [],
        holes: [],
        indexs10: []
    };
    //第一个点
    // group.indexs10.push(index);
    // var point = getPositionByIndex10(index);
    // group.points.push(point[0], point[1]);
    //顺时针遍历,找到满足的格子
    var directionsOri = ["r", "l", "u", "d"];
    var antDirections = {
        "r": "l",
        "l": "r",
        "u": "d",
        "d": "u"
    }
    let curIndex: number;
    //上一个过来的方向，很重要,
    let lastDirection: string
    let lastIndex: number;
    while (curIndex != index) {
        lastIndex = curIndex || index;
        //求得行列
        var rc = Tool.indexToRc10(lastIndex);
        var directionAll = {
            "r": rc[1] < Tool.colNum ? lastIndex + 1 : null,
            "l": rc[1] > 0 ? lastIndex - 1 : null,
            "u": rc[0] > 0 ? lastIndex - Tool.colNum - 1 : null,
            "d": rc[0] < Tool.rowNum ? lastIndex + Tool.colNum + 1 : null
        }
        //去掉来的反方向
        var directions = directionsOri.slice();
        if (lastDirection) Tool.removeEle(antDirections[lastDirection], directions);

        var direction: string
        for (var i = 0; i < directions.length; i++) {
            var dIndex = directionAll[directions[i]]
            if (dIndex != null) {
                if (vertexs[dIndex].indexOf(1) > -1 && vertexs[dIndex].indexOf(0) > -1) {
                    //再判断右手准则：指下必须有，指上必须无，拐点特殊判断
                    if (getDown(lastIndex, dIndex, vertexs) &&
                        !getUp(lastIndex, dIndex, vertexs) &&
                        getCorner(lastDirection, directions[i], lastIndex, vertexs)) {

                        curIndex = dIndex;
                        direction = directions[i];
                        break
                    }
                }
            }
        }
        if (curIndex == index) {
            group.indexs10.push(lastIndex);
            if (lastDirection != direction) {
                var point = Tool.getPositionByIndex10(lastIndex);
                group.points.push(point[0], point[1]);
                lastDirection = direction
            }
            //这里就break吧
            break
        } else {
            group.indexs10.push(lastIndex);
            if (lastDirection == direction) {

            } else {
                var point = Tool.getPositionByIndex10(lastIndex);
                group.points.push(point[0], point[1]);
                lastDirection = direction
            }
        }
    }
    //多判断一次，第一个点是否在第二个点和最后一个点之间,是就去掉位置
    clearGroup(group);
    return group
}

//取顶点格子左上角格子索引
function getLeftUp(index: number): number {
    var rc = Tool.indexToRc10(index);
    if (rc[0] > 0 && rc[1] > 0) {
        return Tool.rcToIndex(rc[0] - 1, rc[1] - 1)
    } else {
        return null
    }
}
//取顶点格子右上角格子索引
function getRightUp(index: number): number {
    var rc = Tool.indexToRc10(index);
    if (rc[0] > 0 && rc[1] < Tool.colNum) {
        return Tool.rcToIndex(rc[0] - 1, rc[1])
    } else {
        return null
    }
}
//取顶点格子右下角格子
function getRightDown(index: number): number {
    var rc = Tool.indexToRc10(index);
    if (rc[0] < Tool.rowNum && rc[1] < Tool.colNum) {
        return Tool.rcToIndex(rc[0], rc[1])
    } else {
        return null
    }
}
//取顶点格子左下角格子
function getLeftDown(index: number): number {
    var rc = Tool.indexToRc10(index);
    if (rc[0] < Tool.rowNum && rc[1] > 0) {
        return Tool.rcToIndex(rc[0], rc[1] - 1)
    } else {
        return null
    }
}

//根据两个顶点索引，有顺序，取下是否有
function getDown(l: number, r: number, vertexs: number[][]) {
    var rcL = Tool.indexToRc10(l);
    var rcR = Tool.indexToRc10(r);
    if (rcR[1] - rcL[1] == 1) {
        //正下方
        return vertexs[l][2]
    }
    if (rcR[0] - rcL[0] == 1) {
        //左边
        return vertexs[l][3]
    }
    if (rcR[1] - rcL[1] == -1) {
        //上边
        return vertexs[l][0]
    }
    if (rcR[0] - rcL[0] == -1) {
        //右边
        return vertexs[l][1]
    }
}
////根据两个顶点索引，有顺序，取上是否有
function getUp(l: number, r: number, vertexs: number[][]) {
    var rcL = Tool.indexToRc10(l);
    var rcR = Tool.indexToRc10(r);
    if (rcR[1] - rcL[1] == 1) {
        //上方
        return vertexs[l][1]
    }
    if (rcR[0] - rcL[0] == 1) {
        //右边
        return vertexs[l][2]
    }
    if (rcR[1] - rcL[1] == -1) {
        //下边
        return vertexs[l][3]
    }
    if (rcR[0] - rcL[0] == -1) {
        //左边
        return vertexs[l][0]
    }
}
//特定方向时。必须拐点有
function getCorner(lastD: string, curD: string, lastI: number, vertexs: number[][]) {
    if (lastD == "r" && curD == "u") {
        //右，上
        return vertexs[lastI][2]
    }
    if (lastD == "d" && curD == "r") {
        //下，右
        return vertexs[lastI][3]
    }
    if (lastD == "l" && curD == "d") {
        //左，下
        return vertexs[lastI][0]
    }
    if (lastD == "u" && curD == "l") {
        //上，左
        return vertexs[lastI][1]
    }
    return true
}
//第一个点是否在第二个点和最后一个点之间,是就去掉位置信息
function clearGroup(group: PathData) {
    var one = group.indexs10[0];
    var two = group.indexs10[1];
    var Last = group.indexs10[group.indexs10.length - 1];
    var rc1 = Tool.indexToRc10(one);
    var rc2 = Tool.indexToRc10(two);
    var rcL = Tool.indexToRc10(Last);
    if ((rc1[0] == rc2[0] && rc1[0] == rcL[0]) || (rc1[1] == rc2[1] && rc1[1] == rcL[1])) {
        // group.indexs10.shift();
        group.points.shift();
        group.points.shift();
    }
}

const getIndex9 = [
    getLeftUp,
    getRightUp,
    getRightDown,
    getLeftDown
]

/**
 * 10*10的顶点的信息，[0,1,0,1]分别代表，左上lu，右上ru，右下rd，左下ld是否右格子
 */
function getVertexs(lattices: number[]): number[][] {
    var vertexs: number[][] = [];
    var rowNum = Tool.rowNum + 1;
    var colNum = Tool.colNum + 1;
    for (var i = 0; i < rowNum * colNum; i++) {
        //对每个顶点，push
        var indexs = [];
        for (var m = 0; m < 4; m++) {
            var index = getIndex9[m](i)
            if (index != null && lattices[index]) {
                indexs.push(1)
            } else {
                indexs.push(0)
            }
        }
        vertexs.push(indexs)
    }
    return vertexs
}
