import type { IframeMessenger } from "../iframe-messenger.js";
export type Position = {
    x: number;
    y: number;
    z: number;
};
export type Scale = {
    x: number;
    y: number;
};
export type Bbox = {
    min: Position;
    max: Position;
};
/**
 * Represents a terrain pad (flat polygon) that modifies the terrain surface.
 *
 * @remarks
 * Terrain pads are used to create flat areas on the terrain at specific elevations.
 * They are commonly used for building foundations, roads, or other construction purposes.
 * The pad modifies the terrain mesh within its defined polygon boundary, setting
 * all terrain vertices within that area to the specified elevation.
 *
 * @example
 * ```typescript
 * // Example of a TerrainPad object returned by getPads()
 * {
 *   id: "7ab85ec80b3e2",
 *   coordinates: [
 *     { x: 100, y: 200 },
 *     { x: 150, y: 200 },
 *     { x: 150, y: 250 },
 *     { x: 100, y: 250 }
 *   ],
 *   elevation: 45.5,
 *   slopeAngle: 30,
 *   slopePercentage: 57.74
 * }
 * ```
 */
export type TerrainPad = {
    /**
     * Unique identifier for the terrain pad. Can be an arbitrary string.
     */
    id: string;
    /**
     * Array of 2D coordinates defining the polygon boundary of the pad.
     * Coordinates are in the local coordinate system (meters).
     * The polygon should be closed (first and last points should form a closed shape).
     */
    coordinates: {
        x: number;
        y: number;
    }[];
    /**
     * The elevation of the pad in meters above sea level.
     * All terrain within the pad boundary will be set to this elevation.
     */
    elevation: number;
    /**
     * Whether to apply a grade to the pad.
     * If true, the pad will be graded to the specified slope angle or slope percentage.
     * If false, the pad will not be graded.
     */
    applySlope: boolean;
    /**
     * The slope angle in degrees for the transition zone around the pad boundary.
     * This defines how steeply the terrain slopes from the surrounding terrain
     * to the pad's elevation at its boundary.
     *
     * When modifying pads, you must specify the slope using either
     * {@link TerrainPad.slopeAngle} (in degrees) or {@link TerrainPad.slopePercentage}.
     * If both are specified, the slope percentage will be used.
     *
     * Must be greater than 0 and strictly lower than 90 degrees.
     *
     * @remarks
     * - When undefined, no slope buffer is applied and the terrain transitions
     *   abruptly at the pad boundary.
     * - A value of 45 degrees means the terrain rises/falls 1 meter vertically
     *   for every 1 meter of horizontal distance in the buffer zone.
     * - Smaller angles create gentler slopes; larger angles create steeper slopes.
     *
     * @see {@link TerrainPad.slopePercentage} for the equivalent slope as a percentage.
     */
    slopeAngle?: number;
    /**
     * The slope percentage for the transition zone around the pad boundary.
     * This is an alternative representation of the slope, where 100% means
     * the terrain rises/falls 1 meter vertically for every 1 meter of horizontal distance.
     *
     * When modifying pads, you must specify the slope using either
     * {@link TerrainPad.slopeAngle} (in degrees) or {@link TerrainPad.slopePercentage}.
     * If both are specified, the slope percentage will be used.
     *
     * Must be larger than 0.
     *
     * @remarks
     * - When undefined, no slope buffer is applied and the terrain transitions
     *   abruptly at the pad boundary.
     * - A value of 100 corresponds to a 45-degree slope angle.
     * - A value of 50 corresponds to approximately a 26.57-degree slope angle.
     * - This value is mathematically related to {@link TerrainPad.slopeAngle} by:
     *   `slopePercentage = tan(slopeAngle * π / 180) * 100`
     *
     * @see {@link TerrainPad.slopeAngle} for the equivalent slope in degrees.
     */
    slopePercentage?: number;
};
/**
 * Interact with the terrain in the 3D scene.
 *
 * @remarks
 * Available via {@link auto.Forma | Forma}.{@link index.EmbeddedViewSdk.terrain | terrain}.
 */
