/*
############################################
	作者: COBRA
	改造や配布好き勝手にしても大丈夫だよ
	寧ろ積極的に配布して皆のゲーム開発を快適にしてあげて
	http://cobrara.blogspot.jp/
############################################
*/

// Version 1.1.3
// 2020/4/23 \C[0]に対応してませんでした
// 2018/4/26 ロードした際ステータスの変更もロードされるよう修正
// 2017/12/13 最新のバージョン(1.5)でデプロイメントすると1回目だけ画像が表示されない問題を修正
// 2017/8/27 1.1.0 ページの表示・非表示機能を追加しました
// 2017/7/30 1.0.4 最新のコアスクリプト(ver1.2c)にも対応しました
// 2017/5/4 1.0.3 エロステータス画面を開いてる最中NPCが動いてしまう問題を修正しました
// 2017/1/31 1.0.2 changeにおいて最後の項目に｢@@,@_,@=｣が含まれている場合エスケープされない問題を修正しました
// 2017/1/30 1.0.1 ピクチャ名に変数が反映されないバグを修正しました
// 2017/1/24 1.0.0

/*:
* @plugindesc エロステータス作れちゃうプラグイン(本体)
* @author COBRA
* @help Version 1.1.3
* 自由にいじれちゃうエロステータス画面
*
* 画像はimg/picturesにpngで保存してください
*
* 0pxの画像を表示しようとするとバグります
*
*
* 詳しくはこちらで
* http://cobrara.blogspot.jp/2017/01/blog-post_24.html
*
* 横幅：816　縦幅：624



* @param eroStaName
* @desc メニューに表示される名前だよ
* Default: エロステータス
* @default エロステータス
*
*
* @param
*
*
* @param commonEvent
* @desc エロステ画面を開く直前に実行されるコモンイベント、数値
* Default:
* @default
*/

var CBR_eroStatus = [];
var CBR_eroStatusState = {};


//表示するページ変える
Game_System.prototype.CBR_eroSta_page = function (list) {
	this.availablePage = list;
	CBR_eroStatusState.num = this.availablePage;
};


//起動・ロード・ニューゲーム時
var _CBR_Game_System_initialize = Game_System.prototype.initialize;
Game_System.prototype.initialize = function () {
	_CBR_Game_System_initialize.call(this);

	//初期値
	CBR_eroStatus = [];
	CBR_eroStatusState.num = [];
	CBR_eroStatusState.numOrigin = [];
	CBR_eroStatusState.now = null;
	CBR_eroStatusState.name = null;
	CBR_eroStatusState.event = null;

	this.availablePage = [];

	//ページ数取得
	//こっちがあったら

	for (var i = 0, len = $plugins.length; i < len; i++) {
		var temp = $plugins[i].name.match(/^CBR_eroStatus_(\d+)/);//プラグインが存在して
		if (temp) {
			CBR_eroStatusState.numOrigin[CBR_eroStatusState.numOrigin.length] = Number(temp[1]);
			CBR_eroStatusState.num[CBR_eroStatusState.num.length] = Number(temp[1]);
		}
	}



	//変更箇所の保存
	CBR_eroStatusState.numOrigin.sort(function (a, b) { return a - b; });//_nの小さい順に
	this._CBR_eroSta_change_list = [];

	//numOriginに[1,2,4,8]ってページが入ってる

	//numには表示すべき[2,4]だけが入ってる

	//エロステには[obj,obj,obj,obj]とOriginに対応した順番で入ってる



	this._CBR_eroSta_pageList = [];


	var param = PluginManager.parameters('CBR_eroStatus_main');
	CBR_eroStatusState.name = '' + (param['eroStaName'] || 'エロステータス');
	CBR_eroStatusState.event = Number(param['commonEvent']) || null;

	for (var i = 0, len = CBR_eroStatusState.numOrigin.length; i < len; i++) {//ページの数だけ
		var n = CBR_eroStatusState.numOrigin[i];
		var param = PluginManager.parameters('CBR_eroStatus_' + n);
		//nは_n.js　1,2,3
		//iはページの順番　 0,1,2
		//保存する場合は0から99
		CBR_eroStatus[i] = { 'p': [], 't': [] };

		this._CBR_eroSta_change_list[i] = {
			'p': [],
			't': []
		};

		for (var k = 1; k < 100; k++) {
			this.CBR_eroSta_add(
				'p',
				i,
				k - 1,
				param['picName_' + k],
				param['picX_' + k],
				param['picY_' + k],
				param['picOrigin_' + k],
				param['picShow_' + k],
				param['picOpacity_' + k],
				param['picZoom_' + k]
			);
			this.CBR_eroSta_add(
				't',
				i,
				k - 1,
				param['txtSubject_' + k],
				param['txtX_' + k],
				param['txtY_' + k],
				param['txtOrigin_' + k],
				param['txtShow_' + k],
				param['txtAlign_' + k],
				param['txtSize_' + k]
			);
		}
	}

	this._CBR_eroSta_change_list = [];
	for (var i = 0, len = CBR_eroStatusState.numOrigin.length; i < len; i++) {//ページ分だけチェンジリスト作る
		this._CBR_eroSta_change_list[i] = {
			'p': [],
			't': []
		};
	}

};

