/*:
 * @plugindesc イベント間の経路を可視化するプラグイン（拡張版）
 * @author えむうん
 * @target MZ
 * @help このプラグインは、指定された2つのイベント間の経路を
 * 画面上に描画します。経路の色と線の幅を指定することもできます。
 * また、移動元と移動先の座標を指定した変数に格納します。
 * 
 * 使用方法:
 * プラグインコマンド：
 * DrawPath event1Id event2Id color lineWidth - 2つのイベント間の経路を描画
 * ClearAllPaths - 全ての描画された経路を消去
 * 
 * 色の指定: red, orange, yellow, green, blue, indigo, purple, white, black
 * 線の幅: 1から10の整数
 * 
 * @param startXVariableId
 * @text 開始X座標変数ID
 * @type variable
 * @desc 経路の開始X座標を格納する変数のID
 * @default 1
 * 
 * @param startYVariableId
 * @text 開始Y座標変数ID
 * @type variable
 * @desc 経路の開始Y座標を格納する変数のID
 * @default 2
 * 
 * @param endXVariableId
 * @text 終了X座標変数ID
 * @type variable
 * @desc 経路の終了X座標を格納する変数のID
 * @default 3
 * 
 * @param endYVariableId
 * @text 終了Y座標変数ID
 * @type variable
 * @desc 経路の終了Y座標を格納する変数のID
 * @default 4
 * 
 * @command DrawPath
 * @text 経路描画
 * @desc 2つのイベント間の経路を描画します。
 * 
 * @arg event1Id
 * @type number
 * @text イベント1のID
 * @desc 開始地点となるイベントのID
 * 
 * @arg event2Id
 * @type number
 * @text イベント2のID
 * @desc 終了地点となるイベントのID
 * 
 * @arg color
 * @type select
 * @option 赤
 * @value red
 * @option 橙
 * @value orange
 * @option 黄
 * @value yellow
 * @option 緑
 * @value green
 * @option 青
 * @value blue
 * @option 藍
 * @value indigo
 * @option 紫
 * @value purple
 * @option 白
 * @value white
 * @option 黒
 * @value black
 * @default red
 * @text 経路の色
 * @desc 経路の色を指定します
 * 
 * @arg lineWidth
 * @type number
 * @min 1
 * @max 10
 * @default 3
 * @text 線の幅
 * @desc 経路の線の幅を指定します（1-10）
 * 
 * @command ClearAllPaths
 * @text 全経路消去
 * @desc 描画された全ての経路を消去します。
 */

