/*:
 * @plugindesc 
 * @author 奏ねこま（おとぶき ねこま）
 *
 * @param Plugin Command
 * @desc プラグインコマンドを任意のコマンド名に変更できます。
 * @default compose_picture
 * 
 * @help 
 */
var Imported = Imported || {};
var Makonet = Makonet || {};
var _MpiCmpNo = 0; 
(function(){
    'use strict';
    var plugin = 'JsScript16Set';
    Imported[plugin] = true;
    Makonet[plugin] = {};
    var $mpi        = Makonet[plugin];
    $mpi.parameters = PluginManager.parameters(plugin);
    $mpi.plugin_command = $mpi.parameters['Plugin Command'];
    var _  = plugin;
    var __ = `$${_}`;
    function convertVariables(text) {
        if (typeof(text) !== 'string') return text;
        var pattern = '\\\\v\\[(\\d+)\\]';
        while (text.match(RegExp(pattern, 'i'))) {
            text = text.replace(RegExp(pattern, 'gi'), function(){
                return $gameVariables.value(+arguments[1]);
            });
        }
        return text;
    }
    function executeComposition(condition) {
        var bitmap_d = null;
        var bitmap_s = null;
        if (condition.dname.match(/^::composed/)) {
            var sprite = getSpritePicture(condition.did);
            if (sprite && sprite._pictureName === condition.dname && sprite[_].condition) {
                bitmap_d = sprite.bitmap;
            } else {
                bitmap_d = executeComposition(condition.dcond);
            }
        } else {
            bitmap_d = ImageManager.loadPicture(condition.dname);
        }
        if(condition.sname.match(/^DTextPicture::/)){
            var sprite = getSpritePicture(condition.sid);
            bitmap_s = sprite.bitmap;
        } else {
            if (condition.sname.match(/^::composed/)) {
                var sprite = getSpritePicture(condition.sid);
                if (sprite && sprite._pictureName === condition.sname && sprite[_].condition) {
                    bitmap_s = sprite.bitmap;
                } else {
                    bitmap_s = executeComposition(condition.scond);
                }
            } else {
                bitmap_s = ImageManager.loadPicture(condition.sname);
            }
        }
        var type = condition.type;
        var sx   = condition.sx;
        var sy   = condition.sy;
        var sw   = condition.sw || (bitmap_s.width - sx);
        var sh   = condition.sh || (bitmap_s.height - sy);
        var dx   = condition.dx;
        var dy   = condition.dy;
        var dw   = condition.dw || sw;
        var dh   = condition.dh || sh;
        var bitmap_c = new Bitmap(bitmap_d.width, bitmap_d.height);
        bitmap_c.blt(bitmap_d, 0, 0, bitmap_d.width, bitmap_d.height, 0, 0);
        bitmap_c.context.globalCompositeOperation = type;
        bitmap_c.context.drawImage(bitmap_s.canvas, sx, sy, sw, sh, dx, dy, dw, dh);
        bitmap_c._setDirty();
        return bitmap_c;
    }
    function checkBitmap(condition) {
        if (condition.dname.match(/^::composed/)) {
            var sprite = getSpritePicture(condition.did);
            if (!sprite || sprite._pictureName !== condition.dname || !sprite[_].condition) {
                if (!checkBitmap(condition.dcond)) {
                    return false;
                }
            }
        } else if (!ImageManager.loadPicture(condition.dname).isReady()) {
            return false;
        }
        if(condition.sname.match(/^DTextPicture::/)){
            return true; 
        } 
        if (condition.sname.match(/^::composed/)) {
            var sprite = getSpritePicture(condition.sid);
            if (!sprite || sprite._pictureName !== condition.sname || !sprite[_].condition) {
                if (!checkBitmap(condition.scond)) {
                    return false;
                }
            }
        } else if (!ImageManager.loadPicture(condition.sname).isReady()) {
            return false;
        }
        return true;
    }
    function getSpritePicture(pictureId) {
        var sprite_picture = null;
        var spriteset = SceneManager._scene._spriteset;
        if (spriteset) {
            spriteset._pictureContainer.children.some(function(sprite) {
                if ((sprite instanceof Sprite_Picture) && sprite._pictureId === pictureId) {
                    sprite_picture = sprite;
                    return true;
                }
            });
        }
        return sprite_picture;
    }
    Object.defineProperty(Game_Picture.prototype,_,{
        get:function(){return this[__]=this[__]||{ condition: null }},
        set:function(value){this[__]=value},
        configurable: true
    });
    Object.defineProperty(Sprite_Picture.prototype,_,{
        get:function(){return this[__]=this[__]||{ condition: null }},
        set:function(value){this[__]=value},
        configurable: true
    });
    (function(o,p){
        var f=o[p];o[p]=function(){
            var picture = this.picture();
            if (picture) {
                var condition = picture[_].condition;
                if (condition && condition !== this[_].condition) {
                    this[_].condition = null;
                    if (checkBitmap(condition)) {
                        this.bitmap = executeComposition(condition);
                        this[_].condition = condition;
                    }
                }
            }
            f.apply(this,arguments);
        };
    }(Sprite_Picture.prototype,'updateBitmap'));
    (function(o,p){
        var f=o[p];o[p]=function(){
            if (!this._pictureName.match(/^::composed/)) {
                f.apply(this,arguments);
            }
        };
    }(Sprite_Picture.prototype,'loadBitmap'));
    (function(o,p){
        var f=o[p];o[p]=function(command, args){
            if (command === $mpi.plugin_command) {
                var did = +convertVariables(args[0]) || 0;
                var sid = +convertVariables(args[1]) || 0;
                var picture_d = $gameScreen.picture(did);
                var picture_s = $gameScreen.picture(sid);
                if (picture_d && picture_s) {
                    picture_d[_].condition = {
                        did:   did,
                        dname: picture_d.name(),
                        dcond: picture_d[_].condition,
                        sid:   sid,
                        sname: picture_s.name(),
                        scond: picture_s[_].condition,
                        type:  convertVariables(args[2])  || 'source-over',
                        dx:   +convertVariables(args[3])  || 0,
                        dy:   +convertVariables(args[4])  || 0,
                        dw:   +convertVariables(args[5])  || 0,
                        dh:   +convertVariables(args[6])  || 0,
                        sx:   +convertVariables(args[7])  || 0,
                        sy:   +convertVariables(args[8])  || 0,
                        sw:   +convertVariables(args[9])  || 0,
                        sh:   +convertVariables(args[10]) || 0
                    };
                    picture_d._name = '::composed' + _MpiCmpNo; 
                    _MpiCmpNo++;
                    //picture_d._name = '::composed' + Date.now(); //←もともと:nupu
                } else {
                    var id = [];
                    if (!picture_d) id.push(did);
                    if (!picture_s) id.push(sid);
                    //throw new Error('[' + plugin + '] Picture does not exist. [id:' + id.join(',') + ']');
                }
            }
            f.apply(this,arguments);
        };
    }(Game_Interpreter.prototype,'pluginCommand'));
}());
