require("debug.lua");
if(DEBUG_FUNCTION)
then
	require("101_common_oop.lua");
	require("111_logger.lua");
	require("113_common_collections.lua");
	require("151_common_environment.lua");
	require("152_global_instance.lua");
	require("161_common_functions.lua");
	require("162_round_utils.lua");
	require("201_capture_info.lua");
end
----------------------------------------------------------------------------------------------------------
-- 
-- 自分 or 敵の行動をトレースするクラス
-- 
----------------------------------------------------------------------------------------------------------
MotionTracer=extends(NamedObject);

	----------------------------------------------------------------------------------------------------------
	-- コンストラクタ
	--	引数
	--		name			: 制御インスタンスの名前
	--		target			: トレースターゲット指定
	--		historicalList	: 履歴保存List HistoricalListクラスを使いましょう。
	----------------------------------------------------------------------------------------------------------
	function MotionTracer:constructor(name, target, historicalList)
		-- このTracerの名前
		self.name = name;
		-- トレース対象
		self.target = target;
		-- 履歴用Listインスタンス
		self.historicalList = historicalList;
		-- トレースの有効/無効
		self.enableTrace = true;
	end

	----------------------------------------------------------------------------------------------------------
	-- 試合中、対象の行動をトレースします。
	----------------------------------------------------------------------------------------------------------
	function MotionTracer:trace()
		while (not battleFinished())
		do
			self:traceMotion();
			yield();
		end
	end

	----------------------------------------------------------------------------------------------------------
	-- 対象の行動をトレースします。
	----------------------------------------------------------------------------------------------------------
	function MotionTracer:traceMotion()
		if (not self.enableTrace)
		then
			return;
		end
		-- キャプチャ開始
		self:traceMotionFrame();
	end

	----------------------------------------------------------------------------------------------------------
	-- 学習対象の行動Frame数をトレースします。
	-- 通常、外部からこのメソッドを呼ぶ必要はありません。
	--	see 105_common_functions.lua
	--	戻り値
	--		captureInfo	:キャプチャした環境変数群
	----------------------------------------------------------------------------------------------------------
	function MotionTracer:traceMotionFrame()
		
		local captureInfo = CaptureInfo.new(self.target);
		captureInfo:capture();

		-- 飛翔硬直はいろいろと問題が出るのでトレースしない。
		if (captureInfo.act == 2140)
		then
			return;
		end

		-- 測定開始とともに履歴に追加
		self.historicalList:add(captureInfo);

		-- 初期化
		local currentFrame = 0;
		local currentAct = captureInfo.act;
		local orgAct = captureInfo.act;

		-- デバッグ用
		local tempFrame = getTargetFrame(self.target);

		-- 行動フレーム数測定
		while (currentAct == orgAct)
		do
			if (isIncrementAirMotion(currentAct))
			then
			logger:trace(self.name, "Frame測定中 target:" .. self.target ..
									" orgAct:" .. orgAct ..
									" currentAct:" .. currentAct ..
									" captureInfo.my_air:" .. captureInfo:getParameter(CaptureInfo_my_air) ..
									" my_air:" .. getTargetAir(self.target) ..
									" currentFrame:" .. currentFrame ..
									" targetframe:" .. getTargetFrame(self.target));
			end
			--[[
			]]--
			tempFrame = getTargetFrame(self.target);
			captureInfo:setFrame(currentFrame);

			yield();

			currentFrame = currentFrame + 1;
			currentAct = getTargetCurrentAction(self.target);
		end
		logger:trace(self.name, " トレース対象 : " .. self.target .. 
								" Frame数測定結果 orgAct:" .. orgAct .. 
								" 手動測定frame:" .. captureInfo.frame .. 
								" 自キャラ:" .. captureInfo:getParameter(CaptureInfo_my_char) .. 
								" 敵キャラ:" .. captureInfo:getParameter(CaptureInfo_enemy_char) .. 
								" frame:" .. tempFrame);
		return;
	end

	----------------------------------------------------------------------------------------------------------
	-- 現在トレース中の行動を返します。
	----------------------------------------------------------------------------------------------------------
	function MotionTracer:current()
		return self.historicalList:current();
	end

	----------------------------------------------------------------------------------------------------------
	-- 一つ前のトレース結果の行動を返します。
	----------------------------------------------------------------------------------------------------------
	function MotionTracer:before()
		return self.historicalList:before();
	end

	----------------------------------------------------------------------------------------------------------
	-- トレース済みの最新行動を返します。 beforeといっしょ
	----------------------------------------------------------------------------------------------------------
	function MotionTracer:tracedCurrent()
		return self.historicalList:before();
	end

	----------------------------------------------------------------------------------------------------------
	-- トレース済み最新行動の一つ前のトレース結果の行動を返します。
	----------------------------------------------------------------------------------------------------------
	function MotionTracer:tracedBefore()
		return self.historicalList:get(self.historicalList:size() - 2);
	end

	----------------------------------------------------------------------------------------------------------
	-- 指定Indexをさかのぼったトレース結果の行動を返します。1なら一個前 = before()と一緒。
	----------------------------------------------------------------------------------------------------------
	function MotionTracer:history(index)
		return self.historicalList:get(self.historicalList:size() - index);
	end

tracer={};
function traceThread()
	tracer[TARGET_MY] 	 = MotionTracer.new("自分Tracer", TARGET_MY, HistoricalList.new(10));
	tracer[TARGET_ENEMY] = MotionTracer.new("敵Tracer", TARGET_ENEMY, HistoricalList.new(10));

	create_thread(traceMyMotionThread);
	create_thread(traceEnemyMotionThread);
end

function traceMyMotionThread()
	tracer[TARGET_MY]:trace();
end

function traceEnemyMotionThread()
	tracer[TARGET_ENEMY]:trace();
end


function main()

	create_thread(traceThread);
	yield();

	local myMotion = nil;
	local old_myMotion = nil;
	local enemyMotion = nil;
	local old_enemyMotion = nil;
	while (true)
	do
		myMotion = tracer[TARGET_MY]:current();
		enemyMotion = tracer[TARGET_ENEMY]:current();

		if (not myMotion:equals(old_myMotion))
		then
			print("自分current:", myMotion:serialize());
			if (tracer[TARGET_MY]:before() ~= nil)
			then
				print("自分before:", tracer[TARGET_MY]:before():serialize());
			end
			old_myMotion = myMotion;
		end
		if (not enemyMotion:equals(old_enemyMotion))
		then
			print("敵:", enemyMotion:serialize());
			old_enemyMotion = enemyMotion;
		end
		yield();
	end
end
