//=========================================================================
// CPAFrame.cpp : implementation of the CPA_MainFrame class
// This is a part of the CPA project.
//
// Version                      1.0
// Creation date        06/06/96
// Revision date
//
// (c) Ubi Studios 1996
//
// DO NOT MODIFY THAT FILE. IF SOMETHING NEEDS TO BE CHANGE, PLEASE CONTACT 
// VINCENT GRECO OR CHRISTOPHE BEAUDET.
//=========================================================================

#include "stdafx.h"
#include "acp_base.h"

#include <pbt.h>

#include "direct.h"
#include "Itf/CPARes.h"
#include "errint.h"
#include "mmgint.h"
#include "Itf/DEVViewp.hpp"
#include "Itf/DEVMul3D.hpp"
#include "Itf/CPAFrame.hpp"
#include "Itf/CPAProj.hpp"
#include "Itf/CPAConst.hpp"
#include "Itf/A3dkeyal.hpp"
#include "Itf/cpamworl.hpp"
#include "Itf/camdllb.hpp"
#include "Itf/CPAInter.hpp"
#include "incgam.h"

/////////////////////////////////////////////////////////////////////////////
// CPA_MainFrame

    #define M_BaseClass CFrameWnd

IMPLEMENT_DYNCREATE(CPA_MainFrame, M_BaseClass)
BEGIN_MESSAGE_MAP(CPA_MainFrame, M_BaseClass)

//{{AFX_MSG_MAP(CPA_MainFrame)
	ON_MESSAGE(WM_POWERBROADCAST, m_lOnPowerManagement)
	ON_MESSAGE(WM_DISPLAYCHANGE, OnDisplayChange)
    ON_WM_CREATE()
    ON_WM_CLOSE()
    ON_WM_ACTIVATEAPP()
    ON_WM_ACTIVATE()
    ON_WM_SYSCOMMAND()
    ON_WM_SIZE()
    ON_WM_GETMINMAXINFO()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPA_MainFrame construction/destruction

CPA_MainFrame::CPA_MainFrame()
{
}

CPA_MainFrame::~CPA_MainFrame()
{
}


LRESULT CPA_MainFrame::OnDisplayChange(UINT wParam, LONG lParam)
{
    HDC             hdc;
    int             iAppBPP;

    hdc = ::GetDC(NULL);
    iAppBPP = ::GetDeviceCaps(hdc, PLANES);
    iAppBPP *= wParam;
    ::ReleaseDC(NULL, hdc);

	M_GetMainApp()->m_bBadResolution = FALSE;
	if(iAppBPP != 16)
		M_GetMainApp()->m_bBadResolution = TRUE;

	if(M_GetMainApp()->m_bBadResolution)
	{
		if(!M_GetMainDevice()->GetDevice(0)->IsFullScreen())
		{
			if(!IsIconic())
				SendMessage(WM_SYSCOMMAND, SC_MINIMIZE);
//			else
//				M_GetMainApp()->m_bWasInFullScreenBeforeLooseFocus = TRUE;
		}
	}
	return 0;
}

//###########################################################################
// POWER MANAGEMENT AND SCREEN SAVER
//###########################################################################

// handled WM_POWERBROADCAST
LRESULT CPA_MainFrame::m_lOnPowerManagement(UINT wParam, LONG lParam)
{
	switch ( lParam ) 
	{
	case PBT_APMQUERYSUSPEND: //when system asks apps if they accept to enter low-power mode
	case PBT_APMQUERYSTANDBY:
		return TRUE; //return BROADCAST_QUERY_DENY for refusal to enter low-power mode

	case PBT_APMSTANDBY: //received when all apps granted low-power mode, right before low-power mode is activated
	case PBT_APMSUSPEND:  //these 2 may me received before the two others if some app forces the mode
		if ( !M_GetMainApp()->m_bEngineIsStopped )
		{
			M_GetMainApp()->fn_vStopEngine();
			// if we are in fullscreen, then swap to windowed
			// and tell we were in full screen
			M_GetMainApp()->BeforeWindows();
			if (M_GetMainDevice()->GetDevice(0)->IsFullScreen())
			{
				M_GetMainDevice()->GetDevice(0)->SwapFullScreen();
				if (GLI_lWhatIsGLI() == GLI_C_VersionGlide)
				{
					M_GetMainApp()->m_bWasInFullScreenBeforeLooseFocus = TRUE;
				}
				SendMessage(WM_SYSCOMMAND, SC_MINIMIZE);
			}
			M_GetMainApp()->AfterWindows();

		}
		return TRUE; //accept entry into low-power mode

	case PBT_APMRESUMESUSPEND: //when resuming from low-power mode to normal operation
	case PBT_APMRESUMESTANDBY: //when resuming from low-power mode to normal operation
	case PBT_APMRESUMECRITICAL: //received when power is enough to proceed with normal operations
		OnActivateApp(TRUE, NULL);
		return FALSE;

	case PBT_APMQUERYSUSPENDFAILED: //when an app denied request, others receive this message
	case PBT_APMQUERYSTANDBYFAILED: //when an app denied request, others receive this message
	case PBT_APMPOWERSTATUSCHANGE: //when power supply change is detected (batt<->mains/low, etc...)
	case PBT_APMOEMEVENT: //when bios sends an OEM APM change
	case PBT_APMBATTERYLOW: //when battery is running low
		return FALSE; //return value is irrelevant
	// PBTF_APMRESUMEFROMFAILURE ? 
	}
	return BROADCAST_QUERY_DENY; //any other case is not known, so prevent power management just in case
}

