----------------------------------------------------------------------------------------------------------
-- 
-- 学習テーブル保存関連機能
--
----------------------------------------------------------------------------------------------------------

----------------------------------------------------------------------------------------------------------
-- ラウンド終了時などを検知して自動保存するためのスレッド。
-- TODO ほんとは round_utils の thread にEvent処理として仕込むべきなんだろうけどだるいので。
----------------------------------------------------------------------------------------------------------
function serializerThread()
	
	local rootRelationSaved = false;
	
	while (true)
	do
		-- ラウンド終了時に行動連鎖テーブル保存してなかったら保存。
		if ((roundFinished()) and (not rootRelationSaved))
		then
			serializeMotionRelations();
			rootRelationSaved = true;
		end
		
		-- 次のラウンド開始したらフラグ元に戻す。
		if (roundStarted())
		then
			rootRelationSaved = false;
		end
		yield();
	end
end

----------------------------------------------------------------------------------------------------------
-- 行動連鎖学習クラスを保存します。
-- 保存する絶対量が少ないのでラウンド終了時に一括保存する。
----------------------------------------------------------------------------------------------------------
function serializeMotionRelations()
	--[[
	if (not runningLearning)
	then
		logger:info("serializeMotionRelations", "勉強してないからほぞんしないよ。");
		return
	end
	]]--

	logger:info("serializeMotionRelations", "行動連鎖学習結果保存開始。 ラウンド数:" .. roundCount .. " 学習状態:" .. tostring(runningLearning));
	local orgRunningLearning = runningLearning;
	-- 行動連鎖保存
	if (runningLearning)
	then
		logger:info("serializeMotionRelations", "行動連鎖学習結果保存のため一時的に学習を停止します。");
		runningLearning = false;
	end
	
	--serializeMotionRelation(rootRelation, OutputStreamWriter.new(MOTIONS_RELATION_FILENAME + rootRelation.act, "w+"));
	if (serializeEnable) -- from 304_learning_thread.lua
	then
		serializeMotionRelation();
		serializeLearnTables();
	end
	
	logger:info("serializeMotionRelations", "行動連鎖学習結果を保存しました。");
	
	runningLearning = orgRunningLearning;
end

----------------------------------------------------------------------------------------------------------
-- 行動連鎖学習クラスを保存します。
-- 2階層までしか想定してないよ。
-- モーション値:0 のrootRelation 以下の子となる各モーション値ファイル名はかぶらない前提。
--
--	モーション値0のファイル
--		⇒モーション値301のファイル（モーション値0ファイルの1行）
--			⇒子要素1 401（モーション値301ファイルの1行）
--			⇒子要素2 402（モーション値301ファイルの1行）
--				・
--				・
--		⇒モーション値401のファイル（モーション値0ファイルの1行）
--			⇒子要素1 305（モーション値401ファイルの1行）
--			⇒子要素2 2142（モーション値401ファイルの1行）
--				・
--				・
--
--	※うまくいかないので再帰じゃなくばかちょんで実装。
--	　TODO 原因判明。ルートの0と子供の0がかぶってたから。気力がないので後で修正。
----------------------------------------------------------------------------------------------------------
function serializeLearnTables()
	serializeTargetLearnTable(AI_NAME_OFFENSIVE,	AI_OFFENSIVE_FILENAME);
	serializeTargetLearnTable(AI_NAME_KATAME,		AI_KATAME_FILENAME);
	serializeTargetLearnTable(AI_NAME_DEFENSIVE,	AI_DEFENSIVE_FILENAME);
	serializeTargetLearnTable(AI_NAME_OIUCHI,		AI_OIUCHI_FILENAME);
	serializeTargetLearnTable(AI_NAME_KAIHIKEKKAI,	AI_KAIHIKEKKAI_FILENAME);
	serializeTargetLearnTable(AI_NAME_RECOVERY,		AI_RECOVERY_FILENAME);
	serializeTargetLearnTable(AI_NAME_GUARD,		AI_GUARD_FILENAME);
	serializeTargetLearnTable(AI_NAME_GUREIZU,		AI_GUREIZU_FILENAME);
end

function serializeMotionRelation()

	serializeTargetRelationTable(AI_NAME_OFFENSIVE,		RELATION_OFFENSIVE_FILENAME);
	serializeTargetRelationTable(AI_NAME_KATAME,		RELATION_KATAME_FILENAME);
	serializeTargetRelationTable(AI_NAME_DEFENSIVE,		RELATION_DEFENSIVE_FILENAME);
	serializeTargetRelationTable(AI_NAME_OIUCHI,		RELATION_OIUCHI_FILENAME);
	serializeTargetRelationTable(AI_NAME_KAIHIKEKKAI,	RELATION_KAIHIKEKKAI_FILENAME);
	serializeTargetRelationTable(AI_NAME_RECOVERY,		RELATION_RECOVERY_FILENAME);
end

function serializeTargetRelationTable(name, fileName)

	local rootRelation = learnTableManager:getRelationTable(name);
	if (rootRelation == nil)
	then
		return;
	end

	local writer = OutputStreamWriter.new(fileName, "w+");

	-- 親書き込み
	print(rootRelation:serialize());
	writer:appendLineNoNewLine(rootRelation:serialize());
	-- 子書き込み
	for key, relation in pairs(rootRelation.nextMotions)
	do
		print(relation:serialize());
		writer:appendLineNoNewLine(relation:serialize());
	end
	writer:close();
end

function serializeTargetLearnTable(name, fileName)
	local learnTable = learnTableManager:getLearnTable(name);
	if (learnTable == nil)
	then
		return;
	end
	
	local writer = OutputStreamWriter.new(fileName, "w+");
	
	for key, learnedList in pairs(learnTable.learnedLists)
	do
		serializeCaptureInfo(writer, learnedList.arrayList);
	end
	writer:close();
end

----------------------------------------------------------------------------------------------------------
-- 各行動学習テーブルのCaptureInfoを行単位で保存します。
----------------------------------------------------------------------------------------------------------
function serializeCaptureInfo(writer, targetTable)
	for key, captureInfo in pairs(targetTable)
	do
		writer:appendLine(captureInfo:serialize());
	end
end

