// MainFrm.h : interface of the CMainFrame class
//
/////////////////////////////////////////////////////////////////////////////

#pragma once

#include "aboutdlg.h"

class CMainFrame;       // forward declaration

typedef CWinTraits<VRWS_WINDOWED, WS_EX_APPWINDOW>    CMainWinTraits;
typedef CFrameWindowImpl<CMainFrame, CWindow, CMainWinTraits>   CMainFrameBase;


class CMainFrame 
    : public CMainFrameBase
    , public CMessageFilter
    , public CIdleHandler
{
public:
    DECLARE_FRAME_WND_CLASS_EX(_T("VR:Window_class"), IDR_MAINFRAME, CS_OWNDC|CS_DBLCLKS, COLOR_WINDOW)

    virtual BOOL PreTranslateMessage(MSG* pMsg)
    {
        return CMainFrameBase::PreTranslateMessage(pMsg);
    }

    virtual BOOL OnIdle()
    {
        // @KLUDGE: km - just for test purposes
        /*
        static int cnt = 0;
        if (0 == (++cnt)%100)
            ATLTRACE(_T("[%08d] CMainFrame::OnIdle()\n"), cnt);
        */
        return TRUE;
    }

    BEGIN_MSG_MAP(CMainFrame)
        MESSAGE_HANDLER(WM_CREATE, OnCreate)
        MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
        //MESSAGE_HANDLER(WM_ACTIVATE, OnActivate)
        MESSAGE_HANDLER(WM_ACTIVATE, OnActivateApp) // @KLUDGE:  report this to module
        MESSAGE_HANDLER(WM_ACTIVATEAPP, OnActivateApp)
        MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
        COMMAND_ID_HANDLER(ID_APP_EXIT, OnAppExit)
        COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
        CHAIN_MSG_MAP(CMainFrameBase)
    END_MSG_MAP()


    LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
    {

        // register object for message filtering and idle updates
        CMessageLoop* pLoop = _Module.GetMessageLoop();
        ATLASSERT(pLoop != NULL);
        pLoop->AddMessageFilter(this);
        pLoop->AddIdleHandler(this);

        return 0;
    }

    LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
    {
        ::PostQuitMessage(0);
        return 0;
    }

    LRESULT OnActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
    {
        ATLTRACE(_T("CMainFrame::OnActivate()\n"));

        // Enter idle when active and non-minimized
        if (WA_INACTIVE != LOWORD(wParam) && 0 == HIWORD(wParam))
            ::SetClassLong( m_hWnd, GCL_HCURSOR
                          , (LONG)::LoadCursor(_Module.GetResourceInstance()
                          , MAKEINTRESOURCE(GetWndClassInfo().m_uCommonResourceID)));
        else
            ::SetClassLong( m_hWnd, GCL_HCURSOR, (LONG)::LoadCursor(NULL, IDC_ARROW));
    
        bHandled = FALSE; // leave it for Application message filter.

        return 0;
    }

	LRESULT OnActivateApp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL&)
	{
        _Module.ProcessMessage(uMsg, wParam, lParam);
        
		return 0;
	}
    
    LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
    {
#if 1
        bHandled = true;
        return 1;   // @TRICKY: we don't handle this, but claim we do.
#else
        bHandled = false;
        return 0;
#endif
    }

    LRESULT OnAppExit(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
    {
        PostMessage(WM_CLOSE);
        return 0;
    }

    LRESULT OnAppAbout(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
    {
        CAboutDlg dlg(false);
        dlg.DoModal();
        return 0;
    }
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

