"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
 * @module Elements
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.SheetReference = exports.SheetIndexReference = exports.SheetIndexFolder = exports.SheetIndexEntry = exports.SheetIndex = void 0;
const core_common_1 = require("@itwin/core-common");
const Element_1 = require("./Element");
const core_bentley_1 = require("@itwin/core-bentley");
const NavigationRelationship_1 = require("./NavigationRelationship");
/** A [structured collection]($docs/bis/domains/drawings-sheets#sheet-index) of [[SheetIndexEntry]]s.
 * The sheet index is a tree whose leaf nodes refer to [[Sheet]]s, optionally grouped by [[SheetIndexFolder]]s and/or incorporating
 * sub-trees via [[SheetIndexReference]]s.
 * @beta
 */
class SheetIndex extends Element_1.InformationReferenceElement {
    static get className() { return "SheetIndex"; }
    /** Create a Code for a SheetIndex given a name that is meant to be unique within the scope of the specified SheetIndexModel.
     * @param iModel  The IModelDb
     * @param scopeSheetIndexModelId The Id of the Model that contains the LinkElement and provides the scope for its name.
     * @param codeValue The SheetIndex name
     */
    static createCode(iModel, scopeSheetIndexModelId, codeValue) {
        const codeSpec = iModel.codeSpecs.getByName(core_common_1.BisCodeSpec.sheetIndex);
        return new core_common_1.Code({ spec: codeSpec.id, scope: scopeSheetIndexModelId, value: codeValue });
    }
    /** Create a SheetIndex
     * @param iModelDb The IModelDb
     * @param modelId The Id of the Model that contains the SheetIndex and provides the scope for its name.
     * @param name The name (codeValue) of the SheetIndex
     * @returns The newly constructed SheetIndex
     * @throws [[IModelError]] if there is a problem creating the SheetIndex
     */
    static create(iModelDb, modelId, name) {
        const props = {
            classFullName: this.classFullName,
            code: this.createCode(iModelDb, modelId, name).toJSON(),
            model: modelId,
        };
        return new this(props, iModelDb);
    }
    /** Insert a SheetIndex
     * @param iModelDb The IModelDb
     * @param modelId The Id of the Model that contains the SheetIndex and provides the scope for its name.
     * @param name The name (codeValue) of the SheetIndex
     * @returns The Id of the newly inserted SheetIndex
     * @throws [[IModelError]] if there is a problem inserting the SheetIndex
     */
    static insert(iModelDb, modelId, name) {
        const instance = this.create(iModelDb, modelId, name);
        const elements = iModelDb.elements;
        instance.id = elements.insertElement(instance.toJSON());
        return instance.id;
    }
}
exports.SheetIndex = SheetIndex;
/** The base class for all elements that can participate in a [[SheetIndex]] hierarchy.
 * @beta
*/
class SheetIndexEntry extends Element_1.InformationReferenceElement {
    static get className() { return "SheetIndexEntry"; }
    /** Can be used to prioritize or order members within a SheetIndex or SheetIndexFolder. */
    entryPriority;
    constructor(props, iModel) {
        super(props, iModel);
        this.entryPriority = props.entryPriority;
    }
    toJSON() {
        return { ...super.toJSON(), entryPriority: this.entryPriority };
    }
    /** Create a Code for a Sheet Index Entry given a name that is meant to be unique within the scope of the specified SheetIndexModel.
     * @param iModel  The IModel
     * @param scopeModelId The Id of the [[SheetIndexModel]] that contains the [[SheetIndexEntry]] and provides the scope for its name.
     * @param codeValue The name of the entry
     */
    static createCode(iModelDb, scopeModelId, codeValue) {
        const codeSpec = iModelDb.codeSpecs.getByName(core_common_1.BisCodeSpec.sheetIndexEntry);
        return new core_common_1.Code({ spec: codeSpec.id, scope: scopeModelId, value: codeValue });
    }
    static createParentRelationshipProps(iModelDb, id) {
        const parentElementProps = iModelDb.elements.getElementProps(id);
        const isFolder = parentElementProps.classFullName === SheetIndexFolder.classFullName;
        const relClass = isFolder ? NavigationRelationship_1.SheetIndexFolderOwnsEntries : NavigationRelationship_1.SheetIndexOwnsEntries;
        return { id, relClassName: relClass.classFullName };
    }
    static createProps(arg) {
        const parent = this.createParentRelationshipProps(arg.iModelDb, arg.parentId);
        const props = {
            classFullName: this.classFullName,
            model: arg.sheetIndexModelId,
            code: this.createCode(arg.iModelDb, arg.sheetIndexModelId, arg.name),
            entryPriority: arg.priority,
            parent,
        };
        return props;
    }
}
exports.SheetIndexEntry = SheetIndexEntry;
/** A container used to group [[SheetIndexEntry]]s within a [[SheetIndex]].
 * @beta
 */
