/*=========================================================================
 * DEVDevic.cpp :       Implementation of device.
 * This is a part of the CPA project.
 *
 * Version              1.0
 * Creation date        26/06/96
 * Revision date
 *
 *
 * (c) Ubi Studios 1996
 *=======================================================================*/

#include "stdafx.h"
#include "acp_base.h"
#include "geo.h"
#include "gli.h"
#include "col.h"
#define HieFriend
#include "spo.h"
#include "main.h"
#include "lst.hpp"

#include "itf/CPARes.h"
#include "itf/DEVDevic.hpp"
#include "itf/DEVVp3D.hpp"
#include "itf/DEVVp2D.hpp"
#include "itf/DEVMulti.hpp"
#include "itf/DEVMul3D.hpp"
#include "itf/CPAProj.hpp"
#include "itf/cpamworl.hpp"
#include "itf/StdDLLId.h"
#include "itf/camdllb.hpp"
#include "itf/CPAConst.hpp"

// type of Device.
#define DEV_NORMAL      0
#define DEV_BACKGROUND  1

BEGIN_MESSAGE_MAP(DEV_Device, CWnd)
//{{AFX_MSG_MAP(DEV_Device)
	ON_WM_DESTROY()
	ON_WM_SIZE()
	ON_WM_MOUSEACTIVATE()
	ON_WM_CREATE()
	ON_WM_WINDOWPOSCHANGING()
	ON_WM_WINDOWPOSCHANGED()
	ON_WM_PAINT()
    ON_WM_NCACTIVATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//================================================================================
//================================================================================
DEV_Device::DEV_Device()
{
}

DEV_Device::~DEV_Device()
{
}

#ifndef ACTIVE_EDITOR
CFrameWnd *DEV_Device::GetParentFrame()
{
	return GetParentMultiDevice()->GetParentFrame();
}
#endif


//================================================================================
//================================================================================
// return the number of Device
int DEV_Device::GetNumber()
{
    return 0;
}

//================================================================================
//================================================================================
// Return the Camera if this is a device 3D else return NULL.
GLI_tdxHandleToCamera DEV_Device::GetCamera()
{
    if (mViewType == C_DEVICE3D)
        return ((DEV_ViewPort3D *)mpViewPort)->GetEngineCamera();
    else return NULL;
}


//================================================================================
//================================================================================
// creation of a background Device
// first Device created
void DEV_Device::CreateDeviceBackground(void * device, UINT ViewType)
{
	CRect stRect;
    m_p_oWndParent = (CWnd*)device;


    mType = DEV_BACKGROUND; // definition of type
    mViewType = ViewType;

    GetParentMultiDevice()->GetClientRect(&stRect);
    Create(NULL, (LPCTSTR) "",
		WS_OVERLAPPED | WS_CLIPSIBLINGS | WS_VISIBLE | WS_CHILD | WS_MAXIMIZE,
        stRect, m_p_oWndParent, 1);

    // positioning of Device in rear plan
    if (GLI_lWhatIsGLI() == GLI_C_VersionGlide)
	    SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);


}

//================================================================================
//================================================================================
void DEV_Device::OnDestroy()
{
	if (WaitForSingleObject(M_GetMainApp()->m_hDrawSem,10000) == WAIT_TIMEOUT)
		ASSERT(0);
    CWnd::OnDestroy();

    // Destroy the DisplayViewport.
    // fn_bDeleteViewport3D(mDisplayDevice3D, mViewPort.GetDisplayViewport3D());

	GLD_bReleaseViewportAndDevice(m_hDisplayDevice,mpViewPort->m_hDisplayViewport);

    mpViewPort->SendMessage(WM_DESTROY);
	delete(mpViewPort);


    ReleaseSemaphore(M_GetMainApp()->m_hDrawSem, 1, NULL);

}

//================================================================================
//================================================================================

