----------------------------------------------------------------------------------------------------------
-- 
----------------------------------------------------------------------------------------------------------
ActionManager=extends(NamedObject);

	----------------------------------------------------------------------------------------------------------
	-- 
	----------------------------------------------------------------------------------------------------------
	function ActionManager:constructor(enable)
		self.running = running;
		self.selectors = {};
		self.interrupters = {};
		self.player = ActionPlayer.new();
		self.interruptPlayer = ActionPlayer.new();
		self.evaluateAverageTable = {};			-- デバッグ用
	end

	----------------------------------------------------------------------------------------------------------
	-- 
	----------------------------------------------------------------------------------------------------------
	function ActionManager:addSelector(selector, actionSituation)
		table.insert(self.selectors, ActionSelectorHolder.new(selector, actionSituation));
		self.evaluateAverageTable[selector.name] = AverageCalculator.new();
	end

	----------------------------------------------------------------------------------------------------------
	-- 
	----------------------------------------------------------------------------------------------------------
	function ActionManager:addInterrupter(interrupter, interruptSituation)
		table.insert(self.interrupters, ActionSelectorHolder.new(interrupter, interruptSituation));
		self.evaluateAverageTable[interrupter.name] = AverageCalculator.new();
	end

	----------------------------------------------------------------------------------------------------------
	-- 
	----------------------------------------------------------------------------------------------------------
	function ActionManager:action()
		while (not battleFinished())
		do
			self.running = runningAction;
			if (self.running)
			then
				-- オートガード簡易実装
				if (recommendGuard(TARGET_MY, 80))
				then
					logger:debug("ActionManager", "オートガード発動！");
					key_off(ACT_DOWNLEFT);
					key_off(ACT_DOWNRIGHT);
					key_off(ACT_UPLEFT);
					key_off(ACT_UPRIGHT);
					key_off(ACT_UP);
					key_off(ACT_DOWN);
					key_off(ACT_A);
					key_off(ACT_B);
					key_off(ACT_C);
					key_off(ACT_D);
					key_off(ACT_AB);
					key_off(ACT_BC);

					key_on(back);

					-- オートガード暫定
					for i = 0, 15
					do
						if (isGuardMotion(tracer[TARGET_MY]:current().act))
						then
							-- 結界暴発防止措置
							wait(20);
							break;
						end
						yield();
					end
					self.player:reset();
					self.interruptPlayer:reset();
				else
					self:interrupt();
					self:play();
				end
			else
				-- プレイヤー停止中はyield掛ける。
				yield();
			end
		end
	end

	----------------------------------------------------------------------------------------------------------
	-- 
	----------------------------------------------------------------------------------------------------------
	function ActionManager:interrupt()
		local counter=0;
		local inInterrupting = false;
		while (self:interrupting())
		do
			inInterrupting = true;
			counter = counter + 1;
			if (counter >= 300)
			then
				error("無限ループ気味" .. counter);
			end
			-- 割込み以外の行動中だとまずいので初期化
			self.player:reset();

			-- オートガード簡易実装
			if (recommendGuard(TARGET_MY, 80))
			then
				logger:debug("ActionManager", "Interrupt中オートガード発動！");
				key_off(ACT_DOWNLEFT);
				key_off(ACT_DOWNRIGHT);
				key_off(ACT_UPLEFT);
				key_off(ACT_UPRIGHT);
				key_off(ACT_UP);
				key_off(ACT_DOWN);
				key_off(ACT_A);
				key_off(ACT_B);
				key_off(ACT_C);
				key_off(ACT_D);
				key_off(ACT_AB);
				key_off(ACT_BC);

				key_on(back);

				-- オートガード暫定
				for i = 0, 15
				do
					if (isGuardMotion(tracer[TARGET_MY]:current().act))
					then
						-- 結界暴発防止措置
						wait(20);
						break;
					end
					yield();
				end
				self.player:reset();
				self.interruptPlayer:reset();
			end

			-- 割込み行動を処理
			if (not self.interruptPlayer.playing)
			then
				self.interruptPlayer:reset();
				local captureInfo = self:select(self.interrupters);
				if (captureInfo == nil)
				then
					logger:trace(self.name, "選択行動なし");
					yield(); -- 選択なしなら状況進めるためにyield();
					break;
				end
				self.interruptPlayer:initialize(captureInfo);
			else
				logger:trace("ActionManager", "interruptPlayer再生中 phase:" .. self.interruptPlayer.phase .. 
											  " act:" .. self.interruptPlayer.playingCaptureInfo.act);
				self.interruptPlayer:forward();
			end
		end
		if (inInterrupting and not self:interrupting())
		then
			print("★★★ 割り込みぬけた！！");
		end
		self.interruptPlayer:reset();
	end

	----------------------------------------------------------------------------------------------------------
	-- 
	----------------------------------------------------------------------------------------------------------
	function ActionManager:interrupting()
		local interrupting = false;
		for key, holder in pairs(self.interrupters)
		do
			interrupting = interrupting or holder.actionSituation(TARGET_MY);
		end
		return interrupting;
	end

	----------------------------------------------------------------------------------------------------------
	-- 
	----------------------------------------------------------------------------------------------------------
	function ActionManager:play()
		if (not self.player.playing)
		then
			logger:trace("ActionManager", "player初期化");
			-- 行動選択
			local captureInfo = self:select(self.selectors);
			if (captureInfo == nil)
			then
				logger:trace(self.name, "選択行動なし");
				yield(); -- 選択なしなら状況進めるためにyield();
				return;
			end
			-- 裏でカード選択を試みる。
			tryTargetCardSelect(captureInfo);
			-- Player初期化
			self.player:initialize(captureInfo);
		else		
			logger:trace("ActionManager", "player再生中 phase:" .. self.player.phase .. 
										  " act:" .. self.player.playingCaptureInfo.act);
			self.player:forward();
		end
	end

	----------------------------------------------------------------------------------------------------------
	-- 
	----------------------------------------------------------------------------------------------------------
	function ActionManager:select(selectors)
		local assertAllFalse = false;
		local result, evaluate = nil, nil;
		for key, holder in pairs(selectors)
		do
			assertAllFalse = assertAllFalse or holder.actionSituation(TARGET_MY);
			if (holder.actionSituation(TARGET_MY))
			then
				-- 状況は逐一変わるわけだからいいよね。
				result, evaluate = holder.selector:select(tracer[TARGET_MY]:current());
				--result, evaluate = holder.selector:select(tracer[TARGET_MY]:tracedCurrent());
				if (result ~= nil)
				then
					-- デバッグ用
					if (not self.player.playing)
					then
						if (isBlowMotion(result.act))
						then
							self.evaluateAverageTable[holder.selector.name]:addValue(evaluate, 1);
						end
						logger:debug(holder.selector.name, "で行動選択した。評価:" .. evaluate ..
																		 " ボーダー:" .. holder.selector.border);
					end
					break;
				end
			end
		end
		--assert(assertAllFalse, "行動できなくなった！ ");
		return result, evaluate;
	end

----------------------------------------------------------------------------------------------------------
-- 
----------------------------------------------------------------------------------------------------------
ActionSelectorHolder=extends(NamedObject);

	----------------------------------------------------------------------------------------------------------
	-- 
	----------------------------------------------------------------------------------------------------------
	function ActionSelectorHolder:constructor(selector, actionSituation)
		self.selector = selector;
		self.actionSituation = actionSituation;
	end
	