//セーブデータ読み込み時に実行
var _CBR_Game_System_onAfterLoad = Game_System.prototype.onAfterLoad;
Game_System.prototype.onAfterLoad = function () {
	_CBR_Game_System_onAfterLoad.call(this);

	if (this.availablePage.length) {
		CBR_eroStatusState.num = this.availablePage;
	};

	for (var i = 0, len = CBR_eroStatusState.numOrigin.length; i < len; i++) {//ページ数分繰り返す
		for (var j = 0; j < 2; j++) {
			var ty = (!j) ? 'p' : 't';
			var list = this._CBR_eroSta_change_list[i][ty];//変更したいナンバーリスト
			for (var k = 0, len2 = list.length; k < len2; k++) {
				var koumokuList = list[k].list;
				for (var m = 0, len3 = koumokuList.length; m < len3; m++) {//チェンジする項目数
					if (!CBR_eroStatus[i][ty][list[k].page]) {//その項目のデフォが存在しなかったら作成
						this.CBR_eroSta_add(ty, i);
					}
					CBR_eroStatus[i][ty][list[k].num][koumokuList[m].name] = koumokuList[m].val;
				}

			}
		}
	}
};

Game_System.prototype.CBR_eroSta_getPageIndex = function (num) {//aはaligin or opacity bはzoom
	var ary = CBR_eroStatusState.numOrigin;
	for (var i = 0, len = ary.length; i < len; i++) {
		if (ary[i] == num) {
			return i;
		}
	}
};

Game_System.prototype.CBR_eroSta_add = function (type, page, num, data, x, y, origin, show, a, b) {//aはaligin or opacity bはzoom
	if (type == 'p') {
		CBR_eroStatus[page].p[num] = {
			'name': data,
			'x': this.CBR_eroSta_changeVal('x', x),
			'y': this.CBR_eroSta_changeVal('y', y),
			'origin': origin || 'left',
			'show': (show == 'on'),
			'opacity': this.CBR_eroSta_changeVal('opacity', a),
			'zoom': this.CBR_eroSta_changeVal('zoom', b)
		};
	} else if (type == 't') {
		CBR_eroStatus[page].t[num] = {
			'subject': data,
			'x': this.CBR_eroSta_changeVal('x', x),
			'y': this.CBR_eroSta_changeVal('y', y),
			'origin': origin || 'left',
			'show': (show == 'on'),
			'align': a || 'top',
			'size': this.CBR_eroSta_changeVal('size', b)

		};
	}
};


