/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Entities
 */
import { Id64 } from "@itwin/core-bentley";
import { Point2d, Point3d } from "@itwin/core-geometry";
import { RelatedElement } from "./ElementProps";
/** The primitive types of an Entity property.
 * @beta
 */
export var PrimitiveTypeCode;
(function (PrimitiveTypeCode) {
    PrimitiveTypeCode[PrimitiveTypeCode["Uninitialized"] = 0] = "Uninitialized";
    PrimitiveTypeCode[PrimitiveTypeCode["Binary"] = 257] = "Binary";
    PrimitiveTypeCode[PrimitiveTypeCode["Boolean"] = 513] = "Boolean";
    PrimitiveTypeCode[PrimitiveTypeCode["DateTime"] = 769] = "DateTime";
    PrimitiveTypeCode[PrimitiveTypeCode["Double"] = 1025] = "Double";
    PrimitiveTypeCode[PrimitiveTypeCode["Integer"] = 1281] = "Integer";
    PrimitiveTypeCode[PrimitiveTypeCode["Long"] = 1537] = "Long";
    PrimitiveTypeCode[PrimitiveTypeCode["Point2d"] = 1793] = "Point2d";
    PrimitiveTypeCode[PrimitiveTypeCode["Point3d"] = 2049] = "Point3d";
    PrimitiveTypeCode[PrimitiveTypeCode["String"] = 2305] = "String";
    PrimitiveTypeCode[PrimitiveTypeCode["IGeometry"] = 2561] = "IGeometry";
})(PrimitiveTypeCode || (PrimitiveTypeCode = {}));
/** Metadata for a property.
 * @beta
 */
export class PropertyMetaData {
    constructor(jsonObj) {
        this.primitiveType = jsonObj.primitiveType;
        if (jsonObj.structName)
            this.structName = jsonObj.structName;
        this.extendedType = jsonObj.extendedType;
        this.description = jsonObj.description;
        this.displayLabel = jsonObj.displayLabel;
        if (undefined !== jsonObj.minimumValue)
            this.minimumValue = jsonObj.minimumValue;
        if (undefined !== jsonObj.maximumValue)
            this.maximumValue = jsonObj.maximumValue;
        if (undefined !== jsonObj.minimumLength)
            this.minimumLength = jsonObj.minimumLength;
        if (undefined !== jsonObj.maximumLength)
            this.maximumLength = jsonObj.maximumLength;
        this.readOnly = jsonObj.readOnly;
        this.kindOfQuantity = jsonObj.kindOfQuantity;
        this.isCustomHandled = jsonObj.isCustomHandled;
        if (undefined !== jsonObj.minOccurs)
            this.minOccurs = jsonObj.minOccurs;
        if (undefined !== jsonObj.maxOccurs)
            this.maxOccurs = jsonObj.maxOccurs;
        this.direction = jsonObj.direction;
        this.relationshipClass = jsonObj.relationshipClass;
        this.customAttributes = jsonObj.customAttributes;
    }
    /** Create a typed value, or array of values, from a factory and an input object */
    createValueOrArray(func, jsonObj) {
        if (undefined === this.minOccurs)
            return func(jsonObj); // not an array
        const val = [];
        jsonObj.forEach((element) => val.push(func(element)));
        return val;
    }
    /** construct a single property from an input object according to this metadata */
    createProperty(jsonObj) {
        if (jsonObj === undefined)
            return undefined;
        if (undefined !== this.primitiveType) {
            switch (this.primitiveType) {
                case PrimitiveTypeCode.Boolean:
                case PrimitiveTypeCode.Double:
                case PrimitiveTypeCode.Integer:
                case PrimitiveTypeCode.String:
                    return jsonObj; // this works even for arrays or strings that are JSON because the parsed JSON is already the right type
                case PrimitiveTypeCode.Point2d:
                    return this.createValueOrArray((obj) => Point2d.fromJSON(obj), jsonObj);
                case PrimitiveTypeCode.Point3d:
                    return this.createValueOrArray((obj) => Point3d.fromJSON(obj), jsonObj);
            }
        }
        if (this.isNavigation)
            return jsonObj.id !== undefined ? new RelatedElement(jsonObj) : Id64.fromJSON(jsonObj);
        return jsonObj;
    }
    /** Return `true` if this property is a NavigationProperty. */
    get isNavigation() {
        return (this.direction !== undefined); // the presence of `direction` means it is a navigation property
    }
}
/** Metadata for an Entity.
 * @beta
 */
export class EntityMetaData {
    constructor(jsonObj) {
        this.classId = jsonObj.classId;
        this.ecclass = jsonObj.ecclass;
        this.description = jsonObj.description;
        this.modifier = jsonObj.modifier;
        this.displayLabel = jsonObj.displayLabel;
        this.baseClasses = jsonObj.baseClasses;
        this.customAttributes = jsonObj.customAttributes;
        this.properties = {};
        for (const propName in jsonObj.properties) { // eslint-disable-line guard-for-in
            this.properties[propName] = new PropertyMetaData(jsonObj.properties[propName]);
        }
    }
}
//# sourceMappingURL=EntityProps.js.map