void CPA_MainFrame::OnSysCommand(UINT nID, LPARAM lParam) //handles WM_SYSCOMMAND message
{
	UINT uiTrueNID = nID & 0xFFFFFFF0;

	M_GetMainApp()->BeforeWindows();
	switch ( uiTrueNID )
	{
	case SC_MONITORPOWER:
	case SC_SCREENSAVE: // screensaver
		if (GLI_lWhatIsGLI() == GLI_C_VersionGlide)
		{
			if (M_GetMainDevice()->GetDevice(0)->IsFullScreen() )
			{
				M_GetMainDevice()->GetDevice(0)->SwapFullScreen();
				M_GetMainApp()->m_bWasInFullScreenBeforeLooseFocus = TRUE;
				SendMessage(WM_SYSCOMMAND, SC_MINIMIZE);
			}
			M_GetMainApp()->fn_vAppliAskToStopEngine();
		}
		else
		{
			CFrameWnd::OnSysCommand(nID, lParam);
		}
		break;

	case SC_MINIMIZE:
		if (GLI_lWhatIsGLI() != GLI_C_VersionGlide)
		{
			CFrameWnd::OnSysCommand(nID, lParam);
			M_GetMainDevice()->GetDevice(0)->SwapFullScreen();
		}
		break;

	case SC_MAXIMIZE:
		if (GLI_lWhatIsGLI() != GLI_C_VersionGlide)
		{
			M_GetMainWnd()->SendMessage(WM_SYSCOMMAND, SC_RESTORE);
		}
		break;

	case SC_RESTORE:
		if (GLI_lWhatIsGLI() != GLI_C_VersionGlide)
		{
			CFrameWnd::OnSysCommand(nID, lParam);
			M_GetMainDevice()->GetDevice(0)->SwapFullScreen();
		}
		break;

	default:
		if (GLI_lWhatIsGLI() != GLI_C_VersionGlide)
		{
			CFrameWnd::OnSysCommand(nID, lParam);
		}
	}

	if (GLI_lWhatIsGLI() == GLI_C_VersionGlide)
	{
		CFrameWnd::OnSysCommand(nID, lParam);
	}
	M_GetMainApp()->AfterWindows();
}


void CPA_MainFrame::OnSize(UINT nType, int cx, int cy)
{
	if (GLI_lWhatIsGLI() != GLI_C_VersionGlide)
	{
		M_GetMainApp()->BeforeWindows();
		CFrameWnd::OnSize(nType, cx, cy);
		M_GetMainApp()->AfterWindows();
	}
	else
	{
		if((M_GetMainApp()->m_p_oEngineThread) && (M_GetMainApp()->m_bEngineIsStopped == FALSE))
			WaitForSingleObject(M_GetMainApp()->m_hDrawSem, INFINITE);
		CFrameWnd::OnSize(nType, cx, cy);
		if((M_GetMainApp()->m_p_oEngineThread) && (M_GetMainApp()->m_bEngineIsStopped == FALSE))
			ReleaseSemaphore(M_GetMainApp()->m_hDrawSem, 1, NULL);
	}
}


void CPA_MainFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
    CSize   sizeScreen(GetSystemMetrics(SM_CXMAXIMIZED), GetSystemMetrics(SM_CYMAXIMIZED));

    lpMMI->ptMinTrackSize.x = 50;
    lpMMI->ptMinTrackSize.y = 50;
    lpMMI->ptMaxTrackSize.x = sizeScreen.cx;
    lpMMI->ptMaxTrackSize.y = sizeScreen.cy;
}

