import BaseDrawing from "@common/documents/drawing.mjs";
import CanvasDocumentMixin from "./abstract/canvas-document.mjs";
import {EllipseShapeData, PolygonShapeData, RectangleShapeData} from "@client/data/shapes.mjs";


/**
 * @import {DrawingData} from "@common/documents/_types.mjs";
 */

/**
 * The client-side Drawing document which extends the common BaseDrawing model.
 *
 * @extends BaseDrawing
 * @mixes ClientDocumentMixin
 * @category Documents
 *
 * @see {@link foundry.documents.Scene}: The Scene document type which contains Drawing embedded documents
 * @see {@link foundry.applications.sheets.DrawingConfig}: The Drawing configuration application
 */
export default class DrawingDocument extends CanvasDocumentMixin(BaseDrawing) {
  /**
   * Fields included in the drawing defaults setting
   * @type {(keyof DrawingData)[]}
   */
  static defaultDrawingFields = [
    "strokeWidth",
    "strokeColor",
    "strokeAlpha",
    "bezierFactor",
    "fillType",
    "fillColor",
    "fillAlpha",
    "texture",
    "text",
    "fontFamily",
    "fontSize",
    "textColor",
    "textAlpha",
    "elevation",
    "levels",
    "interface"
  ];

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

  /**
   * The rectangle shape of this Tile document.
   * @type {RectangleShapeData|EllipseShapeData|PolygonShapeData}
   * @internal
   */
  _shape = this._shape; // Workaround for subclass property instantiation issue.

  /* -------------------------------------------- */
  /*  Model Properties                            */
  /* -------------------------------------------- */

  /**
   * Is the current User the author of this drawing?
   * @type {boolean}
   */
  get isAuthor() {
    return game.user === this.author;
  }

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

  /** @inheritDoc */
  prepareDerivedData() {
    super.prepareDerivedData();
    if ( this.parent ) {
      const d = this.parent.dimensions;
      const {width, height} = this.shape;
      this.x = Math.clamp(this.x + (width / 2), 0, d.width) - (width / 2);
      this.y = Math.clamp(this.y + (height / 2), 0, d.height) - (height / 2);
    }
    this._shape = DrawingDocument.#createShape(this);
  }

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

  /**
   * Create the rectangle/ellipse/polygon shape.
   * @param {DrawingDocument} document
   * @returns {RectangleShapeData|EllipseShapeData|PolygonShapeData}
   */
  static #createShape(document) {
    const {x, y, shape, rotation} = document;
    const {type, width, height} = shape;
    switch ( type ) {
      case "r":
        return new RectangleShapeData({
          x: x + (width / 2),
          y: y + (height / 2),
          width, height,
          anchorX: 0.5, anchorY: 0.5,
          rotation
        }, {parent: document});
      case "e":
        return new EllipseShapeData({
          x: x + (width / 2),
          y: y + (height / 2),
          radiusX: width / 2,
          radiusY: height / 2,
          rotation
        }, {parent: document});
      case "p": {
        const polygon = new PolygonShapeData({
          points: shape.points.slice(),
          origin: {x: width / 2, y: height / 2}
        }, {parent: document});
        polygon.rotate(rotation);
        polygon.move({x: x + (width / 2), y: y + (height / 2)});
        return polygon;
      }
      case "c": throw new Error("The circle type is not supported");
    }
  }
}
