/**
 * DataView wrapper for serializing MMD data
 */
export class MmdDataSerializer {
    _dataView;
    _encoder;
    _offset;
    /**
     * Creates MMD data serializer
     * @param arrayBuffer ArrayBuffer to serialize
     */
    constructor(arrayBuffer) {
        this._dataView = new DataView(arrayBuffer);
        this._encoder = new TextEncoder();
        this._offset = 0;
    }
    /**
     * Current offset in the buffer
     */
    get offset() {
        return this._offset;
    }
    set offset(value) {
        this._offset = value;
    }
    /**
     * Writes a uint8 value
     * @param value Uint8 value to write
     */
    setUint8(value) {
        this._dataView.setUint8(this._offset, value);
        this._offset += 1;
    }
    /**
     * Writes a uint8 array
     * @param values Uint8 array to write
     */
    setUint8Array(values) {
        const dataView = this._dataView;
        for (let i = 0; i < values.length; ++i) {
            dataView.setUint8(this._offset, values[i]);
            this._offset += 1;
        }
    }
    /**
     * Writes a int8 value
     * @param value Int8 value to write
     */
    setInt8(value) {
        this._dataView.setInt8(this._offset, value);
        this._offset += 1;
    }
    /**
     * Writes a int8 array
     * @param values Int8 array to write
     */
    setInt8Array(values) {
        const dataView = this._dataView;
        for (let i = 0; i < values.length; ++i) {
            dataView.setInt8(this._offset, values[i]);
            this._offset += 1;
        }
    }
    /**
     * Writes a uint16 value
     * @param value Uint16 value to write
     */
    setUint16(value) {
        this._dataView.setUint16(this._offset, value, true);
        this._offset += 2;
    }
    /**
     * Writes a uint16 array
     * @param values Uint16 array to write
     */
    setUint16Array(values) {
        const dataView = this._dataView;
        for (let i = 0; i < values.length; ++i) {
            dataView.setUint16(this._offset, values[i], true);
            this._offset += 2;
        }
    }
    /**
     * Writes a uint32 value
     * @param value Uint32 value to write
     */
    setUint32(value) {
        this._dataView.setUint32(this._offset, value, true);
        this._offset += 4;
    }
    /**
     * Writes a uint32 array
     * @param values Uint32 array to write
     */
    setUint32Array(values) {
        const dataView = this._dataView;
        for (let i = 0; i < values.length; ++i) {
            dataView.setUint32(this._offset, values[i], true);
            this._offset += 4;
        }
    }
    /**
     * Writes a int32 value
     * @param value Int32 value to write
     */
    setInt32(value) {
        this._dataView.setInt32(this._offset, value, true);
        this._offset += 4;
    }
    /**
     * Writes a int32 array
     * @param values Int32 array to write
     */
    setInt32Array(values) {
        const dataView = this._dataView;
        for (let i = 0; i < values.length; ++i) {
            dataView.setInt32(this._offset, values[i], true);
            this._offset += 4;
        }
    }
    /**
     * Writes a float32 value
     * @param value Float32 value to write
     */
    setFloat32(value) {
        this._dataView.setFloat32(this._offset, value, true);
        this._offset += 4;
    }
    /**
     * Writes a float32 array
     * @param values Float32 array to write
     */
    setFloat32Array(values) {
        const dataView = this._dataView;
        for (let i = 0; i < values.length; ++i) {
            dataView.setFloat32(this._offset, values[i], true);
            this._offset += 4;
        }
    }
    /**
     * Writes a string as UTF-8
     * @param value String to write
     */
    setString(value) {
        const dataView = this._dataView;
        const bytes = this._encoder.encode(value);
        dataView.setUint32(this._offset, bytes.length, true);
        this._offset += 4;
        for (let i = 0; i < bytes.length; ++i) {
            dataView.setUint8(this._offset, bytes[i]);
            this._offset += 1;
        }
    }
    /**
     * The number of bytes available
     */
    get bytesAvailable() {
        return this._dataView.byteLength - this._offset;
    }
    /**
     * Compute byte alignment padding
     * @param offset Offset
     * @param elementSize Element size
     * @returns Padding
     */
    static Padding(offset, elementSize) {
        return offset % elementSize === 0 ? 0 : elementSize - offset % elementSize;
    }
}
