///////////////////////////////////////////////////////////////////////////////
// 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 type { IViewer } from "../viewer/IViewer";

/**
 * Defines the dragger interface for the viewer.
 */
export interface IDragger {
  /**
   * The name of the dragger. Use this name to activate dragger using
   * {@link Viewer.setActiveDragger | Viewer.setActiveDragger()}
   */
  name?: string;

  /**
   * Deprecated since `25.12`. Use costructor instead to initialize dragger.
   *
   * @deprecated
   */
  initialize?(): void;

  /**
   * Releases resources allocated by the dragger.
   */
  dispose(): void;

  /**
   * Deprecated since `25.12`. Instead, register an `update` event listener for the viewer and update the
   * dragger preview in the event handler.
   *
   * @deprecated
   */
  updatePreview?(): void;
}

/**
 * Dragger provider is a function that creates a dragger instance for the specified viewer.
 */
export interface IDraggerProvider {
  /**
   * @param viewer - Viewer instance that creates the dragger.
   */
  (viewer: any): IDragger;
}

export type IDraggersMap = Map<string, IDraggerProvider>;

/**
 * Defines the viewer draggers registry interface.
 */
export interface IDraggersRegistry {
  /**
   * Binds a dragger name to a dragger provider. Registering a dragger with an existing name twice
   * overrides the existing dragger.
   *
   * @param name - Unique name for the dragger.
   * @param provider - Dragger provider.
   */
  registerDragger(name: string, provider: IDraggerProvider): void;

  /**
   * Registers an alias for a dragger.
   *
   * @param name - Unique name for the dragger.
   * @param alias - Dragger alias string.
   */
  registerDraggerAlias(name: string, alias: string): void;

  /**
   * Returns a list of registered draggers.
   */
  getDraggers(): IDraggersMap;

  /**
   * Returns the specified dragger provider or `undefined` when the dragger doesn't exists.
   *
   * @param name - Dragger name.
   */
  getDragger(name: string): IDraggerProvider | undefined;

  /**
   * Creates the dragger denoted by the given name. Returns `null` if a dragger with given name not
   * registered.
   *
   * @param name - Dragger name.
   * @param viewer - Viewer instance that wants to create the dragger.
   */
  createDragger(name: string, viewer: IViewer): IDragger | null;
}