//================================================================================
//================================================================================
void DEV_Device::OnSize(UINT type, int cx, int cy)
{
    RECT r;

    if (GLI_lWhatIsGLI() == GLI_C_VersionGlide)
	{
		if (!IsFreezed())
		{
			CWnd::OnSize(type, cx, cy);
			if (!IsFullScreen())
			{
				
				if (!GLD_bAdjustDeviceToWindow(m_hDisplayDevice))
				{
					ASSERT(0);
				}
				
			}
			
			// Adjust the camera to the new size of the viewport (device)
			if((mViewType == C_DEVICE3D) && (((DEV_ViewPort3D *) mpViewPort)->GetEngineCamera()))
				GLI_xAdjustCameraToViewport
				(
                m_hDisplayDevice, mpViewPort->m_hDisplayViewport, 
				((DEV_ViewPort3D *) mpViewPort)->GetEngineCamera() 
				);
			
					GAMITF_fn_vResizeGameViewport();
			
			
			CWnd::GetClientRect(&r);
			mpViewPort->SetWindowPos(&wndTopMost,r.left,r.top,r.right,r.bottom, SWP_NOZORDER | SWP_SHOWWINDOW);
		}
	}
}

//================================================================================
//  When device gains the focus, it must say it to the contact (and so to one or
//  more editor) to update viewport modes.
//================================================================================
BOOL DEV_Device::OnNcActivate(BOOL)
{
    OnNcPaint();
    return FALSE;
}

//================================================================================
//================================================================================
int DEV_Device::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
{
    int iRes = CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
    return iRes;
}

#ifndef ACTIVE_EDITOR


void DEV_Device::PostCreate()
{
    GLD_tdstDeviceAttributes stDeviceAttr;

    // Create the DisplayDevice.
    if (GLI_lWhatIsGLI() != GLI_C_VersionGlide)
    {
        //VL0
		//stDeviceAttr.bFullScreen = TRUE;
		//mbFullScreen = TRUE;
        stDeviceAttr.bFullScreen = mbFullScreen = MAIN_fn_ulDeviceIsFullScreen();
        //EVL0
		stDeviceAttr.dwFullScreenModeX = MAIN_fn_ulGetDeviceWidth();
		stDeviceAttr.dwFullScreenModeY = MAIN_fn_ulGetDeviceHeight();
		stDeviceAttr.dwFullScreenModeBpp = 16;
		stDeviceAttr.hFullScreenModeWnd = M_GetMainWnd()->GetSafeHwnd();
		stDeviceAttr.hNormalModeWnd = CWnd::GetSafeHwnd();
		stDeviceAttr.uiTypeDriver = C_DRIVER_SOFT | C_DRIVER_RGB; // marc : moteur D3D
		if (!GLD_bCreateDevice(&stDeviceAttr, &m_hDisplayDevice))
		{
			ASSERT(0);
			//		M_GetMainApp()->fn_vDynaFatalError(GLD_szGetLastErrorString());
		}
		
		// Create the Viewport.
/*		if (mViewType == C_DEVICE3D)
		{
*/			mpViewPort = new(DEV_ViewPort3D);
			((DEV_ViewPort3D *)mpViewPort)->CreateViewPort(this, m_hDisplayDevice);
/*		}
		else
		{
			mpViewPort = new(DEV_ViewPort2D);
			((DEV_ViewPort2D *)mpViewPort)->CreateViewPort(this, m_hDisplayDevice);
		}
*/		SetBackgroundColor(0, 0, 0);
		
		//	M_GetMainWnd->OnActivateApp(TRUE,NULL);
	}
}

#endif

