class BufferAttribute {
    /**
     * 实际数据数量，比如顶点个数，array/itemSize
     */
    public count: number;

    public name: string;
    /**
     * 是否需要更新标识，如果glBuffer的_updateId与_dirtyId不一致，就需要upload
     */
    _dirtyId: number = 0;
	/**
	 * array作为原数据要被传入glBuffer
	 * @param array Int8Array,Uint8Array, Int16Array,Uint16Array,Uint32Array,Float32Array等类型化数组
	 * @param itemSize 步长，比如位置是3
	 * @param normalized 是否标准化 默认false
	 */
    constructor(
        public array: any,
        public itemSize: number,
        public normalized: boolean = false
    ) {
        if (Array.isArray(array)) {
            throw new TypeError('array必须士类型化数组');
        }
        this.count = array !== undefined ? array.length / itemSize : 0;
    }

	/**
	 * 重写覆盖
	 * @param value 普通数组，或类型化数组
	 * @param offset 默认0
	 */
    set(value, offset: number = 0) {
        this.array.set(value, offset);
        return this;
    }
	/**
	 * 重置数据
	 * @param array 类型化数组
	 */
    setArray(array) {
        if (Array.isArray(array)) {
            throw new TypeError('array必须是类型化数组');
        }
        this.count = array !== undefined ? array.length / this.itemSize : 0;
        this.array = array;
        return this;
    }
	/**
	 * 
	 * @param index 第几个点
	 */
    getX(index: number) {
        return this.array[index * this.itemSize];
    }

    setX(index: number, x: number) {
        this.array[index * this.itemSize] = x;
        return this;
    }

    getY(index: number) {
        return this.array[index * this.itemSize + 1];
    }

    setY(index: number, y: number) {
        this.array[index * this.itemSize + 1] = y;
        return this;
    }

    getZ(index: number) {
        return this.array[index * this.itemSize + 2];
    }

    setZ(index: number, z: number) {
        this.array[index * this.itemSize + 2] = z;
        return this;
    }

    getW(index: number) {
        return this.array[index * this.itemSize + 3];
    }

    setW(index: number, w: number) {
        this.array[index * this.itemSize + 3] = w;
        return this;
    }

    setXY(index: number, x: number, y: number) {
        index *= this.itemSize;
        this.array[index + 0] = x;
        this.array[index + 1] = y;
        return this;
    }

    setXYZ(index: number, x: number, y: number, z: number) {
        index *= this.itemSize;
        this.array[index + 0] = x;
        this.array[index + 1] = y;
        this.array[index + 2] = z;
        return this;
    }

    setXYZW(index: number, x: number, y: number, z: number, w: number) {
        index *= this.itemSize;
        this.array[index + 0] = x;
        this.array[index + 1] = y;
        this.array[index + 2] = z;
        this.array[index + 3] = w;
        return this;
    }
    copy(source: BufferAttribute) {

        this.name = source.name;
        this.array = new source.array.constructor(source.array);
        this.itemSize = source.itemSize;
        this.count = source.count;
        this.normalized = source.normalized;
        return this;
    }
    clone() {
        return new BufferAttribute(this.array, this.itemSize).copy(this);
    }
}