import { Mesh } from './Mesh';
import { Texture } from '../texture';
import { Point } from '../math';

//  function testRope() {
//     let count = 0;
//     // build a rope!
//     const ropeLength = 918 / 20;
//     const points = [];
//     for (let i = 0; i < 20; i++) {
//         points.push(new Point(i * ropeLength, 0));
//     }

//     const strip = new Rope(Texture.fromImage("snake.png"), points);

//     strip.x = -459;

//     const snakeContainer = new Container();
//     snakeContainer.x = 400;
//     snakeContainer.y = 300;

//     snakeContainer.scale.set(800 / 1100, 800 / 1100);
//     this.addChild(snakeContainer);

//     snakeContainer.addChild(strip);
//     this.addEventListener(Event.ENTER_FRAME, () => {
//         count += 0.1;
//         for (let i = 0; i < points.length; i++) {
//             points[i].y = Math.sin((i * 0.5) + count) * 30;
//             points[i].x = i * ropeLength + Math.cos((i * 0.3) + count) * 20;
//         }
//         strip.refreshVertices()
//     }, this)
// }
/**
 * 为了能加入批处理，不用TRIANGLE_STRIP方式渲染(有需要看v4版本的pixi)，还是用TRIANGLE
 *```js
 * for (let i = 0; i < 20; i++) {
 *     points.push(new Point(i * 50, 0));
 * };
 * let rope = new Rope(Texture.fromImage("snake.png"), points);
 *  ```
 *
 *
 */
export class Rope extends Mesh {
    /**
     * 一组点
     */
    points: Point[];
    /**
     * 是否自动更新顶点，为true,自动更新顶点，否则在points里顶点修改后，自行refreshVertices
     */
    autoUpdateVertices: boolean;

    /**
     * 以横向的为基准，纹理高度
     */
    private textureHeight: number;
    /**
     * @param {Texture} texture
     * @param {Point[]} points
     */
    constructor(texture: Texture, points: Point[]) {
        super(texture);

        this.points = points;

        this._vertices = new Float32Array(points.length * 4);

        this._uvs = new Float32Array(points.length * 4);

        this._indices = new Uint16Array((points.length - 1) * 6);

        this.textureHeight = texture.height;

        this.refresh(true);
        this.refreshVertices();
    }

    /**
     * 计算索引和uv，和顶点计算的要分开
     */
    _refresh() {
        const points = this.points;

        //没点，或贴图uv为空
        if (points.length < 1 || !this.texture._uvs) return;

        //如果顶点数量有变
        if (this._vertices.length / 4 !== points.length) {
            this._vertices = new Float32Array(points.length * 4);
            this._uvs = new Float32Array(points.length * 4);
            this._indices = new Uint16Array((points.length - 1) * 6);
        }

        const uvs = this._uvs;

        const indices = this._indices;

        uvs[0] = 0;
        uvs[1] = 0;
        uvs[2] = 0;
        uvs[3] = 1;

        // indices[0] = 0;
        // indices[1] = 1;

        const total = points.length;

        for (let i = 1; i < total; i++) {
            // time to do some smart drawing!
            let index = i * 4;
            const amount = i / (total - 1);

            uvs[index] = amount;
            uvs[index + 1] = 0;

            uvs[index + 2] = amount;
            uvs[index + 3] = 1;
        }

        let indexCount = 0;

        for (let i = 0; i < total - 1; i++) {
            const index = i * 2;

            indices[indexCount++] = index;
            indices[indexCount++] = index + 1;
            indices[indexCount++] = index + 2;

            indices[indexCount++] = index + 2;
            indices[indexCount++] = index + 1;
            indices[indexCount++] = index + 3;
        }

        this.multiplyUvs();
        // this.refreshVertices();
    }

    /**
     * 根据points刷新顶点
     */
    refreshVertices() {
        const points = this.points;

        //
        if (points.length < 1) return;

        //如果points数量修改过，去执行_refresh
        if (this._vertices.length / 4 !== points.length) {
            this._refresh();//里面肯定会把_vertices的长度矫正
            this.refreshVertices();
            return;
        }

        let lastPoint = points[0];
        let nextPoint;
        let perpX = 0;
        let perpY = 0;

        // this.count -= 0.2;

        const vertices = this._vertices;
        const total = points.length;

        for (let i = 0; i < total; i++) {
            const point = points[i];
            const index = i * 4;

            if (i < points.length - 1) {
                nextPoint = points[i + 1];
            }
            else {
                nextPoint = point;
            }

            perpY = -(nextPoint.x - lastPoint.x);
            perpX = nextPoint.y - lastPoint.y;

            let ratio = (1 - (i / (total - 1))) * 10;

            if (ratio > 1) {
                ratio = 1;
            }

            const perpLength = Math.sqrt((perpX * perpX) + (perpY * perpY));
            const num = this.textureHeight / 2; // (20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio;

            perpX /= perpLength;
            perpY /= perpLength;

            perpX *= num;
            perpY *= num;

            vertices[index] = point.x + perpX;
            vertices[index + 1] = point.y + perpY;
            vertices[index + 2] = point.x - perpX;
            vertices[index + 3] = point.y - perpY;

            lastPoint = point;
        }
        //标记修改
        this._vertexDirty++;
    }

    update() {
        super.update();
        //自动更新顶点，或者纹理高度有修改
        if (this.autoUpdateVertices || this.textureHeight !== this.texture.height) {
            this.textureHeight = this.texture.height
            this.refreshVertices();
        }
    }
}