//================================================================================
//================================================================================
int DEV_Device::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    GLD_tdstDeviceAttributes stDeviceAttr;

    if (GLI_lWhatIsGLI() == GLI_C_VersionGlide)
    {
		
		if (CWnd::OnCreate(lpCreateStruct) == -1)
			return -1;
		
		// Create the DisplayDevice.
        //VL0
		//stDeviceAttr.bFullScreen = FALSE;
		//mbFullScreen = FALSE;
        stDeviceAttr.bFullScreen = mbFullScreen = MAIN_fn_ulDeviceIsFullScreen();
        //EVL
		stDeviceAttr.dwFullScreenModeX = MAIN_fn_ulGetDeviceWidth();
		stDeviceAttr.dwFullScreenModeY = MAIN_fn_ulGetDeviceHeight();
		stDeviceAttr.dwFullScreenModeBpp = 16;
		stDeviceAttr.hFullScreenModeWnd = M_GetMainWnd()->GetSafeHwnd();
		stDeviceAttr.hNormalModeWnd = CWnd::GetSafeHwnd();
		stDeviceAttr.uiTypeDriver = C_DRIVER_SOFT | C_DRIVER_RGB; // marc : moteur D3D
		if (!GLD_bCreateDevice(&stDeviceAttr, &m_hDisplayDevice))
		{
			ASSERT(0);
			//		M_GetMainApp()->fn_vDynaFatalError(GLD_szGetLastErrorString());
		}
		
		// Create the Viewport.
/*		if (mViewType == C_DEVICE3D)
		{
*/			mpViewPort = new(DEV_ViewPort3D);
			((DEV_ViewPort3D *)mpViewPort)->CreateViewPort(this, m_hDisplayDevice);
/*		}
		else
		{
			mpViewPort = new(DEV_ViewPort2D);
			((DEV_ViewPort2D *)mpViewPort)->CreateViewPort(this, m_hDisplayDevice);
		}
*/		Unfreeze();
		SetBackgroundColor(0, 0, 0);
	}
	else
	{
		return CWnd::OnCreate(lpCreateStruct);
	}
	return 0;
}

//================================================================================
//================================================================================
void DEV_Device::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
    CWnd::OnWindowPosChanging(lpwndpos);

    if(mType == DEV_BACKGROUND)
    {
		lpwndpos->flags |= SWP_NOZORDER | SWP_NOMOVE;
    }
}

//================================================================================
//================================================================================
void DEV_Device::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos)
{
    RECT r;

    CWnd::OnWindowPosChanged(lpwndpos);

    if (GLI_lWhatIsGLI() == GLI_C_VersionGlide)
	{
	    GetClientRect(&r);
	    mpViewPort->SetWindowPos(&wndTopMost,r.left,r.top,r.right-r.left,r.bottom-r.top,0);
	}
}



//================================================================================
//================================================================================
void DEV_Device::SetBackgroundColor(COLORREF Color)
{
    mRed = GetRValue(Color);
    mGreen = GetGValue(Color);
    mBlue = GetBValue(Color);
    GLD_bSetBackgroundColorForDevice(m_hDisplayDevice, Color);
    CWnd::SendMessage(WM_PAINT);
}

//================================================================================
//================================================================================
void DEV_Device::SetBackgroundColor(char Red, char Green, char Blue)
{
    mRed = Red;
    mGreen = Green;
    mBlue = Blue;
    SetBackgroundColor(RGB(Red, Green, Blue));
}

//================================================================================
//================================================================================
void DEV_Device::GetBackgroundColor(char *Red, char *Green, char *Blue)
{
    *Red = mRed;
    *Green = mGreen;
    *Blue = mBlue;
}

//================================================================================
//================================================================================
void DEV_Device::OnPaint()
{
    CWnd::OnPaint();
}


