#include "OverlayBase.h"
#include "ModelBase.h"

namespace Engine {

void OverlayManager::InitOverlays() {
	std::map<unsigned int, std::list<OverlayBasePtr> >::iterator map_iter = mOverlays.begin();

	if (map_iter == mOverlays.end())
		return;

	while (map_iter != mOverlays.end()) {
		std::list<OverlayBasePtr>::iterator list_iter = map_iter->second.begin();

		while (list_iter != map_iter->second.end()) {
			(*list_iter)->Init ();
			list_iter++;
		}

		map_iter ++;
	}
}

void OverlayManager::Draw () {
	ModelBase *model = EngineGetModel();
	assert (model);

	std::map<unsigned int, std::list<OverlayBasePtr> >::iterator map_iter = mOverlays.find(model->mGameState);

	if (map_iter == mOverlays.end())
		return;
	
	std::list<OverlayBasePtr>::iterator list_iter = map_iter->second.begin();

	while (list_iter != map_iter->second.end()) {
		(*list_iter)->Draw ();
		list_iter++;
	}
}

void OverlayManager::Register (OverlayBasePtr overlay, unsigned int game_state) {
	LogDebug ("Adding overlay 0x%x state: %u", &overlay, game_state);

	mOverlays[game_state].push_back(overlay);
}

/* Input forwarding for the overlays */
bool OverlayManager::SendKeyDown (const SDL_keysym &keysym) {
	ModelBase *model = EngineGetModel();
	assert (model);

	std::map<unsigned int, std::list<OverlayBasePtr> >::iterator map_iter = mOverlays.find(model->mGameState);

	if (map_iter == mOverlays.end())
		return false;
	
	std::list<OverlayBasePtr>::iterator list_iter = map_iter->second.begin();

	while (list_iter != map_iter->second.end()) {
		if ((*list_iter)->OnKeyDown (keysym))
			return true;

		list_iter++;
	}
	return false;
}

bool OverlayManager::SendKeyUp (const SDL_keysym &keysym) {
	ModelBase *model = EngineGetModel();
	assert (model);

	std::map<unsigned int, std::list<OverlayBasePtr> >::iterator map_iter = mOverlays.find(model->mGameState);

	if (map_iter == mOverlays.end())
		return false;
	
	std::list<OverlayBasePtr>::iterator list_iter = map_iter->second.begin();

	while (list_iter != map_iter->second.end()) {
		if ((*list_iter)->OnKeyUp (keysym))
			return true;

		list_iter++;
	}
	return false;
}

bool OverlayManager::SendMouseButtonUp (Uint8 button, Uint16 xpos, Uint16 ypos) {
	ModelBase *model = EngineGetModel();
	assert (model);

	std::map<unsigned int, std::list<OverlayBasePtr> >::iterator map_iter = mOverlays.find(model->mGameState);

	if (map_iter == mOverlays.end())
		return false;
	
	std::list<OverlayBasePtr>::iterator list_iter = map_iter->second.begin();

	while (list_iter != map_iter->second.end()) {
		if ((*list_iter)->OnMouseButtonUp (button, xpos, ypos))
			return true;

		list_iter++;
	}
	return false;
}

bool OverlayManager::SendMouseButtonDown (Uint8 button, Uint16 xpos, Uint16 ypos) {
	ModelBase *model = EngineGetModel();
	assert (model);

	std::map<unsigned int, std::list<OverlayBasePtr> >::iterator map_iter = mOverlays.find(model->mGameState);

	if (map_iter == mOverlays.end())
		return false;
	
	std::list<OverlayBasePtr>::iterator list_iter = map_iter->second.begin();

	while (list_iter != map_iter->second.end()) {
		if ((*list_iter)->OnMouseButtonDown (button, xpos, ypos))
			return true;

		list_iter++;
	}
	return false;
}

}