export declare class TerrainApi {
    #private;
    groundTexture: GroundTextureApi;
    /** @hidden */
    constructor(iframeMessenger: IframeMessenger);
    /**
     * Fetch the bounding box for the terrain.
     *
     * @returns Axis-aligned bounding box for the terrain.
     * More specifically, the minimum and maximum (x,y,z) values, in the local coordinate system.
     */
    getBbox(): Promise<Bbox>;
    /**
     * Retrieves the elevation of the terrain (in meters above sea level) at a specific point within the scene.
     *
     * If the coordinates are outside the terrain mesh, it returns the minimum elevation in the terrain.
     */
    getElevationAt(request: {
        /** The X-coordinate of the point in the local coordinate system. */
        x: number;
        /** The Y-coordinate of the point in the local coordinate system. */
        y: number;
    }): Promise<number>;
    /**
     * Returns whether the terrain is internal.
     *
     * @remarks
     * Internal terrain is managed fully within Forma Site Design.
     * Non-internal terrain can potentially be coming from other cloud applications,
     * including Revit Cloud Model and other Forma Connected Clients.
     *
     * Certain operations such as {@link TerrainApi.addPads | addPads},
     * {@link TerrainApi.applyPads | applyPads}, and
     * {@link ProposalApi.replaceTerrain | replaceTerrain} are only supported
     * for internal terrains.
     */
    isInternal(): Promise<boolean>;
    /**
     * Retrieves all terrain pads defined in the current terrain.
     *
     * @remarks
     * Terrain pads are flat areas applied to the terrain surface.
     *
     * Each pad defines a polygon boundary at a specific elevation. The terrain mesh
     * within the polygon is modified to match the pad's elevation. An optional slope
     * angle defines how the terrain transitions from surrounding areas to the pad.
     *
     * @returns An array of {@link TerrainPad} objects representing all terrain pads.
     * Returns an empty array if no pads are defined on the terrain.
     *
     * @example
     * ```typescript
     * // Retrieve all terrain pads
     * const pads = await Forma.terrain.getPads();
     *
     * // Log information about each pad
     * for (const pad of pads) {
     *   console.log(`Pad ID: ${pad.id}`);
     *   console.log(`  Elevation: ${pad.elevation}m`);
     *   console.log(`  Vertices: ${pad.coordinates.length}`);
     *   if (pad.slopeAngle !== undefined) {
     *     console.log(`  Slope angle: ${pad.slopeAngle}°`);
     *   }
     * }
     * ```
     */
    getPads(): Promise<TerrainPad[]>;
    /**
     * Adds new terrain pads to the existing pads on the terrain.
     *
     * @remarks
     * This method appends the provided pads to the current set of terrain pads
     * without removing or modifying existing ones. Use this when you want to
     * incrementally add new flat areas to the terrain while preserving existing pads.
     *
     * This method is only supported when the terrain is internal.
     * Use {@link TerrainApi.isInternal | isInternal} to check whether the terrain is internal.
     *
     * Each pad must specify its slope using either `slopeAngle` (in degrees) or
     * `slopePercentage`, but not both.
     *
     * @param pads - Array of terrain pads to add.
     *
     * @example
     * ```typescript
     * // Add multiple pads with different slope specifications
     * await Forma.terrain.addPads([
     *   {
     *     id: "7ab85ec80b3e2",
     *     coordinates: [
     *       { x: 0, y: 0 },
     *       { x: 100, y: 0 },
     *       { x: 100, y: 100 },
     *       { x: 0, y: 100 }
     *     ],
     *     elevation: 50,
     *     applySlope: true,
     *     slopeAngle: 30  // Using degrees
     *   },
     *   {
     *     id: "70234fcf791b2",
     *     coordinates: [
     *       { x: 200, y: 0 },
     *       { x: 300, y: 0 },
     *       { x: 300, y: 100 },
     *       { x: 200, y: 100 }
     *     ],
     *     elevation: 45,
     *     applySlope: true,
     *     slopePercentage: 50  // Using percentage
     *   },
     *   {
     *     id: "70234fcf791b3",
     *     coordinates: [
     *       { x: 200, y: 0 },
     *       { x: 300, y: 0 },
     *       { x: 300, y: 100 },
     *       { x: 200, y: 100 }
     *     ],
     *     elevation: 45,
     *     applySlope: false // No slope applied; abrupt pad
     *   }
     * ]);
     * ```
     *
     * @see {@link TerrainApi.applyPads} to replace all existing pads.
     * @see {@link TerrainApi.getPads} to retrieve current pads.
     */
    addPads(pads: TerrainPad[]): Promise<void>;
    /**
     * Replaces all existing terrain pads with the provided array of pads.
     *
     * @remarks
     * This method unconditionally sets the terrain pads to the provided array,
     * removing any existing pads that are not included in the new array.
     * Use this when you want complete control over the terrain pads, or when
     * you need to remove pads.
     *
     * This method is only supported when the terrain is internal.
     * Use {@link TerrainApi.isInternal | isInternal} to check whether the terrain is internal.
     *
     * To remove all pads, call this method with an empty array.
     *
     * @param pads - Array of terrain pads to set. Pass an empty array to remove all pads.
     *
     * @example
     * ```typescript
     * // Replace all pads with a new set
     * await Forma.terrain.applyPads([
     *   {
     *     id: "7ab85ec80b3e2",
     *     coordinates: [
     *       { x: 0, y: 0 },
     *       { x: 100, y: 0 },
     *       { x: 100, y: 100 },
     *       { x: 0, y: 100 }
     *     ],
     *     elevation: 50,
     *     applySlope: true,
     *     slopeAngle: 30
     *   }
     * ]);
     * ```
     *
     * @example
     * ```typescript
     * // Remove all terrain pads
     * await Forma.terrain.applyPads([]);
     * ```
     *
     * @see {@link TerrainApi.addPads} to add pads without removing existing ones.
     * @see {@link TerrainApi.getPads} to retrieve current pads.
     */
    applyPads(pads: TerrainPad[]): Promise<void>;
}
/**
 * Manage ground textures applied to the terrain object in the 3D scene.
 *
 * @remarks
 * Available via {@link auto.Forma | Forma}.{@link index.EmbeddedViewSdk.terrain | terrain}.{@link terrain.TerrainApi.groundTexture | groundTexture}.
 */
