import type { FormaElement, Transform, Urn } from "forma-elements";
import type { IframeMessenger } from "./iframe-messenger.js";
import { RepresentationsApi } from "./representations.js";
/**
 * Response format when fetching elements.
 *
 * The Urn and FormaElement types can be inspected in the TypeScript type definitions
 * in your local IDE.
 */
export type ElementResponse = Record<Urn, FormaElement>;
/**
 * The Elements API allows you to read all elements and create in a selection of Forma elements systems.
 *
 * @remarks
 * Available via {@link auto.Forma | Forma}.{@link index.EmbeddedViewSdk.elements | elements}.
 */
export declare class ElementsApi {
    #private;
    floorStack: FloorStackApi;
    representations: RepresentationsApi;
    blobs: BlobsApi;
    /** @hidden */
    constructor(iframeMessenger: IframeMessenger);
    /**
     * Get an element by urn.
     *
     * The method can return multiple elements. This can happen
     * if the element has children that are bundled with it.
     *
     * This method can also be used to include all the transitive children of the element
     * by setting the recursive parameter to true.
     *
     * @example
     * // Get the root element of the current proposal
     * const urn = await Forma.proposal.getRootUrn()
     * const { element, elements } = await Forma.elements.get({ urn })
     *
     * @returns
     * A map from identifiers to elements.
     * A single element for the requested element
     */
    get(request: {
        urn: Urn;
        recursive?: boolean;
    }): Promise<{
        element: FormaElement;
        elements: ElementResponse;
    }>;
    /**
     * Get an element hierarchy located at the path relative to the current
     * root. You default to current proposal by omitting the urn parameter.
     *
     * @example
     * // Get all the building elements of the current proposal
     * Forma.selection.subscribe(({ paths }) => {
     *   const { element, elements } = await Forma.elements.getByPath({ path: paths[0] })
     * });
     *
     * @returns
     * A map from identifiers to elements.
     */
    getByPath(request: {
        rootUrn?: Urn;
        path: string;
        recursive?: boolean;
    }): Promise<{
        element: FormaElement;
        elements: ElementResponse;
    }>;
    /**
     * Get the world transform of an element relative to the root element.
     *
     * The world transform is the affine transformation matrix that transforms
     * the element from its local coordinate system to the root coordinate system.
     *
     * @example
     * const { transform } = await Forma.elements.getWorldTransform({ path })
     * const { element } = await Forma.elements.getByPath({ path })
     *
     * if (element.representations?.footprint) {
     *   const footprint = await Forma.elements.representations.footprint(element)
     *
     *   const { data: geojson } = footprint
     *
     *   void Forma.render.geojson.add({ geojson, transform })
     * }
     *
     * @param request the path to element from root
     * @returns The affine transformation matrix of the element
     */
    getWorldTransform(request: {
        path: string;
    }): Promise<{
        transform: Transform;
    }>;
    /**
     * Allows adding, editing and removing custom properties attached directly to elements.
     * All properties must live under a namespace which follows `\w{1,20}:\w{1,50}` pattern (e.g.`my:namespace`).
     * The properties are managed by [JSON Merge Patch](https://datatracker.ietf.org/doc/html/rfc7386) specification.
     *
     * Requires edit access to the project. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info.
     *
     * @example
     * // Add two properties within a namespace to an element and replace its previous urn with the updated urn in a proposal
     * const addTwoProperties = {
     *  "my:namespace": {
     *    "myFirstProperty": "myFirstValue"
     *    "mySecondProperty": "mySecondValue"
     *   }
     * }
     * const result = await Forma.elements.editProperties({urn, propertiesJsonMergePatch: myProperties});
     * await Forma.proposal.replaceElement({path, urn: result.urn})
     *
     * @example
     * // Change value of the first property and remove the second property at the same time
     * const changeFirstRemoveSecondProperty = {
     *   "my:namespace": {
     *     "myFirstProperty": "veryDifferentValue"
     *     "mySecondProperty": null
     *   }
     * }
     * const result = await Forma.elements.editProperties({urn, propertiesJsonMergePatch: changeFirstRemoveSecondProperty});
     * await Forma.proposal.replaceElement({path, urn: result.urn})
     *
     * @example
     * // Remove the whole namespace from the element
     * const removeWholeNamespace = {
     *   "my:namespace": null
     * }
     * const result = await Forma.elements.editProperties({urn, propertiesJsonMergePatch: removeWholeNamespace});
     * await Forma.proposal.replaceElement({path, urn: result.urn})
     *
     */
    editProperties(request: {
        urn: Urn;
        propertiesJsonMergePatch: Record<string, Record<string, any> | null>;
    }): Promise<{
        urn: Urn;
    }>;
}
/** A floor represented as an extruded polygon*/
export type Floor = {
    /**
     * The footprint of the floor. Must be a counterclockwise polygon.
     */
    polygon: [number, number][];
    /**
     * The height of the floor. Must be a positive number.
     */
    height: number;
};
/**
 * API for creating Floor Stack buildings.
 *
 * You can use this API together with the Forma.proposal.addElement
 * API to create a building and add it to a the current proposal.
 *
 * @example
 * // Create a building with 3 floors with a 2 meter setback
 * // Place it where the user clicks in the scene
 * const { urn } = await Forma.elements.floorStack.createFromFloors({
 *  floors: [
 *   {
 *    polygon: [ [0, 0], [10, 0], [10, 10], [0, 10], [0, 0] ],
 *    height: 3,
 *   },
 *   {
 *    polygon: [ [0, 0], [10, 0], [10, 10], [0, 10], [0, 0] ],
 *    height: 2.6,
 *   },
 *   {
 *    polygon: [ [0, 0], [10, 0], [10, 8], [0, 8], [0, 0] ],
 *    height: 2.6,
 *   },
 *  ],
 * })
 * const point = await Forma.designTool.getPoint()
 * if (!point) return
 * const transform = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, point.x, point.y, point.z, 1]
 * await Forma.proposal.addElement({ urn, transform });
 *
 * @remarks
 * Available via {@link auto.Forma | Forma}.{@link index.EmbeddedViewSdk.elements | elements}.{@link elements.ElementsApi.floorStack | floorStack}.
 */
