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

/**
 * 根据分段数的平面
 * verticesX和verticesY都是xy轴上的顶点数，比分段数多1
 * 
 */
export class Plane extends Mesh {
    /**
     * x轴顶点数目
     */
    private _verticesX: number;
    get verticesX(): number {
        return this._verticesX
    }
    set verticesX(value: number) {
        if (this._verticesX !== value) {
            this._verticesX = value
            this._needRefresh = true;
        }
    }
    /**
     * y轴顶点数目
     */
    private _verticesY: number;
    get verticesY(): number {
        return this._verticesY
    }
    set verticesY(value: number) {
        if (this._verticesY !== value) {
            this._verticesY = value
            this._needRefresh = true;
        }
    }
    /**
     * @param {Texture} texture 
     * @param {int} [verticesX=10] 
     * @param {int} [verticesY=10] 
     */
    constructor(texture: Texture, verticesX: number = 10, verticesY: number = 10) {
        super(texture);
        this._verticesX = verticesX;
        this._verticesY = verticesY;
        this.refresh();
    }

    /**
     * 计算所有坐标
     */
    _refresh() {
        const texture = this.texture;
        const total = this.verticesX * this.verticesY;
        const verts = [];
        const uvs = [];

        const segmentsX = this.verticesX - 1;
        const segmentsY = this.verticesY - 1;

        const sizeX = texture.width / segmentsX;
        const sizeY = texture.height / segmentsY;

        for (let i = 0; i < total; i++) {
            const x = (i % this.verticesX);
            const y = ((i / this.verticesX) | 0);

            verts.push(x * sizeX, y * sizeY);

            uvs.push(x / segmentsX, y / segmentsY);
        }


        this._vertices = new Float32Array(verts);
        this._uvs = new Float32Array(uvs);
        this._indices = calculatePlaneIndices(this.verticesX, this.verticesY);
        //标记dirty
        this._vertexDirty++;

        this.multiplyUvs();
    }
}

/**
 * 计算平面的索引
 * @param verticesX x轴上的顶点数量，最小2
 * @param verticesY y轴上的顶点数量，最小2
 */
export function calculatePlaneIndices(verticesX: number, verticesY: number): Uint16Array {
    const segmentsX = verticesX - 1;
    const segmentsY = verticesY - 1;
    const totalSub = segmentsX * segmentsY;
    const indices = [];
    for (let i = 0; i < totalSub; i++) {
        const xpos = i % segmentsX;
        const ypos = (i / segmentsX) | 0;

        const value = (ypos * verticesX) + xpos;
        const value2 = (ypos * verticesX) + xpos + 1;
        const value3 = ((ypos + 1) * verticesX) + xpos;
        const value4 = ((ypos + 1) * verticesX) + xpos + 1;

        indices.push(value, value2, value3);
        indices.push(value2, value4, value3);
    }
    return new Uint16Array(indices);
}