export declare class GroundTextureApi {
    #private;
    /** @hidden */
    constructor(iframeMessenger: IframeMessenger);
    /**
     * Add a ground texture to the terrain.
     *
     * @example
     * // Create canvas
     * const canvas = document.createElement("canvas");
     * canvas.width = 100;
     * canvas.height = 100;
     *
     * // Fill canvas with blue color
     * const ctx = canvas.getContext("2d");
     * if (ctx) {
     *    ctx.fillStyle = "blue";
     *    ctx.fillRect(0, 0, 100, 100);
     *
     *    // Add canvas as ground texture to position (0, 0) in the local coordinate system.
     *    // The texture will cover a 100x100 meter square area on the terrain,
     *    // with lower left corner in (x: -50, y: -50) and upper right corner in (x: 50, y: 50).
     *    await Forma.terrain.groundTexture.add({
     *        name: "myGroundTexture",
     *        canvas,
     *        position: { x: 0, y: 0, z: 1 },
     *        scale: { x: 1, y: 1 },
     *      });
     * }
     */
    add(request: {
        /** The name of the texture to add. */
        name: string;
        /** The canvas to use as texture data. */
        canvas: HTMLCanvasElement;
        /** x and y position denotes where to place the center of the canvas. z gives the order of the ground texture and overlapping textures with a larger z position will cover those with a smaller one. */
        position: Position;
        /** The number of meters each pixel in the canvas represents. Defaults to 1 meter. */
        scale?: Scale | undefined;
    }): Promise<void>;
    /**
     * Update the texture data for an existing ground texture object.
     *
     * @example
     * // Create a new canvas filled with red and update the ground texture with this new texture
     * const newCanvas = document.createElement("newCanvas");
     * newCanvas.width = 100;
     * newCanvas.height = 100;
     * const ctx = newCanvas.getContext("2d");
     * if (ctx) {
     *    ctx.fillStyle = "red";
     *    ctx.fillRect(0, 0, 100, 100);
     *    await Forma.terrain.groundTexture.updateTextureData({
     *        name: "myGroundTexture",
     *        canvas: newCanvas,
     *    });
     * }
     */
    updateTextureData(request: {
        /** The name of the texture to update. */
        name: string;
        /** The canvas to use as updated texture data. */
        canvas: HTMLCanvasElement;
    }): Promise<void>;
    /**
     * Update the placement of an existing ground texture object.
     *
     * @example
     * // Move "myGroundTexture" to (100, 100) in the local coordinate system.
     * await Forma.terrain.groundTexture.updatePosition({
     *   name: "myGroundTexture",
     *   position: { x: 100, y: 100, z: 1 }
     * })
     */
    updatePosition(request: {
        /** The name of the texture to move. */
        name: string;
        /** The position to move the ground texture to. x and y position denotes where to place the center of the canvas. z gives the order of the ground texture and overlapping textures with a larger z position will cover those with a smaller one. */
        position: Position;
    }): Promise<void>;
    /**
     * Remove an existing ground texture object.
     *
     * @example
     * // Remove "myGroundTexture".
     * await Forma.terrain.groundTexture.remove({ name: "myGroundTexture" })
     */
    remove(request: {
        /** The name of the texture to remove. */
        name: string;
    }): Promise<void>;
}