Game_System.prototype.CBR_eroSta_changeVal = function (name, val) {//チェンジする時 add時　ロード時のチェンジで反映させよう
	switch (name) {
		case 'x':
		case 'y':
			return Number(val) || 0;
			break;
		case 'opacity':
		case 'zoom':
			if (val) {
				return Number(val) / 100;
			} else {
				return 1;
			}
			break;
		case 'show':
			return (val == 'on');
			break;
		case 'size':
			return Number(val) || 28;
			break;
		case 'name':
		case 'subject':
			return val || '';
			break;
		default:
			return val;
			break;
	}
};

Game_System.prototype.CBR_eroSta_change = function (ary) {
	var txt_ary = {
		'fontsize': 'fontSize',
		'vardigit': 'varDigit'
	};

	var checkList = {
		'p': ['name', 'origin', 'x', 'y', 'show', 'opacity', 'zoom'],
		't': ['subject', 'origin', 'x', 'y', 'show', 'align', 'size']
	}

	for (var i = 0, len = ary.length; i < len; i++) {//変更したいpage_type_nの分だけ
		var temp = ary[i].split(/@@|@_|@=|_|=/);
		var temp2 = ary[i].match(/@@|@_|@=|_|=/g);

		var list = [];//aryを分割したものを入れる
		var temp3 = '';
		for (var k = 0, len2 = temp.length; k < len2; k++) {
			if (temp2[k]) {
				if (temp2[k].charAt(0) == '@') {
					temp3 += temp[k] + temp2[k].charAt(1);
				} else {
					list[list.length] = temp3 + temp[k];
					temp3 = '';
				}
			} else {
				list[list.length] = temp3 + temp[k];
			}
		}

		list[0] = Number(list[0]);
		var page = null;
		for (var k = 0, len2 = CBR_eroStatusState.numOrigin.length; k < len2; k++) {//ページ数だけ回す
			if (CBR_eroStatusState.numOrigin[k] == list[0]) {//nと一致したら
				page = k;
			}
		}
		var type = list[1];
		var n = Number(list[2]) - 1;

		//しつこい気もするけどエロステータス開く時の軽さを最優先で
		var obj = this._CBR_eroSta_change_list[page][type];

		var objNum = false;
		for (var k = 0, len2 = obj.length; k < len2; k++) {//このページのchange数
			if (n == obj[k].num) {//nとチェンジしたい番号が一緒だったら
				objNum = k;
				break;
			}
		}
		if (objNum === false) {
			objNum = len2;
			obj[objNum] = {
				'num': n,
				'list': []
			};
		}

		//変更したいパラメータ数だけ回す
		var chaList = obj[objNum].list;
		for (var k = 3, len2 = list.length; k + 1 < len2; k += 2) {
			var listNum = false;
			for (var m = 0, len3 = chaList.length; m < len3; m++) {//既に存在するチェンジ数
				if (list[k] == chaList[m].name) {//一致する箇所があるかどうか
					listNum = m;
					break;
				}
			}
			if (listNum === false) {//無かったら
				listNum = len3;
				for (var m = 0, len3 = checkList[type].length; m < len3; m++) {//ちゃんと項目通りかチェック
					if (list[k] == checkList[type][m]) {
						break;
					} else if ((m + 1) == len3) {//もし無かったら
						alert('ERROR:CBR_eroSta_change引数');
					}
				}
			}
			list[k + 1] = this.CBR_eroSta_changeVal(list[k], list[k + 1]);
			chaList[listNum] = {
				'name': list[k],
				'val': list[k + 1]
			};
			CBR_eroStatus[page][type][n][list[k]] = list[k + 1];
		}
	}
};



//########### Scene ###########
function Scene_EroStatus() {
	this.initialize.apply(this, arguments);
}
Scene_EroStatus.prototype = Object.create(Scene_MenuBase.prototype);
Scene_EroStatus.prototype.constructor = Scene_EroStatus;