class SheetIndexFolder extends SheetIndexEntry {
    static get className() { return "SheetIndexFolder"; }
    /** Create a new SheetIndexFolder
     * @returns The newly constructed SheetIndexFolder element.
     * @throws [[IModelError]] if unable to create the element.
     */
    static create(arg) {
        const props = this.createProps(arg);
        return new this(props, arg.iModelDb);
    }
    /** Create a new SheetIndexFolder
     * @returns The Id of the newly inserted SheetIndexFolder element.
     * @throws [[IModelError]] if unable to create the element.
     */
    static insert(arg) {
        const instance = this.create(arg);
        const elements = arg.iModelDb.elements;
        instance.id = elements.insertElement(instance.toJSON());
        return instance.id;
    }
}
exports.SheetIndexFolder = SheetIndexFolder;
/** A node within one [[SheetIndex]] that incorporates another [[SheetIndex]] as a sub-tree.
 * @beta
*/
class SheetIndexReference extends SheetIndexEntry {
    static get className() { return "SheetIndexReference"; }
    /** The bis:SheetIndex that this bis:SheetIndexReference is pointing to. */
    sheetIndex;
    constructor(props, iModel) {
        super(props, iModel);
        if (props.sheetIndex) {
            const sheetIndex = iModel.elements.tryGetElement(props.sheetIndex.id);
            if (!sheetIndex)
                throw new core_common_1.IModelError(core_bentley_1.IModelStatus.NotFound, "SheetIndex not found");
            this.sheetIndex = new NavigationRelationship_1.SheetIndexReferenceRefersToSheetIndex(props.sheetIndex.id);
        }
    }
    static createReferenceRelationshipProps(id) {
        return { id, relClassName: NavigationRelationship_1.SheetIndexReferenceRefersToSheetIndex.classFullName };
    }
    toJSON() {
        return {
            ...super.toJSON(),
            sheetIndex: this.sheetIndex ? this.sheetIndex.toJSON() : undefined,
        };
    }
    /** Create a new SheetIndexReference
     * @returns The newly constructed SheetIndexReference element.
     * @throws [[IModelError]] if unable to create the element.
     */
    static create(arg) {
        const props = {
            ...this.createProps(arg),
            sheetIndex: arg.sheetIndexId ? this.createReferenceRelationshipProps(arg.sheetIndexId) : undefined,
        };
        return new this(props, arg.iModelDb);
    }
    /** Create a new SheetIndexReference
     * @returns The Id of the newly inserted SheetIndexReference element.
     * @throws [[IModelError]] if unable to create the element.
     */
    static insert(arg) {
        const instance = this.create(arg);
        const elements = arg.iModelDb.elements;
        instance.id = elements.insertElement(instance.toJSON());
        return instance.id;
    }
    /** @alpha */
    collectReferenceIds(referenceIds) {
        super.collectReferenceIds(referenceIds);
        if (this.sheetIndex)
            referenceIds.addElement(this.sheetIndex.id);
    }
}
exports.SheetIndexReference = SheetIndexReference;
/** A leaf node in a [[SheetIndex]] that refers to a specific [[Sheet]].
 * @beta
*/
class SheetReference extends SheetIndexEntry {
    static get className() { return "SheetReference"; }
    /** The bis:Sheet that this bis:SheetReference is pointing to. */
    sheet;
    constructor(props, iModel) {
        super(props, iModel);
        if (props.sheet) {
            const sheet = iModel.elements.tryGetElement(props.sheet.id);
            if (!sheet)
                throw new core_common_1.IModelError(core_bentley_1.IModelStatus.NotFound, "Sheet not found");
            this.sheet = new NavigationRelationship_1.SheetReferenceRefersToSheet(sheet.id);
        }
    }
    static createReferenceRelationshipProps(id) {
        return { id, relClassName: NavigationRelationship_1.SheetIndexReferenceRefersToSheetIndex.classFullName };
    }
    toJSON() {
        return {
            ...super.toJSON(),
            sheet: this.sheet ? this.sheet.toJSON() : undefined,
        };
    }
    /** Create a new SheetReference
     * @returns The newly constructed SheetReference element.
     * @throws [[IModelError]] if unable to create the element.
     */
    static create(arg) {
        const props = {
            ...this.createProps(arg),
            sheet: arg.sheetId ? this.createReferenceRelationshipProps(arg.sheetId) : undefined,
        };
        return new this(props, arg.iModelDb);
    }
    /** Insert a new SheetReference
     * @returns The Id of the newly inserted SheetReference element.
     * @throws [[IModelError]] if unable to create the element.
     */
    static insert(arg) {
        const instance = this.create(arg);
        const elements = arg.iModelDb.elements;
        instance.id = elements.insertElement(instance.toJSON());
        return instance.id;
    }
    /** @alpha */
    collectReferenceIds(referenceIds) {
        super.collectReferenceIds(referenceIds);
        if (this.sheet)
            referenceIds.addModel(this.sheet.id);
    }
}
exports.SheetReference = SheetReference;
//# sourceMappingURL=SheetIndex.js.map