//================================================================================
//================================================================================
BOOL DEV_Device::SwapFullScreen(BOOL)
{
	/*
    if (GLI_lWhatIsGLI() != GLI_C_VersionGlide)
	{
		if (!IsFullScreen())
		{
			//save the new pos for when we come back from fullscreen
			M_GetMainWnd()->GetWindowRect(m_stRectWhileFullscreen);
		}
		
		
		SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
		
		M_GetMainApp()->m_bFlagTaken = TRUE;
			GAMITF_fn_vResizeGameViewport();
		
		if (!mbFullScreen)
		{
			if (!GLD_bSwapDeviceMode(m_hDisplayDevice))
			{
				ASSERT(0);
				return FALSE;
			}
			mbFullScreen = TRUE;
		}
		else
		{
			mbFullScreen = FALSE;
		}
		
		//--------------------------------------------------------
		M_GetMainApp()->m_bFlagTaken = FALSE;
		
		SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
		
#ifdef NDEBUG
		if (mbFullScreen == TRUE)
		{
			RECT stRect,stRect2;
			
			M_GetMainWnd()->GetWindowRect(&stRect2);
			stRect.left = stRect2.left + 10;
			stRect.top = stRect2.top + 10;
			stRect.right = stRect2.left + 10;
			stRect.bottom = stRect2.top + 10;
			
			// we are in fullscreen
			// confine cursor in the window
			ClipCursor(&stRect);
			// hide cursor
			while (ShowCursor(FALSE) >= 0);
		}
		else
		{
			// we are not in fullscreen
			// free cursor 
			ClipCursor(NULL);
			// show cursor
			while (ShowCursor(TRUE) < 0);
		}
		
#endif
		
		return TRUE;
	}
	else
    */
	{
		if (!IsFullScreen())
		{
			//save the new pos for when we come back from fullscreen
			M_GetMainWnd()->GetWindowRect(m_stRectWhileFullscreen);
			//M_GetMainWnd()->ShowWindow(FALSE);
		}
		
		SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
		
		WaitForSingleObject(M_GetMainApp()->m_hDrawSem, INFINITE);
		M_GetMainApp()->m_bFlagTaken = TRUE;
		//--------------------------------------------------------
		// Freeze all devices
		GetParentMultiDevice()->FreezeAll();
		
		
		if (!GLD_bSetFullScreenModeForDevice(m_hDisplayDevice, MAIN_fn_ulGetDeviceWidth(),MAIN_fn_ulGetDeviceHeight() , 16, M_GetMainWnd()->GetSafeHwnd()))
		{
			ASSERT(0);
		}
		
		if (!GLD_bSwapDeviceMode(m_hDisplayDevice, TRUE))
		{
			ASSERT(0);
		}
		
		if(((DEV_ViewPort3D *) mpViewPort)->GetEngineCamera())
			GLI_xAdjustCameraToViewport(m_hDisplayDevice, mpViewPort->m_hDisplayViewport, ((DEV_ViewPort3D *) mpViewPort)->GetEngineCamera());
		
			GAMITF_fn_vResizeGameViewport();
		
		if (!mbFullScreen)
		{
			mbFullScreen = TRUE;
			GetParentMultiDevice()->FreezeAllButOne(0);
		}
		else
		{
			mbFullScreen = FALSE;
			GetParentMultiDevice()->UnfreezeAll();
		}
		
		//--------------------------------------------------------
		M_GetMainApp()->m_bFlagTaken = FALSE;
		ReleaseSemaphore(M_GetMainApp()->m_hDrawSem, 1, NULL);
		
		SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
		//M_GetMainWnd()->ShowWindow(TRUE);
		
#ifdef NDEBUG
		if (mbFullScreen == TRUE)
		{
			RECT stRect,stRect2;
			
			M_GetMainWnd()->GetWindowRect(&stRect2);
			stRect.left = stRect2.left + 10;
			stRect.top = stRect2.top + 10;
			stRect.right = stRect2.left + 10;
			stRect.bottom = stRect2.top + 10;
			
			// we are in fullscreen
			// confine cursor in the window
			ClipCursor(&stRect);
			// hide cursor
			while (ShowCursor(FALSE) >= 0);
		}
		else
		{
			// we are in fullscreen
			// confine cursor in the window
			ClipCursor(NULL);
			// show cursor
			while (ShowCursor(TRUE) < 0);
		}
#endif

	}

	return TRUE;

}




//================================================================================
//================================================================================