Scene_EroStatus.prototype.initialize = function () {
	Scene_MenuBase.prototype.initialize.call(this);
};
Scene_EroStatus.prototype.create = function () {
	Scene_MenuBase.prototype.create.call(this);
	if (CBR_eroStatusState.event) {
		$gameTemp.reserveCommonEvent(CBR_eroStatusState.event);

	}
	this._eroStatusWindow = new Window_EroStatus();
	this._eroStatusWindow.setHandler('cancel', this.popScene.bind(this));

	this._eroStatusWindow._margin = 0;//背景ピッチリする為
	this._eroStatusWindow.margin = 0;//本当はこっちだけどね
	this._eroStatusWindow._windowFrameSprite.visible = false;//枠線を消す

	this.addWindow(this._eroStatusWindow);
};

Scene_EroStatus.prototype.update = function () {

	$gameMap.refreshIfNeeded();
	if (this.isActive()) {
		$gameMap.updateInterpreter();
	}
	$gameMap.updateVehicles();

	Scene_Base.prototype.update.call(this);
};

//########### window ###########
function Window_EroStatus() {
	this.initialize.apply(this, arguments);
}

Window_EroStatus.prototype = Object.create(Window_Selectable.prototype);
Window_EroStatus.prototype.constructor = Window_EroStatus;

Window_EroStatus.prototype.initialize = function () {//windowを作る
	var width = Graphics.boxWidth;
	var height = Graphics.boxHeight;
	Window_Selectable.prototype.initialize.call(this, 0, 0, width, height);
	CBR_eroStatusState.now = 0;
	this._CBR_complete = false;
};

Window_EroStatus.prototype.CBR_complete = function () {//描写終わったかどうか
	return this._CBR_complete;
};

