///////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
// All rights reserved.
//
// This software and its documentation and related materials are owned by
// the Alliance. The software may only be incorporated into application
// programs owned by members of the Alliance, subject to a signed
// Membership Agreement and Supplemental Software License Agreement with the
// Alliance. The structure and organization of this software are the valuable
// trade secrets of the Alliance and its suppliers. The software is also
// protected by copyright law and international treaty provisions. Application
// programs incorporating this software must include the following statement
// with their copyright notices:
//
//   This application incorporates Open Design Alliance software pursuant to a
//   license agreement with Open Design Alliance.
//   Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
//   All rights reserved.
//
// By use of this software, its documentation or related materials, you
// acknowledge and accept the above terms.
///////////////////////////////////////////////////////////////////////////////

import { IEventEmitter } from "@inweb/eventemitter2";
import { IViewpoint } from "@inweb/viewer-core";
import { IWorldTransform } from "./IWorldTransform";
import { IMarkupObject } from "./IMarkupObject";

/**
 * Defines the markup edit mode. Matches the type of markup object being created.
 */
export type MarkupMode = "SelectMarkup" | "Line" | "Text" | "Rectangle" | "Ellipse" | "Arrow" | "Image" | "Cloud";

/**
 * 2D markup core interface.
 */
export interface IMarkup {
  /**
   * Line width of new markup objects.
   *
   * @default 4
   */
  lineWidth: number;

  /**
   * Line type of new markup objects. Can be `solid`, `dot` or `dash`.
   *
   * @default `solid`
   */
  lineType: string;

  /**
   * Font size of new markup text.
   *
   * @default 34
   */
  fontSize: number;

  /**
   * Initializes the markup instance. Call {@link dispose | dispose()} to release allocated resources.
   *
   * @param container - Container element used to operate on. This is usually a `<canvas>` or `<div>` on
   *   top of which the markup is drawn. If the `container` is a `<canvas>` element, its content will be
   *   combined with the markup in the viewpoint snapshot.
   * @param containerEvents - List of container events, such as mouse events or
   *   {@link https://developer.mozilla.org/docs/Web/API/Pointer_events#event_types_and_global_event_handlers | pointer events}
   *   or {@link https://developer.mozilla.org/docs/Web/API/TouchEvent#touch_event_types | touch events}
   *   that the markup should redirect to the `viewer`.
   * @param viewer - `Viewer` instance that receives pointing device events.
   * @param worldTransformer - Transformer of screen space into the `viewer` world space and vice versa.
   *   If a transformer is defined, markup objects will be stored at the viewpoint in world coordinates,
   *   otherwise in screen coordinates.
   */
  initialize(
    container: HTMLElement,
    containerEvents?: string[],
    viewer?: IEventEmitter,
    worldTransformer?: IWorldTransform
  ): void;

  /**
   * Releases resources allocated in the {@link initialize | initialize()}.
   */
  dispose(): void;

  /**
   * Creates the markup overlay.
   */
  syncOverlay(): void;

  /**
   * Deletes all markup objects and clears the markup overlay.
   */
  clearOverlay(): void;

  /**
   * Sets the default color of new markup objects.
   *
   * @param r - The `red` component of the color, as a number between 0 and 255.
   * @param g - The `green` component of the color, as a number between 0 and 255.
   * @param b - The `blue` component of the color, as a number between 0 and 255.
   */
  setMarkupColor(r: number, g: number, b: number): void;

  /**
   * Returns the color of new markup objects.
   */
  getMarkupColor(): { r: number; g: number; b: number };

  /**
   * Colors all markup objects with the specified color.
   *
   * @param r - The `red` component of the color, as a number between 0 and 255.
   * @param g - The `green` component of the color, as a number between 0 and 255.
   * @param b - The `blue` component of the color, as a number between 0 and 255.
   */
  colorizeAllMarkup(r: number, g: number, b: number): void;

  /**
   * Colors the selected markup objects with the specified color.
   *
   * @param r - The `red` component of the color, as a number between 0 and 255.
   * @param g - The `green` component of the color, as a number between 0 and 255.
   * @param b - The `blue` component of the color, as a number between 0 and 255.
   */
  colorizeSelectedMarkups(r: number, g: number, b: number): void;

  /**
   * Sets the markup state to the specified viewpoint.
   *
   * @param viewpoint - Viewpoint data.
   */
  setViewpoint(viewpoint: IViewpoint): void;

  /**
   * Saves the markup state at the viewpoint.
   */
  getViewpoint(viewpoint: IViewpoint): IViewpoint;

  /**
   * Enables mouse interactions to select or draw markups.
   *
   * @param mode - Edit mode. Matches the type of markup object being created. Specify `false` to exit
   *   edit mode.
   */
  enableEditMode(mode: MarkupMode | false): this;

  /**
   * Creates a markup object.
   *
   * @param type - Markup object type. Can be `Line`, `Text`, `Rectangle`, `Ellipse`, `Arrow`, `Image` or
   *   `Cloud`.
   * @param params - Parameters for creating a markup object. Must match the object type:
   *
   *   - `Line` - {@link IMarkupLineParams}
   *   - `Text` - {@link IMarkupTextParams}
   *   - `Rectangle` - {@link IMarkupRectangleParams}
   *   - `Ellipse` - {@link IMarkupEllipseParams}
   *   - `Arrow` - {@link IMarkupArrowParams}
   *   - `Image` - {@link IMarkupImageParams}
   *   - `Cloud` - {@link IMarkupCloudParams}
   */
  createObject(type: string, params: any): IMarkupObject;

  /**
   * Returns the list of all markup objects.
   */
  getObjects(): IMarkupObject[];

  /**
   * Returns the list of selected markup objects.
   */
  getSelectedObjects(): IMarkupObject[];

  /**
   * Selects the specified markup objects.
   *
   * @param objects - The list of markup objects.
   */
  selectObjects(objects: IMarkupObject[]): void;

  /**
   * Clears the markup objects selection.
   */
  clearSelected(): void;
}