export declare class FloorStackApi {
    #private;
    /** @hidden */
    constructor(iframeMessenger: IframeMessenger);
    /**
     * Create a 2.5D building from a stack of floors.
     *
     * By 2.5D, we mean that the building only has vertical walls and flat roofs.
     * The floors are given from bottom to top.
     *
     * Requires edit access to the project. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info.
     *
     * @returns URN of the created building element.
     */
    createFromFloors(request: {
        /** The floors which define the building */
        floors: Floor[];
    }): Promise<{
        urn: string;
    }>;
    /**
     * Create multiple 2.5D buildings from stacks of floors.
     *
     * By 2.5D, we mean that the building only has vertical walls and flat roofs.
     * The floors are given from bottom to top.
     *
     * Requires edit access to the project. See {@link EmbeddedViewSdk.getCanEdit | getCanEdit} for more info.
     *
     * @returns URNs of the created building elements.
     */
    createFromFloorsBatch(request: {
        /** The floors which define the building */
        floors: Floor[];
    }[]): Promise<{
        urns: string[];
    }>;
}
/**
 * The Blobs API allows you to read blobs related to an element
 *
 * @remarks
 * Available via {@link auto.Forma | Forma}.{@link index.EmbeddedViewSdk.elements | elements}.{@link elements.ElementsApi.blobs | blobs}.
 */
export declare class BlobsApi {
    #private;
    /** @hidden */
    constructor(iframeMessenger: IframeMessenger);
    /**
     * Retrieve a blob by its id.
     *
     * Blobs are binary data that can be used for various purposes.
     * A common use case is together with linked representations
     *
     * @example
     * ```typescript
     * const { element } = await Forma.elements.get({
     *   urn: "urn:adsk-forma-elements:terrain:pro_cnusxrl4s1:c418dafe-1963-4160-9df5-239a49eef10b:1716818829774",
     * })
     *
     * if (element.representations?.volumeMesh?.type === "linked") {
     *   const blobResponse = await Forma.elements.blobs.get({
     *     blobId: element.representations.volumeMesh.blobId,
     *   })
     *   const arrayBuffer: ArrayBuffer = blobResponse.data
     * }
     * ```
     *
     * @returns an object containing the ArrayBuffer of the blob as data
     */
    get(request: {
        /** BlobId of the blob you want. For example found through a linked representation */
        blobId: string;
    }): Promise<{
        data: ArrayBuffer;
    }>;
}
