import _ from 'lodash';
import '../../../../assert/js/assert.js';
import '../../../../globals.js';
// Copyright 2023-2024, University of Colorado Boulder
/**
 * A clipped part of a RasterChunk, which will get filled with data during reduction.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
import { alpenglow, RasterSplitReduceData } from '../../imports.js';
class RasterClippedChunk {
    constructor(renderProgramIndex, needsFace, isConstant, 
    // Filled in by early steps
    isReducible, isComplete, isFullArea, area, 
    // Floating point (typically integral or offset by 0.5) bounds.
    minX, minY, maxX, maxY, 
    // EdgedClipped counts. See EdgedClippedFace for details.
    minXCount, minYCount, maxXCount, maxYCount) {
        this.renderProgramIndex = renderProgramIndex;
        this.needsFace = needsFace;
        this.isConstant = isConstant;
        this.isReducible = isReducible;
        this.isComplete = isComplete;
        this.isFullArea = isFullArea;
        this.area = area;
        this.minX = minX;
        this.minY = minY;
        this.maxX = maxX;
        this.maxY = maxY;
        this.minXCount = minXCount;
        this.minYCount = minYCount;
        this.maxXCount = maxXCount;
        this.maxYCount = maxYCount;
    }
    needsCompleteOutputSplit() {
        return this.isComplete && this.isFullArea && !this.isConstant;
    }
    outputSplitCount() {
        assert && assert(this.needsCompleteOutputSplit());
        return (this.maxX - this.minX) * (this.maxY - this.minY);
    }
    getSplitReduceData() {
        return new RasterSplitReduceData(this.isReducible ? 1 : 0, this.isComplete ? (this.needsCompleteOutputSplit() ? this.outputSplitCount() : 1) : 0);
    }
    isExportingCompleteEdges() {
        return this.isComplete && !this.isFullArea && this.needsFace;
    }
    toString() {
        if (isNaN(this.renderProgramIndex)) {
            return 'RasterClippedChunk[INDETERMINATE]';
        }
        const counts = `counts:${this.minXCount},${this.minYCount},${this.maxXCount},${this.maxYCount}`;
        const bounds = `bounds:x[${this.minX},${this.maxX}],y[${this.minY},${this.maxY}]`;
        const needs = this.needsFace ? ' needsFace' : '';
        const area = `area:${this.area}`;
        const reducible = this.isReducible ? ' reducible' : '';
        const contributing = this.isComplete ? ' complete' : '';
        const fullArea = this.isFullArea ? ' fullArea' : '';
        return `RasterClippedChunk[prog:${this.renderProgramIndex} ${counts} ${bounds} ${area}${reducible}${contributing}${fullArea}${needs}]`;
    }
    writeEncoding(encoder) {
        assert && assert(this.renderProgramIndex >= 0 && this.renderProgramIndex <= 0x00ffffff);
        encoder.pushU32((this.renderProgramIndex & 0x00ffffff) |
            (this.isReducible ? 0x08000000 : 0) |
            (this.isComplete ? 0x10000000 : 0) |
            (this.isFullArea ? 0x20000000 : 0) |
            (this.needsFace ? 0x40000000 : 0) |
            (this.isConstant ? 0x80000000 : 0));
        encoder.pushF32(this.area);
        encoder.pushF32(this.minX);
        encoder.pushF32(this.minY);
        encoder.pushF32(this.maxX);
        encoder.pushF32(this.maxY);
        encoder.pushI32(this.minXCount);
        encoder.pushI32(this.minYCount);
        encoder.pushI32(this.maxXCount);
        encoder.pushI32(this.maxYCount);
    }
    static readEncoding(arrayBuffer, byteOffset) {
        const uintBuffer = new Uint32Array(arrayBuffer, byteOffset, RasterClippedChunk.ENCODING_BYTE_LENGTH / 4);
        const intBuffer = new Int32Array(arrayBuffer, byteOffset, RasterClippedChunk.ENCODING_BYTE_LENGTH / 4);
        const floatBuffer = new Float32Array(arrayBuffer, byteOffset, RasterClippedChunk.ENCODING_BYTE_LENGTH / 4);
        const renderProgramIndex = uintBuffer[0] & 0x00ffffff;
        const isReducible = (uintBuffer[0] & 0x08000000) !== 0;
        const isComplete = (uintBuffer[0] & 0x10000000) !== 0;
        const isFullArea = (uintBuffer[0] & 0x20000000) !== 0;
        const needsFace = (uintBuffer[0] & 0x40000000) !== 0;
        const isConstant = (uintBuffer[0] & 0x80000000) !== 0;
        return new RasterClippedChunk(renderProgramIndex, needsFace, isConstant, isReducible, isComplete, isFullArea, floatBuffer[1], floatBuffer[2], floatBuffer[3], floatBuffer[4], floatBuffer[5], intBuffer[6], intBuffer[7], intBuffer[8], intBuffer[9]);
    }
    static fromArrayBuffer(arrayBuffer) {
        assert && assert(arrayBuffer.byteLength % RasterClippedChunk.ENCODING_BYTE_LENGTH === 0);
        return _.range(0, arrayBuffer.byteLength / RasterClippedChunk.ENCODING_BYTE_LENGTH).map(i => {
            return RasterClippedChunk.readEncoding(arrayBuffer, i * RasterClippedChunk.ENCODING_BYTE_LENGTH);
        });
    }
}
RasterClippedChunk.ENCODING_BYTE_LENGTH = 4 * 10;
RasterClippedChunk.INDETERMINATE = new RasterClippedChunk(NaN, false, false, false, false, false, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN);
RasterClippedChunk.DISCARDABLE = new RasterClippedChunk(0, false, false, false, false, false, 0, 0, 0, 0, 0, 0, 0, 0, 0);
export default RasterClippedChunk;
alpenglow.register('RasterClippedChunk', RasterClippedChunk);
//# sourceMappingURL=RasterClippedChunk.js.map