#include"CMessageHookManager.h"
#include"../../auxiliary/Debug/CAssert.h"


namespace Maid
{

static CMessageHookManager* g_pHookManager;


CMessageHookManager::CMessageHookManager()
{
	MAID_ASSERT( g_pHookManager!=NULL, "すでに存在しています" );

	g_pHookManager = this;
}

void CMessageHookManager::AddHook( IMessageHook* pHook, HWND hWnd )
{
	if( hWnd==NULL )
	{
		m_GlobalProc.push_front( pHook );
	}else
	{
		m_ProcMap[hWnd].push_front( pHook );
	}
}

void CMessageHookManager::DelHook( IMessageHook* pHook, HWND hWnd )
{
	if( hWnd==NULL )
	{
		m_GlobalProc.remove( pHook );
	}else
	{
		const MySTL::map<HWND,HOOKLIST>::iterator ite = m_ProcMap.find(hWnd);

		MAID_ASSERT(ite==m_ProcMap.end(), "登録されていないクラスが削除されようとしています" );

		HOOKLIST& List = ite->second;

		List.remove( pHook );
	}
}

CMessageHookManager* CMessageHookManager::GetInstance()
{
	return g_pHookManager;
}


LRESULT CALLBACK CMessageHookManager::OnMessage( CWindowsMessage& mess  )
{
	{
		HOOKLIST& List = m_GlobalProc;

		for( HOOKLIST::iterator ite=List.begin(); ite!=List.end(); ++ite )
		{	//	投げられたメッセージを処理したら DefWindowProc は呼ばない
			if( (*ite)->OnMessage( mess )==IMessageHook::RETURNCODE_EXIT ) { return 0; }
		}
	}

	MySTL::map<HWND,HOOKLIST>::iterator ProcList = m_ProcMap.find( mess.GetHWND() );
	if( ProcList!=m_ProcMap.end() )
	{
		HOOKLIST& List = ProcList->second;

		for( HOOKLIST::iterator ite=List.begin(); ite!=List.end(); ++ite )
		{	//	投げられたメッセージを処理したら DefWindowProc は呼ばない
			if( (*ite)->OnMessage( mess )==IMessageHook::RETURNCODE_EXIT ) { return 0; }
		}
	}

	return ::DefWindowProc(mess.GetHWND(),mess.GetMSG(),mess.GetWPARAM(),mess.GetLPARAM());
}

}