#include "mof/Window.hpp"
#include "mof/InputDevice.hpp"
#include "mof/ConsoleIO.hpp"
#include <stdexcept>

LRESULT WINAPI wndProc( HWND hWnd , UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg)
	{
		case WM_ACTIVATEAPP:
			if(LOWORD(wParam) == 0)
			{
			/*	*ConsoleOut::getInstance() << "Windowが非アクティブになりました" << std::endl;
				mof::System::getInstance()->activate(false);
				mof::InputDevice::getInstance()->activate(false);*/
				mof::InputDevice::setActivation(false);
			}
			else 
			{
			/*	*ConsoleOut::getInstance() << "Windowがアクティブになりました" << std::endl;
				mof::System::getInstance()->activate(true);
				mof::InputDevice::getInstance()->activate(true);*/
				mof::InputDevice::setActivation(true);
			}
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		case WM_SETCURSOR:
			SetCursor(NULL);
			break;
	}
	
	return DefWindowProc( hWnd, msg, wParam, lParam );
}




namespace mof
{
    
    struct Window::Impl
    {
    	mof::tstring appName;
    	HINSTANCE hInstance;
    	HWND hWindow;
	
    	Impl(const mof::tstring& appname , HINSTANCE hInstance );
    };

    Window::Impl::Impl(const mof::tstring &appname, HINSTANCE hInstance )
    : appName( appname ) , hInstance( hInstance ) , hWindow( NULL )
    {
	    // do nothing
    }   

    Window::Window( const mof::tstring &appname , int width , int height , bool fullscreen )
    : m_pImpl( new mof::Window::Impl( appname , GetModuleHandle(NULL) ) )
    {

	    // ウィンドウクラス設定
        WNDCLASSEX wc = 
            { 
                sizeof(WNDCLASSEX), CS_CLASSDC, wndProc, 0L, 0L, 
                m_pImpl->hInstance , NULL, NULL, NULL, NULL,
                m_pImpl->appName.c_str()  , NULL
            };
        RegisterClassEx( &wc );

	    // ウィンドウ生成
	    if( !fullscreen )
	    {
	    	// 指定されたクライアント領域を確保するために必要なウィンドウサイズを得る
	    	RECT rect_win;
	    	SetRect( &rect_win , 0 , 0 , width , height );
	    	AdjustWindowRect( &rect_win , WS_OVERLAPPEDWINDOW , false );
            
	    	//Windowモード
	        m_pImpl->hWindow = 
	            CreateWindow
	            ( 
	                 m_pImpl->appName.c_str() , m_pImpl->appName.c_str() , 
	                 WS_OVERLAPPEDWINDOW , CW_USEDEFAULT, CW_USEDEFAULT, (rect_win.right - rect_win.left) ,
	                 (rect_win.bottom - rect_win.top) , GetDesktopWindow() , NULL , wc.hInstance , NULL
	            );
	    }
    	else
    	{
		    //フルスクリーン
		    m_pImpl->hWindow = 
		        CreateWindow
		        (
		            m_pImpl->appName.c_str() , m_pImpl->appName.c_str() , 
		    	    WS_VISIBLE , CW_USEDEFAULT , CW_USEDEFAULT , width , height ,
		        	HWND_DESKTOP , NULL , wc.hInstance , NULL
		        );
	    }
	
	 
	    // ウィンドウ描画
        ShowWindow( m_pImpl->hWindow , SW_SHOWDEFAULT );
        UpdateWindow( m_pImpl->hWindow );


    } // function constructor 



    Window::~Window( )
    {
	    try
	    {
	    	
	    	//例外なげる？
	    	UnregisterClass(m_pImpl->appName.c_str() , m_pImpl->hInstance );
	    }
	    catch(...)
	    {
	    }
	
    }
    
    HWND Window::getHandler() const {
        return m_pImpl->hWindow;
    }

} // namespace mof