/*:
 * @target MZ
 * @plugindesc Force Pixel-Perfect (no smoothing) for all graphics & canvas. v1.1.0
 * @author AKIRA-support
 * @help AK_ForcePixelPerfectMZ.js
 * 
 * 目的:
 *  - すべての拡大縮小を「最近傍補間(NEAREST)」に固定し、
 *    画面の拡大率やCSS拡大でも“にじみ/ぼけ”を完全に抑えます。
 *  - WebGL/Canvas 両方に対して強制適用。キャンバスのCSSにも介入します。
 * 
 * 使い方:
 *  - js/plugins に入れてプラグイン管理でON。
 *  - 画面の拡大率(エディタ設定)を2～4にしてもドットはくっきりのまま。
 *
 * 注意:
 *  - 高解像度素材はギザギザが目立ちます。ピクセルアート向け。
 *  - 並び順は他の描画系プラグインより下(後)に置くとより確実です。
 *
 * 更新履歴:
 *  v1.1.0  CSSレベル(image-rendering: pixelated)とMutationObserverを追加
 *  v1.0.0  初版
 */
(() => {
  'use strict';

  // ---------------------------------------------------------------
  // 1) PIXI 全体を NEAREST に固定
  // ---------------------------------------------------------------
  if (window.PIXI && PIXI.settings && PIXI.SCALE_MODES) {
    PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
    PIXI.settings.ROUND_PIXELS = true;
    // PIXI v6: BaseTexture デフォルト設定を上書き（保険）
    if (PIXI.BaseTexture && PIXI.BaseTexture.defaultOptions) {
      PIXI.BaseTexture.defaultOptions.scaleMode = PIXI.SCALE_MODES.NEAREST;
    }
  }

  // 既存・今後生成される Bitmap/BaseTexture にも保険をかける
  const _Bitmap_createBaseTexture = Bitmap.prototype._createBaseTexture;
  Bitmap.prototype._createBaseTexture = function(source) {
    _Bitmap_createBaseTexture.call(this, source);
    const base = this.baseTexture;
    if (base) {
      base.scaleMode = (PIXI && PIXI.SCALE_MODES) ? PIXI.SCALE_MODES.NEAREST : 0;
    }
  };

  // 既存のテクスチャキャッシュにも適用（タイトル画面など早期読み込み対策）
  const enforceNearestForTextureCache = () => {
    try {
      const cache = PIXI.utils.TextureCache;
      if (!cache) return;
      for (const key in cache) {
        const tx = cache[key];
        if (tx && tx.baseTexture) {
          tx.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;
        }
      }
    } catch (e) {
      console.warn('AK_ForcePixelPerfectMZ: TextureCache patch failed', e);
    }
  };

  // ---------------------------------------------------------------
  // 2) Pixiアプリ生成後、renderer と canvas にドット保持設定を適用
  // ---------------------------------------------------------------
  const _Graphics_createPixiApp = Graphics._createPixiApp;
  Graphics._createPixiApp = function() {
    _Graphics_createPixiApp.call(this);
    try {
      const app = this._app;
      if (app && app.renderer) {
        if ('roundPixels' in app.renderer) app.renderer.roundPixels = true;
        // WebGL テクスチャのデフォルトサンプリングを NEAREST に（可能なら）
        if (app.renderer.texture && app.renderer.texture.bind) {
          // 現行Pixiでは個別のBind時に scaleMode 参照されるため、
          // enforceNearestForTextureCache でカバー
        }
      }
      enforceNearestForTextureCache();
      // Canvas要素にCSS適用（画面の拡大率による CSS スケールのにじみを根絶）
      const canvases = document.querySelectorAll('canvas');
      canvases.forEach(c => applyCanvasPixelated(c));
      // 今後追加される canvas にも自動で適用
      setupCanvasObserver();
    } catch (e) {
      console.warn('AK_ForcePixelPerfectMZ: Renderer/CSS patch failed', e);
    }
  };

  // ---------------------------------------------------------------
  // 3) Canvas2D フォールバック時の平滑化を完全OFF
  // ---------------------------------------------------------------
  const disableCtxSmoothing = (ctx) => {
    try {
      ctx.imageSmoothingEnabled = false;
      ctx.msImageSmoothingEnabled = false;
      ctx.mozImageSmoothingEnabled = false;
      ctx.webkitImageSmoothingEnabled = false;
    } catch(_) {}
  };

  const _Bitmap_context = Object.getOwnPropertyDescriptor(Bitmap.prototype, 'context');
  if (_Bitmap_context && _Bitmap_context.get) {
    Object.defineProperty(Bitmap.prototype, 'context', {
      get: function() {
        const ctx = _Bitmap_context.get.call(this);
        if (ctx) disableCtxSmoothing(ctx);
        return ctx;
      },
      configurable: true
    });
  }

  // ---------------------------------------------------------------
  // 4) CSS: image-rendering: pixelated を強制
  // ---------------------------------------------------------------
  function applyCanvasPixelated(canvas) {
    if (!canvas || canvas.__ak_pixelated_applied) return;
    canvas.style.imageRendering = 'pixelated';       // Chrome/Edge/Firefox
    canvas.style.msInterpolationMode = 'nearest-neighbor'; // old IE (念のため)
    canvas.__ak_pixelated_applied = true;
  }

  function setupCanvasObserver() {
    try {
      const obs = new MutationObserver((mutations) => {
        for (const m of mutations) {
          m.addedNodes.forEach(node => {
            if (node && node.nodeName === 'CANVAS') {
              applyCanvasPixelated(node);
            } else if (node && node.querySelectorAll) {
              node.querySelectorAll('canvas').forEach(c => applyCanvasPixelated(c));
            }
          });
        }
      });
      obs.observe(document.body, {childList: true, subtree: true});
    } catch (e) {
      console.warn('AK_ForcePixelPerfectMZ: MutationObserver failed', e);
    }
  }

  // ---------------------------------------------------------------
  // 5) 既存画面の Canvas にも即時適用（タイトル画面やエディタ起動直後対策）
  // ---------------------------------------------------------------
  if (document && document.readyState !== 'loading') {
    document.querySelectorAll('canvas').forEach(c => applyCanvasPixelated(c));
  } else {
    window.addEventListener('DOMContentLoaded', () => {
      document.querySelectorAll('canvas').forEach(c => applyCanvasPixelated(c));
    });
  }

})();