// tslint:disable:only-arrow-functions
// tslint:disable:no-conditional-assignment
// tslint:disable:prefer-const
// tslint:disable:no-var-keyword
// tslint:disable:no-inferrable-types
import { Vector } from "./Vector";
import { degToRad, translateToLocalCor, sqrt3, twoPointsAngleDis, radToDeg } from "./Const";
import { Projection } from "./Projection";
import { Tween } from "../tween/Tween";
import Body from "./Body";
//正三角形
export class RegPolygon extends Body {
    public type = "regPolygon";
    public view;
    public length;
    public _rotation = 0;       //顺时针为正方向,角度制

    _x = 0;
    _y = 0;
    _num;


    //各边的直线方程，以a，b记录
    linesOri = [];

    //原始各点的坐标 考虑是否需要
    // pointsOri;


    //记录边的方向向量顺时针，从左上边开始  未归一
    sideNormals = [];

    //记录点的法向量，顺时针，从上开始 未归一
    pointNormals = [];

    //旋转后的点
    points = [];

    // //中心点到各点长度
    // pointLength;
    // //中心点到各边长度
    // sideLength;

    axes = [];

    projects = [];

    dirty = true;

    constructor(length, view) {
        super();
        this.length = length;
        this.view = view;

        this.calculateNormals();

        this.calculatePoints();

        this.calculateLines()

    }

    get rotation() {
        return this._rotation
    }
    set rotation(value) {
        if (this._rotation != value) {
            this._rotation = value;
            this.view.rotation = value;
            this.view.txt.rotation = -value;
            //计算四条边得方向向量,避免每帧计算   暂时不考虑优化90度
            var rad = value * degToRad;

            this.calculateNormals();

            this.calculatePoints();

            this.dirty = true;
        }
    }

    get x() {
        return this._x;
    }

    set x(value) {
        if (this._x != value) {
            this._x = value;
            this.view.x = value;
            //
            this.dirty = true;
        }
    }

    get y() {
        return this._y;
    }

    set y(value) {
        if (this._y != value) {
            this._y = value;
            this.view.y = value;
            //
            this.dirty = true;


        }
    }

    get num() {
        return this._num;
    }

    set num(value) {
        if (this._num != value) {
            this._num = value;
            this.view.txt.text = value||3 + "";
        }
    }
    //新增，矫正偏移
    get _viewx(){
        return this.view.x;
    }
    get _viewy(){
        return this.view.y;
    }

    //根据继承重写
    calculateNormals() {

    }
    //根据继承重写
    calculatePoints() {

    }

    calculateLines() {

    }


    getAxes() {
        var v1 = new Vector(); //代表多边形的相邻两点
        var v2 = new Vector();
        var axes = [];
        var thisvx = this._viewx
        var thisvy = this._viewy;

        for (var i = 0; i < this.points.length - 1; i++) {  //遍历多边形所有相邻的点得去所有的投影轴
            v1.x = this.points[i].x + thisvx;
            v1.y = this.points[i].y + thisvy;

            v2.x = this.points[i + 1].x +thisvx;
            v2.y = this.points[i + 1].y + thisvy;
            axes.push(v1.edge(v2).perpendicularNormal());
        };

        //将收尾两点的投影轴也加入
        v1.x = this.points[this.points.length - 1].x + thisvx;
        v1.y = this.points[this.points.length - 1].y + thisvy;

        v2.x = this.points[0].x + thisvx;
        v2.y = this.points[0].y + thisvy;
        axes.push(v1.edge(v2).perpendicularNormal());
        return axes;
    };

    //得到多边形各个点在某一条投影轴上投影，并得到投影两端点值，传递给投影对象Projection返回投影对象
    project(axis) {
        var scalars = [];  //用于存放所有点向量在投影轴向量上的点积集合，注意点积集合是数量不是向量
        var v = new Vector();
        var self = this;
        var thisvx = this._viewx;
        var thisvy = this._viewy;
        this.points.forEach(function (point) {
            v.x = point.x + thisvx;
            v.y = point.y + thisvy;
            scalars.push(v.dotProduct(axis));
        });
        return new Projection(Math.min.apply(Math, scalars), Math.max.apply(Math, scalars));
    };

