import PlaceablesLayer from "./base/placeables-layer.mjs";
import Ray from "../geometry/shapes/ray.mjs";

/**
 * @deprecated since v14
 * @ignore
 */
export default class TemplateLayer extends PlaceablesLayer {

  /** @inheritdoc */
  static get layerOptions() {
    return foundry.utils.mergeObject(super.layerOptions, {
      name: "templates",
      rotatableObjects: true,
      zIndex: 400
    });
  }

  /** @inheritdoc */
  static documentName = "MeasuredTemplate";

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

  /** @inheritdoc */
  get hookName() {
    return TemplateLayer.name;
  }

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

  /** @override */
  get placeables() {
    return canvas.scene?.templates.map(document => document.object) || [];
  }

  /* -------------------------------------------- */
  /*  Methods                                     */
  /* -------------------------------------------- */

  /** @inheritDoc */
  _getCopyableObjects(options) {
    if ( !game.user.can("TEMPLATE_CREATE") ) return [];
    return super._getCopyableObjects(options);
  }

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

  /** @override */
  activate() {
    canvas.regions.activate();
    return this;
  }

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

  /** @override */
  async _draw(options) {
    this.zIndex = this.getZIndex();

    // The objects remain empty because now only preview Measured Templates are possible
    this.objects = this.addChild(new PIXI.Container());
    this.objects.sortableChildren = true;
    this.objects.visible = false;

    // Create config preview container which is always above objects
    this._configPreview = this.addChild(new PIXI.Container());
    this._configPreview.eventMode = "none";

    // Create preview container which is always above objects
    this.preview = this.addChild(new PIXI.Container());
    this.preview.eventMode = "none";
  }

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

  /**
   * Register game settings used by the TemplatesLayer
   */
  static registerSettings() {
    /** @deprecated since v14 */
    game.settings.register("core", "gridTemplates", {
      name: "Grid-based Template Shapes",
      scope: "world",
      config: false,
      type: new foundry.data.fields.BooleanField({initial: false})
    });
    /** @deprecated since v14 */
    game.settings.register("core", "coneTemplateType", {
      name: "Cone Template Shape",
      scope: "world",
      config: false,
      type: new foundry.data.fields.StringField({required: true, blank: false, initial: "round", choices: ["round", "flat"]})
    });
  }

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

  /** @override */
  static prepareSceneControls() {
    return {
      name: "templates",
      order: 0,
      title: "Measurement Controls",
      icon: "fa-solid fa-ruler-combined",
      // We hide the scene controls because Measured Templates are deprecated
      visible: false,
      tools: {}
    };
  }

  /* -------------------------------------------- */
  /*  Event Listeners and Handlers                */
  /* -------------------------------------------- */

  /** @override */
  _createDragPreviewData(event) {
    let {origin} = event.interactionData;
    if ( !event.shiftKey ) origin = this.getSnappedPoint(origin);
    const tool = game.activeTool;
    const data = {
      user: game.user.id,
      t: tool,
      x: origin.x,
      y: origin.y,
      sort: Math.max(this.getMaxSort() + 1, 0),
      distance: 1,
      direction: 0,
      fillColor: game.user.color || "#FF0000",
      hidden: event.altKey
    };
    const defaults = CONFIG.MeasuredTemplate.defaults;
    if ( tool === "cone") data.angle = defaults.angle;
    else if ( tool === "ray" ) data.width = (defaults.width * canvas.dimensions.distance);
    return data;
  }

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

  /** @inheritdoc */
  _onDragLeftMove(event) {
    const {preview} = event.interactionData;
    if ( !preview || preview._destroyed ) return;

    // Compute the ray
    const origin = {x: preview.document.x, y: preview.document.y};
    let {destination} = event.interactionData;
    if ( !event.shiftKey ) destination = this.getSnappedPoint(destination);
    const ray = new Ray(origin, destination);
    let distance;

    // Grid type
    if ( game.settings.get("core", "gridTemplates") ) {
      distance = canvas.grid.measurePath([origin, destination]).distance;
    }

    // Euclidean type
    else {
      const ratio = (canvas.dimensions.size / canvas.dimensions.distance);
      distance = ray.distance / ratio;
    }

    // Update the preview object
    preview.document.updateSource({direction: Math.normalizeDegrees(Math.toDegrees(ray.angle)), distance});
    preview.renderFlags.set({refreshShape: true});
  }

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

  /** @inheritdoc */
  _onMouseWheel(event) {

    // Determine whether we have a hovered template?
    const template = this.hover;
    if ( !template || template.isPreview ) return;

    // Determine the incremental angle of rotation from event data
    const snap = event.shiftKey ? 15 : 5;
    const delta = snap * Math.sign(event.delta);
    return template.rotate(template.document.direction + delta, snap);
  }
}
