/*:
 * @plugindesc Live2D関連のエラーを防止し、安全に使用するためのプラグイン
 * @author えむうん 
 * @target MZ
 * @base PictureLive2D
 * @orderAfter PictureLive2D
 *
 * @help
 * このプラグインは、PictureLive2D.jsプラグインで発生する可能性のある
 * エラーを防止し、Live2D機能を安全に使用するためのものです。
 * 
 * 使用方法：
 * 1. このプラグインをPictureLive2D.jsの直後に配置してください。
 * 2. プラグインパラメータは必要ありません。
 * 
 * 機能：
 * - 存在しないピクチャへのLive2D操作を防止します。
 * - エラーが発生した場合、コンソールに警告を表示します。
 * - Live2D関連の操作が失敗しても、ゲームのクラッシュを防ぎます。
 * - トラック番号を飛ばして指定しても停止しないようにします。
 * - あとから飛ばしたトラック番号にアニメを指定した場合も正常に動作します。
 */

(function() {
    'use strict';

    // Game_Live2D クラスの拡張
    const _Game_Live2D_initialize = Game_Live2D.prototype.initialize;
    Game_Live2D.prototype.initialize = function() {
        _Game_Live2D_initialize.call(this);
        this._animation = new PIXI.Live2D.Animation([], { ids: [], values: [], count: 0 }, { ids: [], opacities: [] }, {});
    };

    // Game_Screen.prototype.live2dの安全なバージョン
    const _Game_Screen_live2d = Game_Screen.prototype.live2d;
    Game_Screen.prototype.live2d = function(id) {
        id = Number(id);
        const picture = this.picture(id);
        if (!picture) {
            console.warn(`警告: ID ${id} のピクチャが存在しません。Live2D操作をスキップします。`);
            return new Game_Live2D(); // ダミーのLive2Dオブジェクトを返す
        }
        if (!picture._live2d) {
            picture._live2d = new Game_Live2D();
        }
        return _Game_Screen_live2d.call(this, id);
    };

    // Game_Picture.prototype.initializeの拡張
    const _Game_Picture_initialize = Game_Picture.prototype.initialize;
    Game_Picture.prototype.initialize = function() {
        _Game_Picture_initialize.call(this);
        this._live2d = null; // Live2Dプロパティの初期化
    };

    // エラーハンドリング用のラッパー関数
    function safeLive2DOperation(pictureId, operation) {
        try {
            const live2d = $gameScreen.live2d(pictureId);
            return operation(live2d);
        } catch (error) {
            console.error(`Live2D操作中にエラーが発生しました: ${error.message}`);
            return null;
        }
    }

    // トラックの存在を確認し、必要に応じて初期化する関数
    function ensureTrackExists(animation, index) {
        if (!animation.tracks[index]) {
            animation.tracks[index] = new PIXI.Live2D.Track();
        }
    }

    // プラグインコマンドの安全なバージョン（RPGツクールMZ用）
    PluginManager.registerCommand('PictureLive2D', 'setModel', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => live2d.setModel(args.modelName));
    });

    PluginManager.registerCommand('PictureLive2D', 'setAnimation', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => {
            const index = Number(args.index);
            const animations = JSON.parse(args.animations);
            const order = args.order;
            const continuance = args.continuance;
            const interrupt = args.interrupt === 'true';

            ensureTrackExists(live2d._animation, index);
            live2d.setAnimation(index, animations, order, continuance, interrupt);
        });
    });

    PluginManager.registerCommand('PictureLive2D', 'clearAnimation', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => {
            const index = Number(args.index);
            const mixTime = Number(args.mixTime || 0);

            ensureTrackExists(live2d._animation, index);
            live2d.clearAnimation(index, mixTime);
        });
    });

    PluginManager.registerCommand('PictureLive2D', 'setTimeScale', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => live2d.setTimeScale(Number(args.value)));
    });

    PluginManager.registerCommand('PictureLive2D', 'setWeight', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => {
            const index = Number(args.index);
            const value = Number(args.value);

            ensureTrackExists(live2d._animation, index);
            live2d.setWeight(index, value);
        });
    });

    PluginManager.registerCommand('PictureLive2D', 'setMix', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => {
            const from = args.from;
            const to = args.to;
            const duration = Number(args.duration);
            live2d.setMix(from, to, duration);
        });
    });

    PluginManager.registerCommand('PictureLive2D', 'setAutoEyeBlink', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => {
            const enabled = args.enabled === 'true';
            const options = args.options ? JSON.parse(args.options) : undefined;
            live2d.setAutoEyeBlink(enabled, options);
        });
    });

    PluginManager.registerCommand('PictureLive2D', 'setExpression', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => live2d.setExpression(args.name));
    });

    PluginManager.registerCommand('PictureLive2D', 'setCustomExpression', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => {
            const exp3 = JSON.parse(args.exp3);
            live2d.setCustomExpression(exp3);
        });
    });

    PluginManager.registerCommand('PictureLive2D', 'clearExpression', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => live2d.clearExpression());
    });

    PluginManager.registerCommand('PictureLive2D', 'setColor', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => {
            const id = args.id || '/default/';
            const r = Number(args.r);
            const g = Number(args.g);
            const b = Number(args.b);
            const a = Number(args.a);
            live2d.setColor(id, r, g, b, a);
        });
    });

    PluginManager.registerCommand('PictureLive2D', 'setMosaic', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => {
            const id = args.id || '/default/';
            const size = Number(args.size);
            live2d.setMosaic(id, size);
        });
    });

    PluginManager.registerCommand('PictureLive2D', 'setOffset', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => {
            const x = Number(args.x);
            const y = Number(args.y);
            live2d.setOffset(x, y);
        });
    });

    PluginManager.registerCommand('PictureLive2D', 'setScale', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => {
            const x = Number(args.x);
            const y = Number(args.y);
            live2d.setScale(x, y);
        });
    });

    PluginManager.registerCommand('PictureLive2D', 'setVisible', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => {
            const visible = args.visible === 'true';
            live2d.setVisible(visible);
        });
    });

    PluginManager.registerCommand('PictureLive2D', 'resetParameters', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => {
            const ids = args.ids ? JSON.parse(args.ids) : [];
            live2d.resetParameters(...ids);
        });
    });

    PluginManager.registerCommand('PictureLive2D', 'playVoice', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => {
            const path = args.path;
            const options = args.options ? JSON.parse(args.options) : undefined;
            live2d.playVoice(path, options);
        });
    });

    PluginManager.registerCommand('PictureLive2D', 'stopVoice', function(args) {
        safeLive2DOperation(args.pictureId, (live2d) => live2d.stopVoice());
    });

})();