    polygonCollidesWithCircle(ball) {
        var v1;
        var v2;
        var ballax = ball._viewx;
        var ballay = ball._viewy;
        // var axes = this.getAxes();
        if (this.dirty) {
            this.dirty = false;
            this.axes = this.getAxes();
            for (var i = 0; i < this.axes.length; i++) {
                this.projects[i] = this.project(this.axes[i])
            }
        }
        var axes = this.axes.slice();
        var closestPoint = this.getPolygonPointClosestToCircle(ball);

        v1 = new Vector(ballax, ballay);
        v2 = new Vector(closestPoint.x, closestPoint.y);

        axes.push(v1.subtract(v2).normalize());

        return !this.separationOnAxes(axes, ball);
    }

    //得到多边形距离圆形最近点
    getPolygonPointClosestToCircle(ball) {
        var min;
        var length;
        var testPoint;
        var closestPoint;

        var ballax = ball._viewx;
        var ballay = ball._viewy;

        var thisax = this._viewx;
        var thisay = this._viewy;

        // tslint:disable-next-line:prefer-for-of
        for (var i = 0; i < this.points.length; i++) {
            testPoint = new Vector(this.points[i].x + thisax, this.points[i].y + thisay);
            length = Math.pow(testPoint.x - ballax, 2) + Math.pow(testPoint.y - ballay, 2);
            if (!min || length < min) {
                min = length;
                closestPoint = testPoint;
            }
        };
        return closestPoint;
    };
    //检测在投影轴上投影是否有分离
    separationOnAxes(axes, ball) {
        var axis;
        var projection1;
        var projection2;
        for (var i = 0; i < axes.length; ++i) {
            axis = axes[i];
            projection1 = ball.project(axis); //得到形状在当前投影轴上的投影
            if (i == axes.length - 1) {
                projection2 = this.project(axis); //得到当前拖拽形状在当前投影轴上的投影
            } else {
                projection2 = this.projects[i]
            }
            if (!projection1.overlaps(projection2)) { //检测两个投影在当前投影轴上是否重叠,分离返回false
                return true;  //在当前投影轴上分离返回true,表示两个形状肯定没有碰撞，不需在检测后面的投影轴了，
            }
        };
        return false; //检测完全部的投影轴上的投影没和一个分离的，返回false;
    }

    //
    collideBall(ball) {
        var ballax = ball._viewx;
        var ballay = ball._viewy;

        var thisax = this._viewx;
        var thisay = this._viewy;

        if (this.polygonCollidesWithCircle(ball)) {
            //如果碰撞。
            //先转换坐标，
            var returnP = translateToLocalCor({ x: ballax, y: ballay }, this.view);
            var velocity = ball.velocity.clone().rotate(-this._rotation * degToRad);
            var deta = Math.floor(velocity.length() / ball.radius) + 1    //deta就是插值数量,如为0，则直接取上一帧的法向量

            var speedX = velocity.x / (deta + 1);
            var speedY = velocity.y / (deta + 1);

            for (var i = 0; i <= deta; i++) {
                this.ballPosition(ball, deta + 1, i + 1)
                if (!this.polygonCollidesWithCircle(ball)) {
                    //算此时的球的位置所对应碰撞的法向量
                    var noraml = this.nearestCollideNormal({ x: returnP.x - speedX * (i + 1), y: returnP.y - speedY * (i + 1) });
                    //如果normal和速度方向一致则判断不碰撞，还原球的位置  暂时没用，去掉
                    //    if(!noraml) console.log(noraml)
                    //     if(noraml.parallel(velocity)){
                    //         console.log(2322)
                    // ball.view.x += ball.velocity.x / (deta + 1) * (i + 1);
                    // ball.view.y += ball.velocity.y / (deta + 1) * (i + 1);
                    // return false
                    // }else{
                    // console.log("多边形碰撞返回",noraml);
                    return noraml
                    // }
                }
            }
            ball.view.x += ball.velocity.x;
            ball.view.y += ball.velocity.y;
            return false;
        } else {
            return false
        }
    }



    //同样可以进行碰撞检测，考虑之   继承时重写
    nearestCollideNormal(returnP): Vector {

        return
    }





    private ballPosition(ball, deta, i) {
        ball.view.x -= ball.velocity.x / deta;
        ball.view.y -= ball.velocity.y / deta;
    }


    public shake() {
        var startx = -this.view.bg.anchorX;
        var starty = -this.view.bg.anchorY;
        this.view.bg.x = startx;
        this.view.bg.y = starty;
        Tween.to(this.view.bg, 1, {
            x: startx+3,
            y: starty+3,
            yoyo: 2,
            useFrame: true,
            onComplete: function () {
            }

        })
    }
}