#include "Task.h"

namespace Brainstem
{
	TaskManager::TaskManager() { }
	TaskManager::~TaskManager() { }

	void TaskManager::Update()
	{
		std::list<IPtr<ITask>>::iterator it;

		for(it = Tasks.begin(); it != Tasks.end();) 
		{
			ITask *t=(*it);
			it++;

			if(!t->Kill)
				t->Update();
		}

		Cleanup();
	}

	void TaskManager::AddTask(ITask* task)
	{
		std::list<IPtr<ITask>>::iterator it;
		Tasks.insert(Tasks.end(), task);

		WRITELN("<TSK> Allocated Task [" << task->GetName() << " | " << task << "]");
	}

	bool TaskManager::StartTasks()
	{
		WRITELN(std::endl << "Initialising Tasks.." << std::endl);

		for(std::list<IPtr<ITask>>::iterator it = Tasks.begin(); it != Tasks.end(); it++)
		{
			WRITELN("<TSK> Init Task [" << (*it)->GetName() << " | " << (*it) << "]");
			
			if (!(*it)->Init())
			{
				WRITELN((*it)->GetName() << " Initialisation Failed!" << std::endl);
				return false;
			}

			WRITELN((*it)->GetName() << " Successfully Initialised" << std::endl);
		}

		return true;
	}

	void TaskManager::RemoveTask(ITask* task)
	{
		IPtr<ITask> taskPtr = IPtr<ITask>(task);

		if(std::find(Tasks.begin(), Tasks.end(), taskPtr) != Tasks.end())
			taskPtr->Kill = true;

		Cleanup();
	}

	void TaskManager::KillAll()
	{
		for(std::list<IPtr<ITask>>::iterator it = Tasks.begin(); it != Tasks.end(); it++)
			(*it)->Kill = true;

		Cleanup();
	}

	void TaskManager::Cleanup()
	{
		std::list<IPtr<ITask>>::iterator it, thisIt;
		for(it = Tasks.begin(); it != Tasks.end();)
		{
			ITask *t=(*it);
			thisIt = it; ++it;
			if (t->Kill)
			{
				WRITELN("<TSK> Killed Task [" << t->GetName() << " | " << t << "]");
				t->Release();
				Tasks.erase(thisIt);
				t=0;
			}
		}
		IObject::CollectGarbage();
	}
}