//===========================================================================
//      Description:    That function is called by MFC to update main frame title.
//                      We put project title and actual version of project.     
//      Creation date:  06 Jun 96
//      Author:         CB
//---------------------------------------------------------------------------
//      BOOL            Not used
//      Return void
//---------------------------------------------------------------------------
//      Revision date:                                                                                          
//      Author:         
//===========================================================================
void CPA_MainFrame::OnUpdateFrameTitle(BOOL)
{
    M_GetMainApp()->fn_vUpdateFrameTitle();
	::SetWindowText(m_hWnd, (LPCTSTR) m_szProjectName);
}




void CPA_MainFrame::OnActivate( UINT nState, CWnd* pWndOther, BOOL bMinimized )
{
	long l;
	static BOOL s_bPreventNestedCalls = FALSE;
	static BOOL s_bActive = FALSE;

  Erm_fn_v_PrintErrMsgWithPersonalMsg("ITF - CpaFrame_eng", "on_Activate", "***********************");

	if (nState == WA_ACTIVE || nState == WA_CLICKACTIVE)
	{
		l = 5;
		l++;
	}
	CFrameWnd::OnActivate(nState,pWndOther,bMinimized);
  			
}




//===========================================================================
//      Description:    Call when application is activate or desactivate.
//      Creation date:  24 Jun 96
//      Author:         CB
//---------------------------------------------------------------------------
//      bActive         Application is activated or not ?
//      Return void
//---------------------------------------------------------------------------
//      Revision date:                                                                                          
//      Author:         
//===========================================================================
void CPA_MainFrame::OnActivateApp(BOOL bActive, DWORD)
{
	static BOOL s_bPreventNestedCalls = FALSE;
	static BOOL s_bActive = FALSE;


	if (GLI_lWhatIsGLI() != GLI_C_VersionGlide)
	{
		
		
		Erm_fn_v_PrintErrMsgWithPersonalMsg("ITF - CpaFrame_eng", "on_ActivateApp", "***********************");
		if ( s_bPreventNestedCalls )
			return;
		s_bPreventNestedCalls = TRUE;
		
		if(bActive)
		{
			Erm_fn_v_PrintErrMsgWithPersonalMsg("ITF - CpaFrame_eng", "on_ActivateApp", "*********TRUE**************");
			if (s_bActive)
			{
				s_bPreventNestedCalls = FALSE;
				return;
			}
			
			s_bActive = TRUE;
			M_GetMainApp()->BeforeWindows();
			// Change priority level of main process
			// Warning ! HIGH_PRIORITY_CLASS = same level as windows task manager. So if
			// appli crash, it may causes somes problems.
			//		SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
			
			// if we are not in editor mode, check if we were in fullscreen before leaving
			// and resume then engine
			
			if (M_GetMainApp()->m_p_oEngineThread)
			{
				
				//				if((M_GetMainApp()->m_bWasInFullScreenBeforeLooseFocus) || (M_GetMainApp()->m_bBadResolution))
				//				{
				//					M_GetMainApp()->m_bWasInFullScreenBeforeLooseFocus = FALSE;
				if (GLI_lWhatIsGLI() == GLI_C_VersionGlide)
				{
					if ((M_GetMainDevice()->GetDevice(0)->IsFullScreen() == FALSE))
					{
						M_GetMainDevice()->GetDevice(0)->SwapFullScreen();
					}
				}
				
				
				if ((M_GetMainWnd()->IsIconic()))
				{
					M_GetMainWnd()->SendMessage(WM_SYSCOMMAND, SC_RESTORE);
				}
			}
			M_GetMainApp()->m_bAppliAskedToStopEngine = FALSE;
			M_GetMainApp()->fn_vRestartEngine();
			
			// Call a virtual method for a real project
			M_GetMainApp()->fn_vWhenAppGainFocus();
			M_GetMainApp()->AfterWindows();
			M_GetMainApp()->AfterWindows();
		}
		else
		{
			Erm_fn_v_PrintErrMsgWithPersonalMsg("ITF - CpaFrame_eng", "on_ActivateApp", "*********FALSE**************");
			if (!s_bActive)
			{
				s_bPreventNestedCalls = FALSE;
				return;
			}
			
			s_bActive = FALSE;
			
			M_GetMainApp()->BeforeWindows();
			
			if (M_GetMainApp()->m_bProjectIsClosing == 0)
			{
				if (M_GetMainApp()->m_bLeavingApplication == FALSE)
				{
					// Suspend engine thread
					M_GetMainApp()->fn_vAppliAskToStopEngine();
					M_GetMainApp()->BeforeWindows();
					
					if (!(M_GetMainWnd()->IsIconic()))
					{
						SendMessage(WM_SYSCOMMAND, SC_MINIMIZE);
					}
					
					// Restore a normal priority for actual process
					//			SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
					
					// Call a virtual method for a real project
					M_GetMainApp()->fn_vWhenAppLooseFocus();
				}
			}
			M_GetMainApp()->AfterWindows();
		}
		s_bPreventNestedCalls = FALSE;
	}
	else
	{
		if ( s_bPreventNestedCalls )
			return;
		s_bPreventNestedCalls = TRUE;
		
		if(bActive)
		{
			// Change priority level of main process
			// Warning ! HIGH_PRIORITY_CLASS = same level as windows task manager. So if
			// appli crash, it may causes somes problems.
			//		SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
			
			// if we are not in editor mode, check if we were in fullscreen before leaving
			// and resume then engine
			
			if (M_GetMainApp()->m_bWasInFullScreenBeforeLooseFocus)
			{
				M_GetMainApp()->m_bWasInFullScreenBeforeLooseFocus = FALSE;
				if (M_GetMainDevice()->GetDevice(0)->IsFullScreen() == FALSE)
				{
					if(M_GetMainWnd()->IsIconic())
						M_GetMainWnd()->SendMessage(WM_SYSCOMMAND, SC_RESTORE);
					M_GetMainDevice()->GetDevice(0)->SwapFullScreen();
				}
			}
			M_GetMainApp()->m_bAppliAskedToStopEngine = FALSE;
			M_GetMainApp()->fn_vRestartEngine();
			
			
			// Call a virtual method for a real project
			M_GetMainApp()->fn_vWhenAppGainFocus();
		}
		else
		{
			
			if (M_GetMainApp()->m_bProjectIsClosing == 0)
			{
				if (M_GetMainApp()->m_bLeavingApplication == FALSE)
				{
					
					// Suspend engine thread
					M_GetMainApp()->fn_vAppliAskToStopEngine();
					
					//if we were in full screen, it might be because the screen saver was activated...			
					if (M_GetMainDevice()->GetDevice(0)->IsFullScreen())
					{
						M_GetMainDevice()->GetDevice(0)->SwapFullScreen();
						M_GetMainApp()->m_bWasInFullScreenBeforeLooseFocus = TRUE;
						SendMessage(WM_SYSCOMMAND, SC_MINIMIZE);
					}
					// Restore a normal priority for actual process
					//			SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
					
					// Call a virtual method for a real project
					M_GetMainApp()->fn_vWhenAppLooseFocus();
				}
			}
		}
		s_bPreventNestedCalls = FALSE;
	}
}	