Window_EroStatus.prototype.update = function () {//毎回image描写してもいいけどそれだと負荷が多くなるのでこの方法で
	Window_Selectable.prototype.update.call(this);

	if (1 < CBR_eroStatusState.num.length && this.isOpenAndActive()) {//操作があった時
		if (Input.isRepeated('right') || Input.isRepeated('left')) {
			SoundManager.playCursor(2);//音楽鳴らす
			CBR_eroStatusState.now = ((CBR_eroStatusState.now + 1) < CBR_eroStatusState.num.length) ? CBR_eroStatusState.now + 1 : 0;
			this._CBR_complete = false;//初期化
			//this._statusWindow.refresh();//切り替えしたんでリフレッシュ
		}
	}

	var page = $gameSystem.CBR_eroSta_getPageIndex(CBR_eroStatusState.num[CBR_eroStatusState.now]);

	if (!this.CBR_complete()) {//まだ画像の描写してないのなら
		var flag = false;
		var ary = CBR_eroStatus[page].p;
		var p_data = [];
		//ピクチャの数だけ
		for (var i = 0, len = ary.length; i < len; i++) {
			var name = ary[i].name;
			if (!name || !ary[i].show) {
				continue;
			}
			name = name.replace(/\\(\\)|\\([VNP])\[(\d+)\]|\\(<)(.+)\\>/g, function (a, b, c, d, e, f) {//汚いけどこれは毎回やらないとね
				if (b) {//\\
					return '\\';
				} else if (c) {//[VNP]
					d = Number(d);
					switch (c) {
						case 'V':
							return $gameVariables.value(d);
							break;
						case 'N':
							return $gameActors._data[d]._name;
							break;
						case 'P':
							return $dataActors[$gameParty._actors[d - 1]].name;
							break;
					}
				} else {//script
					return eval(f);
				}
			});

			if (ary[i].var) {//変数があったら入れる
				var v = '' + $gameVariables.value(ary[i].var);
				if (ary[i].varDigit) {//2ケタの時は2まで
					if (v.length >= ary[i].varDigit) {
						name += v.substr(-1 * ary[i].varDigit, 1);
					} else {
						name = false;
					}
				} else {
					name += v;
				}
			}
			if (name) {
				var temp = ImageManager.loadPicture(name);//初回読み込み
				if (temp) {
					//if(temp._isLoading || temp._loadingState == 'requesting'){//前者は古いver用 ロード中ならアウト
					if (!temp.width) {//前者は古いver用 ロード中ならアウト
						flag = true;
						break;
					}
				} else {//その名前の画像が無かったら
					flag = true;
					this._CBR_complete = true;
					break;
				}
				p_data[i] = {
					'w': temp.width,
					'h': temp.height,
				}
			}
		}

		if (!flag) {//全ロードが終わってたら
			this.contents.clear();

			//ピクチャの表示
			var ary = CBR_eroStatus[page].p;
			for (var i = 0, len = ary.length; i < len; i++) {
				var name = ary[i].name;
				if (!name || !ary[i].show) {
					continue;
				}

				//変数とか文字化
				name = name.replace(/\\(\\)|\\([VNP])\[(\d+)\]|\\(<)(.+)\\>/g, function (a, b, c, d, e, f) {
					if (b) {//\\
						return '\\';
					} else if (c) {//[VNP]
						d = Number(d);
						switch (c) {
							case 'V':
								return $gameVariables.value(d);
								break;
							case 'N':
								return $gameActors._data[d]._name;
								break;
							case 'P':
								return $dataActors[$gameParty._actors[d - 1]].name;
								break;
						}
					} else {//script
						return eval(f);
					}
				});

				if (name) {
					this.changePaintOpacity(ary[i].opacity);

					var x = ary[i].x;
					var y = ary[i].y;
					if (ary[i].origin == 'center') {
						x -= p_data[i].w * ary[i].zoom / 2;
						y -= p_data[i].h * ary[i].zoom / 2;
					}
					this.drawPicture('pictures', name, 0, 0, x, y, 0, 0, ary[i].zoom, 0);
				}
			}

			//テキストの表示
			this.resetTextColor();
			var ary = CBR_eroStatus[page].t;
			for (var i = 0, len = ary.length; i < len; i++) {
				var size = ary[i].size;// ary[i].fontSize;
				var temp = ary[i].subject;
				if (!temp || !ary[i].show) {
					continue;
				}

				var opAry = temp.match(/(\\\{|\\\}|\\[CI]\[\d+\])+/g);

				//先頭にある場合は"","tesa"になる
				var strAry = temp.split(/(?:\\\{|\\\}|\\[CI]\[\d+\])+/);

				var str = '';
				var allW = 0;
				var maxSize = null;
				var dataFAry = [];
				var dataWAry = [];
				var drawI = [];
				var drawC = [];
				//分割した配列の数
				for (var k = 0, len2 = strAry.length; k < len2; k++) {

					//前方にある\{のフォントサイズを入れる
					dataFAry[k] = k ? dataFAry[k - 1] : 0;
					drawI[k] = [];

					//変数とか文字化
					strAry[k] = strAry[k].replace(/\\(\\)|\\([VNP])\[(\d+)\]|\\(G)|\\(<)(.+)\\>/g, function (a, b, c, d, e, f, g) {
						if (b) {//\\
							return '\\';
						} else if (c) {//[VNP]
							d = Number(d);
							switch (c) {
								case 'V':
									return $gameVariables.value(d);
									break;
								case 'N':
									return $gameActors._data[d]._name;
									break;
								case 'P':
									return $dataActors[$gameParty._actors[d - 1]].name;
									break;
							}
						} else if (e) {//G
							return $dataSystem.currencyUnit;
						} else {//script
							return eval(g);
						}
					});

					//自身の前に区切りマッチがあったら
					if (0 < k) {
						var temp = opAry[k - 1].split('\\');//\\{\\}を分割する
						for (var m = 1, len3 = temp.length; m < len3; m++) {

							switch (temp[m].charAt(0)) {
								case '{':
									dataFAry[k] += 6;
									break;
								case '}':
									dataFAry[k] -= 6;
									break;
								case 'C':
									drawC[k] = Number(temp[m].match(/\[(\d+)\]/)[1]);//Cは複数あっても最後のが適応されれば良いわけで
									break;
								case 'I':
									drawI[k][drawI[k].length] = Number(temp[m].match(/\[(\d+)\]/)[1]);
									break;
							}
						}
					}
					this.contents.fontSize = size + dataFAry[k];
					this.contents.context.font = this.contents._makeFontNameText();
					dataWAry[k] = this.contents.context.measureText(strAry[k]).width;//何の為に+4するのか忘れた
					allW += dataWAry[k];

					if (strAry[k]) {//先頭に\{や変数がある時の問題　アイコン乃場合もここを通さないと
						if (maxSize === null) {//まだ記録されてなかったら入れよう
							maxSize = dataFAry[k];
						} else {
							maxSize = (maxSize < dataFAry[k]) ? dataFAry[k] : maxSize;
						}
					}
				}

				var x = ary[i].x;
				if (ary[i].origin == 'center') {
					x -= allW / 2;
				} else if (ary[i].origin == 'right') {
					x -= allW;
				}
				for (var k = 0, len2 = strAry.length; k < len2; k++) {
					this.contents.fontSize = size + dataFAry[k];
					this.contents.context.font = this.contents._makeFontNameText();
					//bottom→下揃え原点の上　top→上揃え原点の下　center→原点
					var line = ary[i].y;
					var iconLine = ary[i].y;
					if (ary[i].align == 'top') {
						line += (size + dataFAry[k]) / 2;
					} else if (ary[i].align == 'bottom') {
						line -= (size + dataFAry[k]) / 2;
						iconLine -= Window_Base._iconWidth;
					} else {
						iconLine -= Window_Base._iconWidth / 2;
					}
					if (drawI[k].length) {
						for (var m = 0, len3 = drawI[k].length; m < len3; m++) {
							this.drawIcon(drawI[k][m], x, iconLine);
							x += Window_Base._iconWidth;
						}
					}
					if (drawC[k] || drawC[k] === 0) {
						this.changeTextColor(this.textColor(drawC[k]));
					}
					this.contents.drawText(strAry[k], x, line, dataWAry[k], 0, 'left');
					x += dataWAry[k];
				}
				this.contents.fontSize = this.standardFontSize();
			}
			this.resetTextColor();
			this.changePaintOpacity(true);

			this.activate();
			this._CBR_complete = true;
		}
	}
};

