#include"CMouseDriverWindowsMSG.h"
#include<Winuser.h>


#if !defined(WM_MOUSEWHEEL)
	#define WM_MOUSEWHEEL  (0x020A)	//!<	マウスホイールが回ったときに投げられるメッセージ
#endif



namespace Maid
{
	/*!
	 	@class	CMouseDriverWindowsMSG CMouseDriverWindowsMSG.h
	 	@brief	マウスドライバ
	 */ 

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! コンストラクタ
/*!
 */
CMouseDriverWindowsMSG::CMouseDriverWindowsMSG( HWND hWnd ) : m_hWnd(hWnd), m_Position(3), m_IsDown(3)
{
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! デストラクタ
/*!
 */
CMouseDriverWindowsMSG::~CMouseDriverWindowsMSG()
{
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! マウスドライバの初期化
/*!
 	引数などは IMouseDriver::Initialize を参照すること
 */
void CMouseDriverWindowsMSG::Initialize()
{
	for( int i=0; i<(int)m_Position.size(); ++i ) { m_Position[i] = 0; }
	for( int i=0; i<(int)m_IsDown.size()  ; ++i ) { m_IsDown[i] = false; }

	m_ShowCount = 0;
	AddProc( NULL );
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! マウスドライバの解放
/*!
 *	引数などは IMouseDriver::Finalize を参照すること
 */
void CMouseDriverWindowsMSG::Finalize()
{

}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! 各軸の座標を取得する
/*!
 	引数などは IMouseDriver::GetPosition を参照すること
 */
void CMouseDriverWindowsMSG::GetState( MySTL::vector<int>& PosList, MySTL::vector<bool>& KeyList ) const
{
	POINT pos;

	::GetCursorPos( &pos );
	::ScreenToClient( m_hWnd, &pos );

	PosList = m_Position;
	PosList[0] = pos.x;
	PosList[1] = pos.y;

	const int key[] = { VK_LBUTTON, VK_RBUTTON };
	for( int i=0; i<NUMELEMENTS(key); ++i )
	{
		const_cast<CMouseDriverWindowsMSG*>(this)->m_IsDown[i] = IsFlag(::GetAsyncKeyState(key[i]),0x8000);
	}

	KeyList = m_IsDown;
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! このドライバで識別できる軸の数を取得する
/*!
 	引数などは IMouseDriver::GetPositionMax を参照すること
 */
int	CMouseDriverWindowsMSG::GetPositionMax()	const
{
	return (int)m_Position.size();
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! このドライバで識別できるボタンの数を取得する
/*!
 	引数などは IMouseDriver::GetButtonMax を参照すること
 */
int	CMouseDriverWindowsMSG::GetButtonMax()	const
{
	return (int)m_IsDown.size();
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! OSで供給されているマウスカーソルをつけたり消したり
/*!
 	引数などは IMouseDriver::SetDrawHardWareCursor を参照すること
 */
void CMouseDriverWindowsMSG::SetDrawHardWareCursor( bool IsShow )
{
	m_ShowCount = ::ShowCursor(IsShow? TRUE : FALSE);
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! OSで供給されているマウスカーソルが表示されているか？
/*!
 	引数などは IMouseDriver::IsCursorShow を参照すること
 */
bool CMouseDriverWindowsMSG::IsCursorShow() const
{
	return 0<=m_ShowCount;
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! プロシージャにコールバックしてもらう関数
/*!
 	引数などは IMessageHook::OnMessage を参照すること
 */
IMessageHook::RETURNCODE CMouseDriverWindowsMSG::OnMessage( CWindowsMessage& Param )
{
	const UINT	 msg = Param.GetMSG();
	const WPARAM wParam = Param.GetWPARAM();
	const LPARAM lParam = Param.GetLPARAM();

	switch( msg )
	{
/*
	case WM_MOUSEMOVE:
		{	//	ウィンドウ外に出ると値が検出できないのでアウト
			m_Position[0] = LOWORD( lParam ); 
			m_Position[1] = HIWORD( lParam ); 
		}break;
*/
/*
	case WM_LBUTTONDOWN:
	case WM_RBUTTONDOWN:
	case WM_MBUTTONDOWN:
	case WM_LBUTTONUP:	
	case WM_RBUTTONUP:	
	case WM_MBUTTONUP:
		{
			m_IsDown[0] = IsFlag(wParam,MK_LBUTTON); 
			m_IsDown[1] = IsFlag(wParam,MK_RBUTTON); 
			m_IsDown[2] = IsFlag(wParam,MK_MBUTTON); 
		} break;
*/
	case WM_MBUTTONDOWN:
	case WM_MBUTTONUP:
		{
			m_IsDown[2] = IsFlag(wParam,MK_MBUTTON); 
		} break;

	case WM_MOUSEWHEEL:
		{
			m_Position[2] += (short)HIWORD( wParam );
		}break;
	}

	return IMessageHook::RETURNCODE_CONTINUE;
}

}