/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Rendering
 */
import { Id64 } from "@itwin/core-bentley";
import { BatchType, Feature } from "@itwin/core-common";
import { HitPriority } from "../HitDetail";
/** Describes aspects of a pixel as read from a [[Viewport]].
 * @see [[Viewport.readPixels]].
 * @public
 * @extensions
 */
export var Pixel;
(function (Pixel) {
    /** Describes a single pixel within a [[Pixel.Buffer]]. */
    class Data {
        /** @internal */
        get isClassifier() {
            return undefined !== this.batchType && BatchType.Primary !== this.batchType;
        }
        /** @internal */
        constructor(args) {
            if (args?.feature)
                this.feature = new Feature(args.feature.elementId, args.feature.subCategoryId, args.feature.geometryClass);
            this.modelId = args?.feature?.modelId;
            this.distanceFraction = args?.distanceFraction ?? -1;
            this.type = args?.type ?? GeometryType.Unknown;
            this.planarity = args?.planarity ?? Planarity.Unknown;
            this.iModel = args?.iModel;
            this.tileId = args?.tileId;
            this.viewAttachmentId = args?.viewAttachmentId;
        }
        /** The Id of the element that produced the pixel. */
        get elementId() {
            return this.feature?.elementId;
        }
        /** The Id of the [SubCategory]($backend) that produced the pixel. */
        get subCategoryId() {
            return this.feature?.subCategoryId;
        }
        /** The class of geometry that produced the pixel. */
        get geometryClass() {
            return this.feature?.geometryClass;
        }
        /** Computes the [[HitPriority]] of this pixel based on its [[type]] and [[planarity]]. */
        computeHitPriority() {
            switch (this.type) {
                case Pixel.GeometryType.Surface:
                    return Pixel.Planarity.Planar === this.planarity ? HitPriority.PlanarSurface : HitPriority.NonPlanarSurface;
                case Pixel.GeometryType.Linear:
                    return HitPriority.WireEdge;
                case Pixel.GeometryType.Edge:
                    return Pixel.Planarity.Planar === this.planarity ? HitPriority.PlanarEdge : HitPriority.NonPlanarEdge;
                case Pixel.GeometryType.Silhouette:
                    return HitPriority.SilhouetteEdge;
                default:
                    return HitPriority.Unknown;
            }
        }
        /** Convert this pixel to a [[Pixel.HitProps]] suitable for constructing a [[HitDetail]].
         * @param viewport The viewport in which the hit originated.
         */
        toHitProps(viewport) {
            let viewAttachment;
            if (this.viewAttachmentId) {
                const attachmentViewport = viewport.view.getAttachmentViewport(this.viewAttachmentId);
                if (attachmentViewport)
                    viewAttachment = { viewport: attachmentViewport, id: this.viewAttachmentId };
            }
            return {
                sourceId: this.elementId ?? Id64.invalid,
                priority: this.computeHitPriority(),
                distFraction: this.distanceFraction,
                subCategoryId: this.subCategoryId,
                geometryClass: this.geometryClass,
                modelId: this.modelId,
                tileId: this.tileId,
                isClassifier: this.isClassifier,
                sourceIModel: this.iModel,
                viewAttachment,
            };
        }
    }
    Pixel.Data = Data;
    /** Describes the type of geometry that produced the [[Pixel.Data]]. */
    let GeometryType;
    (function (GeometryType) {
        /** [[Pixel.Selector.GeometryAndDistance]] was not specified, or the type could not be determined. */
        GeometryType[GeometryType["Unknown"] = 0] = "Unknown";
        /** No geometry was rendered to this pixel. */
        GeometryType[GeometryType["None"] = 1] = "None";
        /** A surface produced this pixel. */
        GeometryType[GeometryType["Surface"] = 2] = "Surface";
        /** A point primitive or polyline produced this pixel. */
        GeometryType[GeometryType["Linear"] = 3] = "Linear";
        /** This pixel was produced by an edge of a surface. */
        GeometryType[GeometryType["Edge"] = 4] = "Edge";
        /** This pixel was produced by a silhouette edge of a curved surface. */
        GeometryType[GeometryType["Silhouette"] = 5] = "Silhouette";
    })(GeometryType = Pixel.GeometryType || (Pixel.GeometryType = {}));
    /** Describes the planarity of the foremost geometry which produced the pixel. */
    let Planarity;
    (function (Planarity) {
        /** [[Pixel.Selector.GeometryAndDistance]] was not specified, or the planarity could not be determined. */
        Planarity[Planarity["Unknown"] = 0] = "Unknown";
        /** No geometry was rendered to this pixel. */
        Planarity[Planarity["None"] = 1] = "None";
        /** Planar geometry produced this pixel. */
        Planarity[Planarity["Planar"] = 2] = "Planar";
        /** Non-planar geometry produced this pixel. */
        Planarity[Planarity["NonPlanar"] = 3] = "NonPlanar";
    })(Planarity = Pixel.Planarity || (Pixel.Planarity = {}));
    /**
     * Bit-mask by which callers of [[Viewport.readPixels]] specify which aspects are of interest.
     * Aspects not specified will be omitted from the returned data.
     */
    let Selector;
    (function (Selector) {
        Selector[Selector["None"] = 0] = "None";
        /** Select the [[Feature]] which produced each pixel. */
        Selector[Selector["Feature"] = 1] = "Feature";
        /** Select the type and planarity of geometry which produced each pixel as well as the fraction of its distance between the near and far planes. */
        Selector[Selector["GeometryAndDistance"] = 4] = "GeometryAndDistance";
        /** Select all aspects of each pixel. */
        Selector[Selector["All"] = 5] = "All";
    })(Selector = Pixel.Selector || (Pixel.Selector = {}));
})(Pixel || (Pixel = {}));
//# sourceMappingURL=Pixel.js.map