Window_EroStatus.prototype.drawPicture = function (dir, filename, sx, sy, x, y, w, h, zoom, hue) {
	var bitmap = ImageManager.loadBitmap('img/' + dir + '/', filename, hue, true);
	this.contents.blt(bitmap, sx, sy, bitmap.width, bitmap.height, x, y, bitmap.width * zoom, bitmap.height * zoom);
};
Window_EroStatus.prototype.standardPadding = function () {
	return 0;
};
Window_Status.prototype.lineColor = function () {
	return this.normalColor();
};
Window_Status.prototype.maxEquipmentLines = function () {
	return 6;
};

//#########　コマンドの追加　##########
Scene_Menu.prototype.commandEroSta = function () {
	SceneManager.push(Scene_EroStatus);
};
setTimeout(function () {
	var _Scene_Menu_createCommandWindow = Scene_Menu.prototype.createCommandWindow;
	Scene_Menu.prototype.createCommandWindow = function () {
		_Scene_Menu_createCommandWindow.call(this);
		this._commandWindow.setHandler('eroStatus', this.commandEroSta.bind(this));
	};
}, 0);
_Window_MenuCommand_addOriginalCommands = Window_MenuCommand.prototype.addOriginalCommands;
Window_MenuCommand.prototype.addOriginalCommands = function () {
	_Window_MenuCommand_addOriginalCommands.call(this);
	this.addCommand(CBR_eroStatusState.name, 'eroStatus', true);
};
