// created by momotaro
/**
 * :grep の結果を修正したものを、実際のビューに反映させる。
 */

/**
 * 作業対象範囲を取得する
 */
function getRange() {
	var range;

	if (__range.from == __range.to == 0) {
		range = __range;
	} else if (thisView.isBoxSelected()) {
		//サポート外
		range = thisView.getCursorPos();
		range = {from: range.line, to: range.line};
	} else if (thisView.isSelected()) {
		range = thisView.getSelectedRange();
		range = {from: range.line1, to: range.line2};
	} else {
		range = thisView.getCursorPos();
		range = {from: range.line, to: range.line};
	}

	return range;
}

/**
 * 指定行より前のファイル名を探す。
 * @param line 行
 * @return 見つかったファイル名
 */
function searchFileName(line) {
	var fileName;
	var str = "";

	while (!(str =~ /^"(.*)"$/) && line > 0) {
		str = thisView.getLineString(line--);
	}
	return $1;
}


/**
 * 指定した行から、ファイル名・行・変更内容を取得する。
 */
function getReplaceData(line, prevData) {
	var str = thisView.getLineString(line);
	var result;

	if (str =~ /^\s+(\d+):(.*)$/) {
		result.line = $1.toInteger();
		result.str = $2;
		//ファイル名をまとめて表示している
		if (prevData.isMember("fileName")) {
			result.fileName = prevData.fileName;
		} else {
			result.fileName = searchFileName(line);
		}

	} else if (str =~ /^"(.*)"\((\d+)\):(.*)$/) {
		//ファイル名を個別に表示している
		result.fileName = $1;
		result.line = $2.toInteger();
		result.str = $3;

	}

	return result;
}

/**
 * 指定した範囲から、ファイル名毎の行・変更内容を取得する。
 * @param range 範囲
 * @return {ファイル名: {{ファイル名, 行, 変更内容}, ...}, ...} という形式
 */
function getReplaceDatas(range) {
	var data, result;
	for (var i = range.from; i <= range.to; i++) {
		data = getReplaceData(i, data);
		if (data.isMember("fileName")) {
			result[data.fileName] = result[data.fileName].pushBack(data);
		}
	}

	return result;
}

/**
 * 指定したファイルをViViで開いているかチェックする
 * @param fileName ファイル名
 * @return 開いていれば 1
 */
function isOpened(fileName) {
	var docs = getOpenDocPath();
	fileName = fileName.replace("/", "\\");
	for (var i = 0; i < docs.getCount(); i++) {
		if (docs[i].replace("/", "\\") == fileName) return 1;
	}
	return 0;
}

/**
 * ファイルを開き変更内容を反映する
 * @param fileName ファイル名
 * @param data 変更内容の配列
 * @param isSave 保存を行うかどうか
 * @param isClose 開いていなかったファイルを閉じるかどうか
 * @return 変更されたなら 1
 */
function replaceData(fileName, data, isSave, isClose) {
	var isReplace = 0;
	isClose = isClose && !isOpened(fileName);

	var view = openDocument(fileName).getView();

	var OrigAutoEndTag = view.getTypeSettings().getBoolValue("autoEndTag");
	view.getTypeSettings().setBoolValue("autoEndTag", 0);

	for (var i = 0; i < data.getCount(); i++) {
		if (view.getLineString(data[i].line) != data[i].str) {
			view.viCommand(data[i].line + "G0C" + data[i].str + "\x1b");
			isReplace = 1;
		}
	}

	view.getTypeSettings().setBoolValue("autoEndTag", OrigAutoEndTag);

	if (isReplace) {
		if (isSave) {
			if (isClose) {
				view.viCommand(":wq\n");
			} else {
				view.viCommand(":w\n");
			}
		}

	} else {
		if (isClose) {
			view.viCommand(":q\n");
		}
	}

	return isReplace;
}

//* メイン
function main() {
	var range = getRange();
	var data = getReplaceDatas(range);
	var fileName;
	for (fileName in data) {
		replaceData(fileName, data[fileName], 0, 1);
	}
}
//*/