(() => {
    const pluginName = "EventPathVisualizer";
    let pathSprites = [];

    const COLOR_MAP = {
        red: 'rgba(255, 0, 0, 0.7)',
        orange: 'rgba(255, 165, 0, 0.7)',
        yellow: 'rgba(255, 255, 0, 0.7)',
        green: 'rgba(0, 255, 0, 0.7)',
        blue: 'rgba(0, 0, 255, 0.7)',
        indigo: 'rgba(75, 0, 130, 0.7)',
        purple: 'rgba(128, 0, 128, 0.7)',
        white: 'rgba(255, 255, 255, 0.7)',
        black: 'rgba(0, 0, 0, 0.7)'
    };

    const parameters = PluginManager.parameters(pluginName);
    const startXVariableId = Number(parameters['startXVariableId'] || 1);
    const startYVariableId = Number(parameters['startYVariableId'] || 2);
    const endXVariableId = Number(parameters['endXVariableId'] || 3);
    const endYVariableId = Number(parameters['endYVariableId'] || 4);

    function debugLog(message) {
        if (Utils.isOptionValid('test')) {
            console.log(`[${pluginName}] ${message}`);
        }
    }

    PluginManager.registerCommand(pluginName, "DrawPath", args => {
        const event1Id = Number(args.event1Id);
        const event2Id = Number(args.event2Id);
        const color = COLOR_MAP[args.color] || COLOR_MAP.red;
        const lineWidth = Number(args.lineWidth).clamp(1, 10);
        drawPathBetweenEvents(event1Id, event2Id, color, lineWidth);
    });

    PluginManager.registerCommand(pluginName, "ClearAllPaths", args => {
        clearAllPaths();
    });

    function drawPathBetweenEvents(event1Id, event2Id, color, lineWidth) {
        const event1 = $gameMap.event(event1Id);
        const event2 = $gameMap.event(event2Id);
        
        if (!event1 || !event2) {
            debugLog(`指定されたイベントが見つかりません。Event1: ${event1Id}, Event2: ${event2Id}`);
            return;
        }

        // 座標を変数に格納
        $gameVariables.setValue(startXVariableId, event1.x);
        $gameVariables.setValue(startYVariableId, event1.y);
        $gameVariables.setValue(endXVariableId, event2.x);
        $gameVariables.setValue(endYVariableId, event2.y);

        debugLog(`経路探索開始 - Event1(${event1.x}, ${event1.y}) to Event2(${event2.x}, ${event2.y})`);
        const path = findPath(event1.x, event1.y, event2.x, event2.y);
        if (path) {
            debugLog(`経路が見つかりました。長さ: ${path.length}`);
            createPathSprite(path, color, lineWidth);
        } else {
            debugLog("経路が見つかりませんでした。");
        }
    }

    function findPath(startX, startY, endX, endY) {
        debugLog(`経路探索: (${startX}, ${startY}) から (${endX}, ${endY})`);
        
        // 簡易的な経路探索（直線）を実装
        const path = [];
        let x = startX;
        let y = startY;

        while (x !== endX || y !== endY) {
            path.push({x, y});
            if (x < endX) x++;
            else if (x > endX) x--;
            if (y < endY) y++;
            else if (y > endY) y--;
        }
        path.push({x: endX, y: endY});

        debugLog(`探索完了。経路長: ${path.length}`);
        return path;
    }

    function createPathSprite(path, color, lineWidth) {
        debugLog("経路の描画を開始");
        const sprite = new Sprite_Path(path, color, lineWidth);
        SceneManager._scene._spriteset._tilemap.addChild(sprite);
        pathSprites.push(sprite);
        debugLog(`経路の描画完了 (色: ${color}, 線の幅: ${lineWidth})`);
    }

    function clearAllPaths() {
        debugLog("全ての経路を消去します");
        for (const sprite of pathSprites) {
            sprite.parent.removeChild(sprite);
        }
        pathSprites = [];
        debugLog("全ての経路を消去しました");
    }

    class Sprite_Path extends Sprite {
        constructor(path, color, lineWidth) {
            super();
            this._path = path;
            this._color = color;
            this._lineWidth = lineWidth;
            this.createBitmap();
            this.updatePosition();
        }

        createBitmap() {
            const width = $gameMap.width() * $gameMap.tileWidth();
            const height = $gameMap.height() * $gameMap.tileHeight();
            this.bitmap = new Bitmap(width, height);
            this.redrawPath();
        }

        updatePosition() {
            this.x = -$gameMap.displayX() * $gameMap.tileWidth();
            this.y = -$gameMap.displayY() * $gameMap.tileHeight();
        }

        redrawPath() {
            this.bitmap.clear();
            const context = this.bitmap.context;
            context.strokeStyle = this._color;
            context.lineWidth = this._lineWidth;
            context.beginPath();

            for (let i = 0; i < this._path.length; i++) {
                const x = (this._path[i].x + 0.5) * $gameMap.tileWidth();
                const y = (this._path[i].y + 0.5) * $gameMap.tileHeight();
                
                if (i === 0) {
                    context.moveTo(x, y);
                } else {
                    context.lineTo(x, y);
                }
            }
            context.stroke();
        }

        update() {
            super.update();
            this.updatePosition();
        }
    }

    const _Spriteset_Map_createLowerLayer = Spriteset_Map.prototype.createLowerLayer;
    Spriteset_Map.prototype.createLowerLayer = function() {
        _Spriteset_Map_createLowerLayer.call(this);
        this.createPathLayer();
    };

    Spriteset_Map.prototype.createPathLayer = function() {
        this._pathLayer = new Sprite();
        this._tilemap.addChild(this._pathLayer);
    };
})();