import _ from 'lodash';
import '../../../../assert/js/assert.js';
import '../../../../globals.js';
// Copyright 2023-2024, University of Colorado Boulder
/**
 * Represents the clipped state of a RasterEdge. For the binary version, there will be two of these edge clips per
 * input edge.
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
import Vector2 from '../../../../dot/js/Vector2.js';
import { alpenglow } from '../../imports.js';
class RasterEdgeClip {
    constructor(clippedChunkIndex, point0, point1, point2, point3, isFirstEdge, isLastEdge) {
        this.clippedChunkIndex = clippedChunkIndex;
        this.point0 = point0;
        this.point1 = point1;
        this.point2 = point2;
        this.point3 = point3;
        this.isFirstEdge = isFirstEdge;
        this.isLastEdge = isLastEdge;
    }
    getCount() {
        return (this.point0.equals(this.point1) ? 0 : 1) +
            (this.point1.equals(this.point2) ? 0 : 1) +
            (this.point2.equals(this.point3) ? 0 : 1);
    }
    getArea() {
        return 0.5 * ((this.point1.x + this.point0.x) * (this.point1.y - this.point0.y) +
            (this.point2.x + this.point1.x) * (this.point2.y - this.point1.y) +
            (this.point3.x + this.point2.x) * (this.point3.y - this.point2.y));
    }
    toString() {
        if (isNaN(this.clippedChunkIndex)) {
            return 'RasterEdgeClip[INDETERMINATE]';
        }
        const firstLast = this.isFirstEdge ? (this.isLastEdge ? ' BOTH' : ' FIRST') : (this.isLastEdge ? ' LAST' : '');
        const coords = `${this.point0.x},${this.point0.y} => ${this.point1.x},${this.point1.y} => ${this.point2.x},${this.point2.y} => ${this.point3.x},${this.point3.y}`;
        return `RasterEdgeClip[clippedChunk:${this.clippedChunkIndex} ${coords}${firstLast}]`;
    }
    writeEncoding(encoder) {
        assert && assert(this.clippedChunkIndex >= 0 && this.clippedChunkIndex <= 0x2fffffff);
        encoder.pushU32((this.clippedChunkIndex & 0x2fffffff) |
            (this.isFirstEdge ? 0x40000000 : 0) |
            (this.isLastEdge ? 0x80000000 : 0));
        encoder.pushF32(this.point0.x);
        encoder.pushF32(this.point0.y);
        encoder.pushF32(this.point1.x);
        encoder.pushF32(this.point1.y);
        encoder.pushF32(this.point2.x);
        encoder.pushF32(this.point2.y);
        encoder.pushF32(this.point3.x);
        encoder.pushF32(this.point3.y);
    }
    static readEncoding(arrayBuffer, byteOffset) {
        const uintBuffer = new Uint32Array(arrayBuffer, byteOffset, RasterEdgeClip.ENCODING_BYTE_LENGTH / 4);
        const floatBuffer = new Float32Array(arrayBuffer, byteOffset, RasterEdgeClip.ENCODING_BYTE_LENGTH / 4);
        const clippedChunkIndex = uintBuffer[0] & 0x2fffffff;
        const isFirstEdge = (uintBuffer[0] & 0x40000000) !== 0;
        const isLastEdge = (uintBuffer[0] & 0x80000000) !== 0;
        return new RasterEdgeClip(clippedChunkIndex, new Vector2(floatBuffer[1], floatBuffer[2]), new Vector2(floatBuffer[3], floatBuffer[4]), new Vector2(floatBuffer[5], floatBuffer[6]), new Vector2(floatBuffer[7], floatBuffer[8]), isFirstEdge, isLastEdge);
    }
    static fromArrayBuffer(arrayBuffer) {
        assert && assert(arrayBuffer.byteLength % RasterEdgeClip.ENCODING_BYTE_LENGTH === 0);
        return _.range(0, arrayBuffer.byteLength / RasterEdgeClip.ENCODING_BYTE_LENGTH).map(i => {
            return RasterEdgeClip.readEncoding(arrayBuffer, i * RasterEdgeClip.ENCODING_BYTE_LENGTH);
        });
    }
}
RasterEdgeClip.ENCODING_BYTE_LENGTH = 4 * 9;
RasterEdgeClip.INDETERMINATE = new RasterEdgeClip(NaN, new Vector2(NaN, NaN), new Vector2(NaN, NaN), new Vector2(NaN, NaN), new Vector2(NaN, NaN), false, false);
export default RasterEdgeClip;
alpenglow.register('RasterEdgeClip', RasterEdgeClip);
//# sourceMappingURL=RasterEdgeClip.js.map