import '../../../assert/js/assert.js';
import '../../../globals.js';
import { alpenglow, isWindingIncluded, LinearEdge, RenderColor, RenderPath, RenderProgram } from '../imports.js';
export default class RenderPathBoolean extends RenderProgram {
    constructor(path, inside, outside) {
        super([inside, outside], inside.isFullyTransparent && outside.isFullyTransparent, inside.isFullyOpaque && outside.isFullyOpaque, false, false, true // We'll use the centroid as the point for determining whether we are on the interior of our path
        );
        this.path = path;
        this.inside = inside;
        this.outside = outside;
    }
    getName() {
        return 'RenderPathBoolean';
    }
    withChildren(children) {
        assert && assert(children.length === 2);
        return new RenderPathBoolean(this.path, children[0], children[1]);
    }
    transformed(transform) {
        return new RenderPathBoolean(this.path.transformed(transform), this.inside.transformed(transform), this.outside.transformed(transform));
    }
    equalsTyped(other) {
        return this.path === other.path;
    }
    isOneSided() {
        return this.outside.isFullyTransparent || this.inside.isFullyTransparent;
    }
    getOneSide() {
        assert && assert(this.isOneSided());
        return this.outside.isFullyTransparent ? this.inside : this.outside;
    }
    withOneSide(program) {
        assert && assert(this.isOneSided());
        return this.outside.isFullyTransparent ?
            new RenderPathBoolean(this.path, program, this.outside) :
            new RenderPathBoolean(this.path, this.inside, program);
    }
    getSimplified(children) {
        const inside = children[0];
        const outside = children[1];
        if (inside.isFullyTransparent && outside.isFullyTransparent) {
            return RenderColor.TRANSPARENT;
        }
        else if (inside.equals(outside)) {
            return inside;
        }
        else if (this.path.isTriviallyEmpty()) {
            // NOTE: We're not checking to see if there is zero area, because of the performance impact. This is unlikely to
            // significantly help performance if we check area, so it's not worth it.
            return outside;
        }
        else {
            return null;
        }
    }
    evaluate(context) {
        assert && assert(context.hasCentroid());
        // TODO: ACTUALLY, we should clip the face with our path....
        const windingNumber = LinearEdge.getWindingNumberPolygons(this.path.subpaths, context.centroid);
        const included = isWindingIncluded(windingNumber, this.path.fillRule);
        return (included ? this.inside : this.outside).evaluate(context);
    }
    getExtraDebugString() {
        return `${this.path.id}`;
    }
    serialize() {
        return {
            type: 'RenderPathBoolean',
            path: this.path.serialize(),
            inside: this.inside.serialize(),
            outside: this.outside.serialize()
        };
    }
    static deserialize(obj) {
        return new RenderPathBoolean(RenderPath.deserialize(obj.path), RenderProgram.deserialize(obj.inside), RenderProgram.deserialize(obj.outside));
    }
    static fromInside(path, inside) {
        return new RenderPathBoolean(path, inside, RenderColor.TRANSPARENT);
    }
}
alpenglow.register('RenderPathBoolean', RenderPathBoolean);
//# sourceMappingURL=RenderPathBoolean.js.map