import PlaceablePaletteMixin from "./placeable-palette-mixin.mjs";
import TileConfig from "../tile-config.mjs";
import FormDataExtended from "../../ux/form-data-extended.mjs";

/**
 * A dialog that provides bulk operation or default values for newly-created tiles.
 * @extends {TileConfig}
 * @mixes PlaceablePaletteMixin
 */
export default class TilePalette extends PlaceablePaletteMixin(TileConfig) {
  /** @override */
  static DEFAULT_OPTIONS = {
    id: "tile-palette",
    initialData: { width: 100, height: 100 }
  };

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

  /**
   * The setting key where default data is saved.
   * @type {string}
   */
  static SETTING_KEY = "tilePalette";

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

  /**
   * The placeable document.
   * @type {string}
   */
  static documentName = "Tile";

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

  /** @override */
  static TABS = {};

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

  /** @override */
  static PARTS = {
    body: { template: "templates/scene/palette/tile/body.hbs" },
    footer: { template: "templates/generic/form-footer.hbs" }
  };

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

  /** @inheritDoc */
  get createData() {
    if ( !this.rendered ) return super.createData;
    // Special case handling for the tile layer which doesn't typically 'draw' tiles, but instead places them from the
    // tile browser while the select tool is active. Changes made to the palette with the select tool do not usually
    // update draw state, so we retrieve them directly from the form.
    const formData = new FormDataExtended(this.form);
    return foundry.utils.expandObject(formData.object);
  }

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

  /** @override */
  static get schema() {
    const schema = super.schema;
    ["x", "y", "width", "height", "sort", "rotation", "name", "hidden", "locked"].forEach(f => {
      delete schema.fields[f];
    });
    ["src", "fit", "alphaThreshold"].forEach(f => delete schema.fields.texture.fields[f]);
    return schema;
  }

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

  /**
   * Store ephemeral palette state.
   * @type {{elevation: {dynamic: boolean, original: number|null}}}
   */
  #state = {
    elevation: {
      dynamic: false,
      original: null
    }
  };

  /* -------------------------------------------- */
  /*  Rendering                                   */
  /* -------------------------------------------- */

  /** @inheritDoc */
  async _prepareContext(options) {
    const context = await super._prepareContext(options);
    context.elevation = context.source.elevation;
    context.isForeground = context.elevation >= canvas.level.elevation.top;
    if ( context.isForeground ) {
      if ( context.elevation < canvas.level.elevation.top ) {
        Object.assign(this.#state.elevation, { dynamic: true, original: context.elevation });
        context.elevation = canvas.level.elevation.top;
      }
    } else if ( this.#state.elevation.dynamic ) {
      context.elevation = this.#state.elevation.original;
      Object.assign(this.#state.elevation, { dynamic: false, original: null });
    }
    return context;
  }

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

  /** @override */
  async _preparePartContext(partId, context) {
    context.partId = `${this.id}-${partId}`;
    return context;
  }
}
