/**
 * @import Sound from "../../audio/sound.mjs";
 * @import {ElevatedPoint} from "../../_types.mjs";
 * @import {PlaceableObject, AmbientSound} from "../placeables/_module.mjs";
 * @import PointSoundSource from "../sources/point-sound-source.mjs";
 */

/**
 * @typedef AmbientSoundPlaybackConfig
 * @property {Sound} sound              The Sound node which should be controlled for playback
 * @property {PointSoundSource} source  The SoundSource which defines the area of effect for the sound
 * @property {AmbientSound} object      An AmbientSound object responsible for the sound, or undefined
 * @property {ElevatedPoint} listener   The coordinates of the closest listener or undefined if there is none
 * @property {number} distance          The minimum distance between a listener and the AmbientSound origin
 * @property {boolean} muffled          Is the closest listener muffled
 * @property {boolean} walls            Is playback constrained or muffled by walls and surfaces?
 * @property {number} volume            The final volume at which the Sound should be played
 */

/* -------------------------------------------- */

/**
 * @typedef CanvasHistoryEvent
 * @property {"create"|"update"|"delete"} type    The type of operation stored as history
 * @property {object[]} data                      The data corresponding to the action which may later be un-done
 * @property {object} options                     The options of the undo operation
 */

/* -------------------------------------------- */

/**
 * @typedef PlaceablesLayerOptions
 * @property {boolean} controllableObjects  Can placeable objects in this layer be controlled?
 * @property {boolean} rotatableObjects     Can placeable objects in this layer be rotated?
 * @property {boolean} keyboardMovableObjects  Can placeable objects in this layer be moved via keyboard?
 * @property {boolean} confirmDeleteKey     Confirm placeable object deletion with a dialog?
 * @property {boolean|string[]|() => boolean} confirmBeforeCreation
 *   Confirm before creating the drawn object (for the given tools)?
 * @property {boolean|string[]|() => boolean} controlObjectAfterCreation
 *   Control the drawn object that has been created (for the given tools)?
 * @property {PlaceableObject} objectClass  The class used to represent an object on this layer.
 * @property {boolean} quadtree             Does this layer use a quadtree to track object positions?
 */

/* -------------------------------------------- */

/**
 * @typedef _CanvasVisionContainerSight
 * @property {PIXI.LegacyGraphics} preview    FOV that should not be committed to fog exploration.
 */

/**
 * @typedef {PIXI.LegacyGraphics & _CanvasVisionContainerSight} CanvasVisionContainerSight
 * The sight part of {@link foundry.canvas.layers.types.CanvasVisionContainer}.
 * The blend mode is MAX_COLOR.
 */

/**
 * @typedef _CanvasVisionContainerLight
 * @property {PIXI.LegacyGraphics} preview    FOV that should not be committed to fog exploration.
 * @property {SpriteMesh} cached              The sprite with the texture of FOV of cached light sources.
 * @property {PIXI.LegacyGraphics & {preview: PIXI.LegacyGraphics}} mask The light perception polygons of vision
 *                                                                       sources and the FOV of vision sources that
 *                                                                       provide vision.
 */

/**
 * @typedef {PIXI.LegacyGraphics & _CanvasVisionContainerLight} CanvasVisionContainerLight
 * The light part of {@link foundry.canvas.layers.types.CanvasVisionContainer}.
 * The blend mode is MAX_COLOR.
 */

/**
 * @typedef _CanvasVisionContainerDarkness
 * @property {PIXI.LegacyGraphics} darkness    Darkness source erasing fog of war.
 */

/**
 * @typedef {PIXI.LegacyGraphics & _CanvasVisionContainerDarkness} CanvasVisionContainerDarkness
 * The sight part of {@link foundry.canvas.layers.types.CanvasVisionContainer}.
 * The blend mode is ERASE.
 */

/**
 * @typedef _CanvasVisionContainer
 * @property {CanvasVisionContainerLight} light       Areas visible because of light sources and light perception.
 * @property {CanvasVisionContainerSight} sight       Areas visible because of FOV of vision sources.
 * @property {CanvasVisionContainerDarkness} darkness Areas erased by darkness sources.
 */

/**
 * @typedef {PIXI.Container & _CanvasVisionContainer} CanvasVisionContainer
 * The currently visible areas.
 */

/**
 * @typedef RegionPlacementOptions
 * @property {boolean} [create=true]  Create the Region? If false, the preview document is returned.
 *                                    Default: `true`. Non-GMs cannot create Regions while the game is paused.
 * @property {Partial<Omit<DatabaseCreateOperation, "parent">>} [createOptions]  Optional creation options.
 *   By default the creation option `controlObject` is true.
 * @property {boolean} [allowRotation=true]  Allow rotation of the Region? Default: `true`.
 * @property {boolean} [allowEmpty=false]    Create/return an empty Region if all shapes are skipped?
 *                                           Default: `false`.
 * @property {boolean} [attachToToken=false] Attach the Region to Tokens? If true, the Region is attached to the
 *   hovered Token and the initial elevation range passed in `data` is relative to that Token. The Region is placed
 *   unattached if no Token is hovered: check `document.attachment.token` in `preConfirm` and return false to require
 *   an attachment. Default: `false`.
 * @property {(args: {event: PIXI.FederatedEvent; preview: Region; document: RegionDocument; regionIndex: number;
 *     regionCount: number; shape: BaseShapeData; shapeIndex: number; shapeCount: number; position: Point;
 *     snap: boolean}) => boolean|void} [onMove]
 *   Called when the pointer is moved and after starting the placement of the next shape on confirm and skip. This
 *   callback replaces the default behavior if false is returned. If false is returned, the callback should modify
 *   the passed `shape` and may additionally modify `preview.document` and set the render flags on `preview`
 *   corresponding to the applied changes.
 * @property {(args: {event: WheelEvent; preview: Region; document: RegionDocument; regionIndex: number;
 *     regionCount: number; shape: BaseShapeData; shapeIndex: number; shapeCount: number;
 *     precise: boolean}) => boolean|void} [onRotate]
 *   Called when the mouse wheel is scrolled. This callback replaces the default behavior if false is returned.
 *   If false is returned, the callback should modify the `shape` and may additionally modify `preview.document`
 *   and set the render flags on `preview` corresponding to the applied changes.
 * @property {(args: {preview: Region; document: RegionDocument; regionIndex: number; regionCount: number;
 *     shape: BaseShapeData; shapeIndex: number; shapeCount: number}) => void} [onChange]
 *   Called when the Region shape that is placed has changed.
 * @property {(args: {event: PIXI.FederatedEvent; document: RegionDocument; regionIndex: number; regionCount: number;
 *     shape: BaseShapeData; shapeIndex: number; shapeCount: number}) => boolean|void} [preConfirm]
 *   Called before the confirmation (left-click) of a shape placement. This callback may return false to prevent
 *   the placement of the Region shape and display a warning.
 * @property {(args: {event: PIXI.FederatedEvent; document: RegionDocument; regionIndex: number; regionCount: number;
 *     shape: BaseShapeData; shapeIndex: number; shapeCount: number}) => boolean|void} [preSkip]
 *   Called before skipping (right-click) of a shape placement. This callback may return false to prevent
 *   skipping of the Region shape and display a warning.
 * @property {(documents: ReadonlyArray<RegionDocument>) => Promise<any|void>|void} [preCommit]
 *   Called at the end of the workflow before the Region documents are created/returned. This callback may return
 *   a falsely value other than undefined to prevent the Regions from being created/returned.
 */