//===========================================================================
//      Description:    Call to close main frame.
//                      In editor mode, we ask all editors to close. Editors can
//                      say NO to not close application !
//                      Else we force second thread to close.
//      Creation date:  20 Jun 96
//      Author:         CB
//---------------------------------------------------------------------------
//      Return void
//---------------------------------------------------------------------------
//      Revision date:                                                                                          
//      Author:         
//===========================================================================
void CPA_MainFrame::OnClose(void)
{
	// if the engine has finished its closing process, the perform the onclose
	if (M_GetMainApp()->m_bEngineIsOver == FALSE)
	{
		
		
		// We are in full screen ?
  		if(M_GetMainDevice()->GetDevice(0)->IsFullScreen())
  			M_GetMainDevice()->GetDevice(0)->SwapFullScreen();
 		
		// We indicate that project is closing
		M_GetMainApp()->m_bProjectIsClosing = 1;
		M_GetMainApp()->m_bLeavingApplication = 1;
		
		// Force engine thread to close.
		// we ask engine thread to begin the closing process
		M_GetMainApp()->fn_vAppliAskToEndGame();
	}
	else
	{
	// We close window
	CFrameWnd::OnClose();
	}
}

//===========================================================================
//      Description:    Call to create main frame.
//                      In editor mode, we create toolbar and menus.
//      Creation date:  06 Jun 96
//      Author:         CB
//---------------------------------------------------------------------------
//      Return void
//---------------------------------------------------------------------------
//      Revision date:                                                                                          
//      Author:         
//===========================================================================
int CPA_MainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (M_BaseClass::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	SetMenu(NULL);  // No menu at this point of program
	return 0;
}

//###########################################################################
// RESPONSE TO EDIT INTERFACE MESSAGES
//###########################################################################


