-- 課題：hitしなかったときのキャンセル行動自体キャンセル、受身モーション、起き上がりモーションの扱い

----------------------------------------------------------------------------------------------------------
-- モーションマッピング 主にActionPlayerとかで利用。
----------------------------------------------------------------------------------------------------------
motionMapping = getInitializedMotionMapping(); -- from 203_motion_mapping.lua

----------------------------------------------------------------------------------------------------------
-- 
----------------------------------------------------------------------------------------------------------
ActionSelector=extends(NamedObject);

	----------------------------------------------------------------------------------------------------------
	-- 
	----------------------------------------------------------------------------------------------------------
	function ActionSelector:constructor(name, evaluator, proposalSize, border)
		-- Selector名
		self.name = name;
		-- 比較関数
		self.evaluator = evaluator;
		-- selectする連鎖候補数
		self.proposalSize = proposalSize;
		-- 評価ボーダ
		self.border = border;
	end

	----------------------------------------------------------------------------------------------------------
	-- 
	----------------------------------------------------------------------------------------------------------
	function ActionSelector:select(beforePlayedCaptureInfo)
		local rootRelation = learnTableManager:getRelationTable(self.name);
		local result = nil;
		if ((beforePlayedCaptureInfo == nil) or (beforePlayedCaptureInfo.act == 0))
		then
			result, currentEvaluate = self:selectFromRelation(rootRelation);
		else
			if (rootRelation:hasNextMotion(beforePlayedCaptureInfo.act))
			then
				result, currentEvaluate = self:selectFromRelation(rootRelation:getNextMotion(beforePlayedCaptureInfo.act));
			else
				result, currentEvaluate = self:selectFromRelation(rootRelation);
			end
		end
		return result, currentEvaluate;
	end

	----------------------------------------------------------------------------------------------------------
	-- 
	----------------------------------------------------------------------------------------------------------
	function ActionSelector:selectFromRelation(baseRelation)
		local nextRelations = baseRelation:getNextMotionRandom(self.proposalSize);
		if ((nextRelations == nil) or (#nextRelations < 1))
		then
			logger:trace("ActionSelector, " .. self.name, "候補なし");
			return nil;
		end

		local learnTable = learnTableManager:getLearnTable(self.name);
		local result, minEvaluate = nil, nil;
		local currentEvaluate = DEFAULT_THRESHOLDS;
		local beforeEvaluate = DEFAULT_THRESHOLDS;

		-- 複数候補を取れるようにループネストさせる予定。⇒とりあえず対応。
		for key, nextRelation in pairs(nextRelations)
		do
			--print(baseRelation.act, nextRelation.act, baseRelation.frequency[nextRelation.act], learnTable:getInnerList(nextRelation.act));
			local learnedList = learnTable:getInnerList(nextRelation.act);
			for key, captureInfo in pairs(learnedList.arrayList)
			do
				currentEvaluate = self.evaluator(captureInfo);
				--print(baseRelation.act, nextRelation.act, baseRelation.frequency[nextRelation.act], currentEvaluate, beforeEvaluate, self.border);
				if ((currentEvaluate < beforeEvaluate) and (currentEvaluate < self.border))
				then
					result = captureInfo;
					minEvaluate = currentEvaluate;
					beforeEvaluate = currentEvaluate;
				end
				if (result ~= nil)
				then
					logger:trace("ActionSelector, " .. self.name, " ボーダー:" .. self.border ..
																  " 前回行動:" .. baseRelation.act .. 
																  " 検索対象行動:" .. nextRelation.act .. 
																  " 行動候補誤差:" .. currentEvaluate);
				end
			end
		end

		return result, minEvaluate;
	end


----------------------------------------------------------------------------------------------------------
--
-- ガード、グレイズ用行動連鎖に依存しないフラット学習テーブル前提のActionSelector
--
----------------------------------------------------------------------------------------------------------
ActionSelectorForFlatTable=extends(ActionSelector);

	----------------------------------------------------------------------------------------------------------
	-- 
	----------------------------------------------------------------------------------------------------------
	function ActionSelectorForFlatTable:constructor(name, evaluator, border)
		-- Selector名
		self.name = name;
		-- 比較関数
		self.evaluator = evaluator;
		-- 評価ボーダ
		self.border = border;
	end

	function ActionSelectorForFlatTable:select()
		-- ガード、グレイズはFlatLearndTable
		local learnTable = learnTableManager:getLearnTable(self.name);
		local learnedList = learnTable:getInnerList();
		if (learnedList == nil)
		then
			logger:debug("[ActionSelector, " .. self.name .. "]", "候補なし");
			return nil;
		end

		local result, minEvaluate = nil, nil;
		local currentEvaluate = DEFAULT_THRESHOLDS;
		local beforeEvaluate = DEFAULT_THRESHOLDS;
		for key, captureInfo in pairs(learnedList.arrayList)
		do
			currentEvaluate = self.evaluator(captureInfo);
			if ((currentEvaluate < beforeEvaluate) and (currentEvaluate < self.border))
			then
				result = captureInfo;
				minEvaluate = currentEvaluate;
				beforeEvaluate = currentEvaluate;
			end
		end
		if (result ~= nil)
		then
			logger:debug("[ActionSelector, " .. self.name .. "]", " ボーダー:" .. self.border ..
																  " 検索対象行動:" .. result.act .. 
																  " 行動候補誤差:" .. minEvaluate);
		end
		return result, minEvaluate;
	end
