/*=========================================================================
 * 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 "IncTUT.h"

#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"
#include "acp_driver.h"

#ifdef USE_DIRECTX
extern "C"
{
#include "gliglou\multidrv\inc\dllinter.h"
}
#endif
/*
#define M_GetParent ((DEV_MultiDevice*)GetWindowParent())
#define M_GetParentFrame() ((FRMBaseMenu *) (GetParent()->GetParent()->GetParent()))
#define M_GetParentDialogBar()	(&(M_GetParentFrame()->m_oGeneralDialogBar)) 
*/
// 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_SYSCOMMAND()
    ON_WM_NCACTIVATE()

    ON_WM_NCHITTEST()
    ON_WM_SIZING()
    ON_WM_NCLBUTTONDBLCLK()
    ON_WM_NCCALCSIZE()
    ON_WM_NCHITTEST()
    ON_WM_NCPAINT()
    ON_WM_NCRBUTTONDOWN()
    ON_WM_NCLBUTTONDOWN()
    ON_WM_NCLBUTTONUP()
    ON_WM_NCMOUSEMOVE()
    ON_COMMAND(CPA_ID_DEVICEMENU_VIEWINGAME, OnCxtMenu1)
    ON_COMMAND(CPA_IDB_DEVICE_TILE_VERT, OnCxtMenu2)
    ON_COMMAND(CPA_IDB_DEVICE_TILE_HORZ, OnCxtMenu3)
    ON_COMMAND(CPA_IDB_DEVICE_CASCADE, OnCxtMenu4)
    ON_COMMAND(CPA_IDB_DEVICE_MAXIMIZE, OnCxtMenu5)
    ON_COMMAND(CPA_IDB_DEVICE_RESTORE, OnCxtMenu6)
    ON_COMMAND(CPA_IDM_DEVICE_CLOSE, OnCxtMenu7)
    ON_COMMAND(CPA_IDM_DEVICE_CLOSEALL, OnCxtMenu8)
    ON_COMMAND(CPA_IDM_DEVICE_NEWDEVICE, OnCxtMenu9)
    ON_COMMAND(CPA_ID_DEVICEMENU_SPLITVERTICAL, OnCxtMenu10)
    ON_COMMAND(CPA_ID_DEVICEMENU_SPLITHORIZONTAL, OnCxtMenu11)

//}}AFX_MSG_MAP
END_MESSAGE_MAP()

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

    m_bIsMaximize = 0;
    mbGameRefresh = TRUE;
    m_oSizingRect.SetRectEmpty();
    m_dfProp = 0;

}

DEV_Device::~DEV_Device()
{
}


//================================================================================
//================================================================================
FRMBaseMenu *DEV_Device::GetParentFrame()
{
	return GetParentMultiDevice()->GetParentFrame();
}


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

CPA_DialogBar *	DEV_Device::GetParentDialogBar()
{
	return &GetParentFrame()->m_oGeneralDialogBar;
}

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

	return mNumber;
}

//================================================================================
//================================================================================
// 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;
}



//================================================================================
//================================================================================
// stocks the number of Device
void DEV_Device::SetNumber(int number)
{
	mNumber = number;
}

void DEV_Device::CreateDevice(void *device,int x, int y,int w, int h, UINT ViewType)
{
	CPA_CameraDLLBase	*p_oCamDLL = NULL;
	CPA_Object			*p_oCamera = NULL;
    m_p_oWndParent = (CWnd*) device;
	
    mType = DEV_NORMAL;
    mViewType = ViewType;
	
    Create(NULL, NULL,
		WS_THICKFRAME | WS_OVERLAPPED | WS_CLIPSIBLINGS | WS_VISIBLE | WS_CHILD | WS_CAPTION | WS_MAXIMIZEBOX,
		CRect(x,y,x+w,y+h), m_p_oWndParent, 1);
	
	// positioning the Device in top plan
    SetWindowPos(&wndTop,0,0,0,0,SWP_NOSIZE | SWP_NOMOVE );

	// if the dialogbar exists, ok. else, it camera creation will be done in the framebase
/*	if (GetParentDialogBar() != NULL)
	{
		// create the default camera for the device
		p_oCamDLL = (CPA_CameraDLLBase*) M_GetMainApp()->m_p_oMainWorld->GetObjectDLLWithName(C_szDLLCameraName);
		ASSERT(p_oCamDLL != NULL);
		
		p_oCamera = p_oCamDLL->CreateDefaultCamera();
		ASSERT(p_oCamera != NULL);
		
		((DEV_ViewPort3D*)GetViewPort())->ChangeCamera(p_oCamera);
	}
*/				
	// stake has day of the list of the existing Devices
	GetParentMultiDevice()->SetActivDevice(GetNumber(),TRUE);
	// stake has days of active Device
	//GetParentMultiDevice()->SetFocusDevice(GetNumber());
		
	mbFullScreen = FALSE;
}

//================================================================================
//================================================================================
BOOL DEV_Device::IsMaximize()
{
    return (m_bIsMaximize || (mType == DEV_BACKGROUND));
}


//================================================================================
//================================================================================
// 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);
	//GetParentFrame()->GetClientRect(&stRect);
	//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
    SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
//	SetWindowPos(&wndTop, 250, 250, 0, 0, SWP_NOSIZE);//chbani



	
/*    if (M_GetMainWnd())
	{
		if (M_GetMainDevice()->GetDevice(0) != this)
		{
			CPA_CameraDLLBase	*p_oCamDLL = NULL;
			CPA_Object			*p_oCamera = NULL;
			
			// we are not in the game device
			// so, create a camera for this device
			p_oCamDLL = (CPA_CameraDLLBase*) M_GetMainApp()->m_p_oMainWorld->GetObjectDLLWithName(C_szDLLCameraName);
			ASSERT(p_oCamDLL != NULL);
			
			p_oCamera = p_oCamDLL->CreateDefaultCamera();
			ASSERT(p_oCamera != NULL);
			
			((DEV_ViewPort3D*)GetViewPort())->ChangeCamera(p_oCamera);
		}
	}
		
*/	GetParentMultiDevice()->SetActivDevice(GetNumber(),TRUE); // stake has day of the list of the existing Device
    //GetParentMultiDevice()->SetFocusDevice(GetNumber()); // stake has days of active Device


    mbFullScreen = FALSE;
}

//================================================================================
//================================================================================
void DEV_Device::OnDestroy()
{
    WaitForSingleObject(M_GetMainApp()->m_hDrawSem, INFINITE);
    CWnd::OnDestroy();

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

	GLD_bReleaseViewportAndDevice(m_hDisplayDevice,mpViewPort->m_hDisplayViewport);

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


    GetParentMultiDevice()->SetActivDevice(GetNumber(),FALSE);
    CWnd *topWnd=this;
    Freeze();
    while(1)
    {
		if((mType != DEV_BACKGROUND) && ((topWnd=topWnd->GetNextWindow()) != NULL))
        {
			if (GetParentMultiDevice()->IsDevice((DEV_Device *)topWnd))
            {
                GetParentMultiDevice()->SetFocusDevice( ((DEV_Device*)topWnd)->GetNumber() );
                break;
            }
        }
        else
		{
            GetParentMultiDevice()->SetFocusDevice( -1 );
            break;
        }
    }


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


    // Destroy bitmap
    m_oBmClose.DeleteObject();
    m_oBmGameRefresh1.DeleteObject();
    m_oBmGameRefresh2.DeleteObject();

}

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

void DEV_Device::OnSizing(UINT nSide, LPRECT lpRect)
{
    char    cFlags;
    char    cKey = M_GetMainApp()->mp_oDevKeyboard->mfn_cActionToKey(KA_PropSizing, &cFlags);
    int     iLW, iLH, iNW, iNH, iDW, iDH;

    if(GetAsyncKeyState(cKey) >= 0)
    {
        m_dfProp = ((double) (lpRect->right - lpRect->left + 1)) / ((double) (lpRect->bottom - lpRect->top + 1));
        m_oSizingRect.SetRect(lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
    }
    else
    {
        iLW = m_oSizingRect.right - m_oSizingRect.left + 1;    
        iLH = m_oSizingRect.bottom - m_oSizingRect.top + 1;    
        iNW = lpRect->right - lpRect->left + 1;
        iNH = lpRect->bottom - lpRect->top + 1;

        iDW = iNW - iLW;
        iDH = iNH - iLH;

        if((abs(iDW) >= abs(iDH)) || (nSide == WMSZ_BOTTOMRIGHT))
        {
            iNH = (int) ((double) iNW / m_dfProp);
            lpRect->bottom = lpRect->top + iNH;
        }
        else
        {
            iNW = (int)  ((double) iNH * m_dfProp);
            lpRect->right = lpRect->left + iNW;
        }

        m_oSizingRect.SetRect(lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
    }
}


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


	if(mNumber)
		WaitForSingleObject(M_GetMainApp()->m_hDrawSem, INFINITE);

    if (!IsFreezed())
    {
		CWnd::OnSize(type, cx, cy);

		GetWindowRect(&m_oSizingRect);
		m_dfProp = ((double) (m_oSizingRect.right - m_oSizingRect.left + 1)) / ((double) (m_oSizingRect.bottom - m_oSizingRect.top + 1));

		if(!M_bEditorsActive())
		{
			if(M_GetMainWnd())
				M_GetMainWnd()->GetWindowRect(&M_GetMainWnd()->m_oMainPos);
		}

		if (!IsFullScreen())
		{
			
			if (!GLD_bAdjustDeviceToWindow(m_hDisplayDevice))
			{
				ASSERT(0);
			}

		}

		else
		{
			//save the new pos for when we come back from fullscreen
			if(M_GetMainWnd())
			{
				M_GetMainWnd()->GetWindowRect(m_stRectWhileFullscreen);
				g_oBaseFrame.ScreenToClient(&m_stRectWhileFullscreen);
			}
		}


        // 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();


        GetParentMultiDevice()->mbForceDrawing = TRUE;


        CWnd::GetClientRect(&r);
        mpViewPort->SetWindowPos(&wndTopMost,r.left,r.top,r.right,r.bottom, SWP_NOZORDER | SWP_SHOWWINDOW);
    }

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

}

//================================================================================
//  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)
{
	if(!M_bEditorsActive())
		return MA_NOACTIVATEANDEAT;

	int iRes = CWnd::OnMouseActivate(pDesktopWnd, nHitTest, message);
	GetParentMultiDevice()->SetFocusDevice(GetNumber());
	return iRes;
}

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

void DEV_Device::OnNcLButtonDblClk(UINT nHitTest, CPoint point)
{
    if((nHitTest == HTCAPTION) && (mType != DEV_BACKGROUND))
    {
        if(m_bIsMaximize)
            SendMessage(WM_SYSCOMMAND, SC_RESTORE, 0);
        else
        {
            if(GetParentFrame()->mbWantTile)
                SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, 0);
        }
    }
}

//================================================================================
//================================================================================
void DEV_Device::OnNcMouseMove(UINT nHitTest, CPoint point)
{
}


//================================================================================
//================================================================================
int DEV_Device::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    GLD_tdstDeviceAttributes stDeviceAttr;
    if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

    // Create the DisplayDevice.
    stDeviceAttr.bFullScreen = FALSE;
    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_HARD | 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);
    // Load bitmap for closing frame

	m_oBmClose.LoadBitmap(CPA_IDB_DEVICE_CLOSE);
    m_oBmGameRefresh1.LoadBitmap(CPA_IDB_DEVICE_GAMEREFRESH1);
    m_oBmGameRefresh2.LoadBitmap(CPA_IDB_DEVICE_GAMEREFRESH2);


    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);


    GetParentMultiDevice()->mbForceDrawing = TRUE;


    GetClientRect(&r);
	if(IsWindow(mpViewPort->m_hWnd))
		mpViewPort->SetWindowPos(&wndTopMost,r.left,r.top,r.right-r.left,r.bottom-r.top,0);

	//CWnd::UpdateWindow();

}



//================================================================================
//================================================================================
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()
{
#ifdef USE_DIRECTX
	static COLORREF clrBand=0x00de967b;
	static COLORREF clrBgr=0x00deebef;
	static dwBand = 7;
	DWORD		dwRealWidth;
	DWORD		dwRealHeight;

	CClientDC	*p_DC;
	CRect		stRect;	

	p_DC = new CClientDC(this);
	GetClientRect(&stRect);		

	if (GLI_xIsGliInit())
	{

		GLI_fn_vRecomputeViewportToMaximizeDisplay(0);
			 
		dwRealWidth =  (DWORD)( (float)stRect.right  / GLI_gst_DllInfo.f_WidthRatio);
		dwRealHeight = (DWORD)( (float)stRect.bottom / GLI_gst_DllInfo.f_HeightRatio);
		
		p_DC->FillSolidRect(dwRealWidth, 0,  stRect.right -  dwRealWidth  , stRect.bottom  ,clrBgr);
		p_DC->FillSolidRect(dwRealWidth, 0, dwBand , dwRealHeight+dwBand  ,clrBand);
		

		p_DC->FillSolidRect(0, dwRealHeight ,  stRect.right , stRect.bottom -  dwRealHeight ,clrBgr);
		p_DC->FillSolidRect(0 , dwRealHeight , dwRealWidth+dwBand , dwBand  ,clrBand);

	}
	else
	{
		p_DC->FillSolidRect(&stRect,0x00);
	}

	if ( !M_bFullScreenEditor())
		GetParentMultiDevice()->DrawObject();

#else

	GetParentMultiDevice()->DrawObject();
	if (M_bFullScreenEditor())
	{
		CClientDC	*p_DC;
		CRect		stRect;	

		p_DC = new CClientDC(this);
		GetClientRect(&stRect);
		p_DC->FillSolidRect(&stRect,0x00);
	}
#endif

    CWnd::OnPaint();
}

//================================================================================
//================================================================================
void DEV_Device::OnSysCommand(UINT nID, LPARAM lParam)
{
    RECT    parentRect;
    CSize   sf(GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));

    switch(nID)
    {

        case SC_RESTORE:
            MoveWindow(&m_oRestoreRect);
            m_bIsMaximize = FALSE;
            break;

        case SC_MAXIMIZE:
            GetParent()->GetClientRect(&parentRect);

            RECT myRect;
            if(m_bIsMaximize == FALSE)
            {
                GetWindowRect(&myRect);
                GetParent()->ScreenToClient(&myRect);
                m_oRestoreRect.CopyRect(&myRect);
                m_bIsMaximize = TRUE;
            }

            if(mType == DEV_BACKGROUND)
            {
                sf.cx = 0; sf.cy = 0;
            }
            MoveWindow(-sf.cx, 0, parentRect.right + 2*sf.cx, parentRect.bottom + sf.cy);
            break;
        default:
            CWnd::OnSysCommand(nID, lParam);
    }
}

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

//
// DrawObject 3D
//
void DEV_Device::DrawObject(GLI_tdxHandleToLight hLight, HIE_tdxHandleToSuperObject hObject)
{
    if (!IsFreezed())
    {
		WaitForSingleObject(M_GetMainApp()->m_hDrawSem, INFINITE);
        if (!IsFreezed())
        {
            ((DEV_ViewPort3D *)mpViewPort)->DrawObject(hLight, hObject);
            if (!GLD_bFlipDevice(m_hDisplayDevice))
			{
				ASSERT(0);
				//                M_GetMainApp()->fn_vDynaFatalError(GLD_szGetLastErrorString());
			}
        }
        ReleaseSemaphore(M_GetMainApp()->m_hDrawSem, 1, NULL);
    }
}

void DEV_Device::DrawEditorObject(GLI_tdxHandleToLight hLight, CPA_SuperObject *pRoot)
{
    if (!IsFreezed())
    {
		WaitForSingleObject(M_GetMainApp()->m_hDrawSem, INFINITE);
        if (!IsFreezed())
        {
            ((DEV_ViewPort3D *)mpViewPort)->DrawEditorObject(hLight, pRoot);
            if (!GLD_bFlipDevice(m_hDisplayDevice))
			{
				ASSERT(0);
				//                M_GetMainApp()->fn_vDynaFatalError(GLD_szGetLastErrorString());
			}
        }
        ReleaseSemaphore(M_GetMainApp()->m_hDrawSem, 1, NULL);
    }
}

//================================================================================
//================================================================================
COLORREF fn_ComputeColor(char cCaption, char cHasFocus)
{
    COLORREF    cActive, cNActive;

    if(cCaption)
    {
        cActive = ::GetSysColor(COLOR_ACTIVECAPTION);
        cNActive = ::GetSysColor(COLOR_INACTIVECAPTION);
    }
    else
    {
        cActive = COLORREF(RGB(150, 0, 0));
        cNActive = ::GetSysColor(COLOR_INACTIVECAPTION);
    }

    if(cHasFocus)
        return cActive;
    return cNActive;
}

void DEV_Device::DrawDeviceTitle(void)
{
    CWindowDC   dc(this);
	CPen        oPen;
    CBrush      oBrush, oBrush1;
    CPen        *p_oldPen;
    RECT        myRect, nRect;
    COLORREF    Color;
    CSize       sizeFrame(GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));

    if(mType == DEV_BACKGROUND)
    {
        sizeFrame.cx = 0;
        sizeFrame.cy = 0;
    }

    GetClientRect(&myRect);
    myRect.right += sizeFrame.cx;

    // Move area
    // Compute color
    if(GetParentMultiDevice())
        Color = fn_ComputeColor(1, GetParentMultiDevice()->GetParent()->GetFocus() == mpViewPort);
    else
        Color = fn_ComputeColor(1, 0);

    oBrush.CreateSolidBrush(Color);
    nRect.left = sizeFrame.cx;
    nRect.right = myRect.right;
    if(mType == DEV_BACKGROUND)
        nRect.top = 0;
    else
        nRect.top = 1;
    nRect.bottom = DEV_YCaption - 2;
    dc.FillRect(&nRect, &oBrush);

    // A black line under caption
    oPen.CreatePen(PS_SOLID, 1, COLORREF(RGB(0, 0, 0)));
    p_oldPen = dc.SelectObject(&oPen);
    dc.MoveTo(sizeFrame.cx, DEV_YCaption - 2);
    dc.LineTo(myRect.right, DEV_YCaption - 2);
    dc.SelectObject(p_oldPen);
    oPen.DeleteObject();

    // A frame line under caption
    if(GetParentMultiDevice()->GetNumFocusDevice() == mNumber)
        Color = ::GetSysColor(COLOR_ACTIVEBORDER);
    else
        Color = ::GetSysColor(COLOR_INACTIVEBORDER);
    oPen.CreatePen(PS_SOLID, 1, Color);
    p_oldPen = dc.SelectObject(&oPen);
    dc.MoveTo(sizeFrame.cx, DEV_YCaption - 1);
    dc.LineTo(myRect.right, DEV_YCaption - 1);
    dc.SelectObject(p_oldPen);

    // To close frame
    if((mType != DEV_BACKGROUND) && (GetParentFrame()->mbWantClose))
    {
        CDC     dcBitmap;
	    HBITMAP hBitmapOld;
	    if (!dcBitmap.CreateCompatibleDC(&dc))
		    return;
	    hBitmapOld = (HBITMAP) dcBitmap.SelectObject(&m_oBmClose);
	    dc.BitBlt(myRect.right - 32, myRect.top, 24, DEV_YCaption, &dcBitmap, 0, 0, SRCCOPY);
	    dcBitmap.SelectObject(hBitmapOld);
    }

    // Game refresh
	if
	(
		(GetParentFrame() == M_GetMainWnd())
	&&	
		(
			(mType != DEV_BACKGROUND)
		||	(GetParent() != GetParentFrame()->m_oSplitter.GetPane(0, 0))
		)
	)
    {
        CDC     dcBitmap;
	    HBITMAP hBitmapOld;
	    if (!dcBitmap.CreateCompatibleDC(&dc))
		    return;
        if(!mbGameRefresh)
	        hBitmapOld = (HBITMAP) dcBitmap.SelectObject(&m_oBmGameRefresh1);
        else
	        hBitmapOld = (HBITMAP) dcBitmap.SelectObject(&m_oBmGameRefresh2);
	    dc.BitBlt(myRect.left + sizeFrame.cx + 8, myRect.top, 24, DEV_YCaption, &dcBitmap, 0, 0, SRCCOPY);
	    dcBitmap.SelectObject(hBitmapOld);
    }
}

void DEV_Device::OnNcPaint(void)
{
    CWnd::OnNcPaint();
    DrawDeviceTitle();
}

void DEV_Device::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
{
    CSize   sizeFrame(GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));

    if(mType == DEV_BACKGROUND)
        lpncsp->rgrc[0].top += DEV_YCaption;
    else
    {
        lpncsp->rgrc[0].left += sizeFrame.cx;
        lpncsp->rgrc[0].right -= sizeFrame.cx;
        lpncsp->rgrc[0].bottom -= sizeFrame.cy;
        lpncsp->rgrc[0].top += DEV_YCaption;
    }
}

UINT DEV_Device::OnNcHitTest(CPoint point)
{
    RECT    myRect;

    GetWindowRect(&myRect);
    if(point.y < (myRect.top + DEV_YCaption))
    {
        CSize   sizeFrame(GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME));

        // To close a windowed device
        if
        (
            ((point.x >= (myRect.right - 32 - sizeFrame.cx)) && (point.x <= (myRect.right - 8 - sizeFrame.cx)))
        &&  (mType != DEV_BACKGROUND)
		&&	(GetParentFrame()->mbWantClose)
        )
            return HTSYSMENU;

        // Refresh or not by game
        if
        (
            (point.x >= myRect.left + 8 + sizeFrame.cx)
        &&  (point.x <= myRect.left + 32 + sizeFrame.cx)
		&&	(GetParentFrame() == M_GetMainWnd())
		&&	
			(
				(mType != DEV_BACKGROUND)
			||	(GetParent() != GetParentFrame()->m_oSplitter.GetPane(0, 0))
			)
        )
        {
            return HTMENU;
        }

        return HTCAPTION;
    }

    UINT    uiHit = CWnd::OnNcHitTest(point);
    switch(uiHit)
    {
    case HTBOTTOMLEFT:
        return HTBOTTOM;
    case HTTOPLEFT:
        return HTLEFT;
    case HTTOPRIGHT:
        return HTRIGHT;
    case HTTOP:
        return HTNOWHERE;
    }
    return uiHit;
}

void DEV_Device::OnNcRButtonDown(UINT HitTest, CPoint point)
{
//ANNECY CB
	return;
//END
    CMenu   oMenu;
    CMenu   *pMenu;
	BOOL    bActiv = FALSE;
    
	if(!M_bEditorsActive())
		return;

    // Is there an additional active device ?
    for(int i = 1; i < MAX_DEVICE; i++)
    {
        if(GetParentMultiDevice()->IsActivDevice(i))
        {
            bActiv = TRUE;
            break;
        }
    }

    oMenu.LoadMenu(CPA_IDM_DEVICEMENU);
    pMenu = oMenu.GetSubMenu(0);

	if
	(
		(mType == DEV_BACKGROUND) 
	&&	(GetParentFrame() == M_GetMainWnd()) 
	&&	(GetParentFrame()->m_oSplitter.GetPane(0, 0) == GetParent())
	)
	{
		pMenu->CheckMenuItem(CPA_ID_DEVICEMENU_VIEWINGAME, MF_BYCOMMAND|MF_CHECKED);
	    pMenu->EnableMenuItem(CPA_ID_DEVICEMENU_VIEWINGAME, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
	}
	else
		pMenu->CheckMenuItem(CPA_ID_DEVICEMENU_VIEWINGAME, MF_BYCOMMAND|mbGameRefresh ? MF_CHECKED : MF_UNCHECKED);

    pMenu->EnableMenuItem(CPA_IDB_DEVICE_MAXIMIZE, MF_BYCOMMAND|mType == DEV_BACKGROUND ? MF_DISABLED|MF_GRAYED : MF_ENABLED);
    pMenu->EnableMenuItem(CPA_IDB_DEVICE_RESTORE, MF_BYCOMMAND|mType == DEV_BACKGROUND ? MF_DISABLED|MF_GRAYED : MF_ENABLED);
    pMenu->EnableMenuItem(CPA_IDM_DEVICE_CLOSE, MF_BYCOMMAND|mType == DEV_BACKGROUND ? MF_DISABLED|MF_GRAYED : MF_ENABLED);

    if(bActiv == FALSE)
    {
        pMenu->EnableMenuItem(CPA_IDM_DEVICE_CLOSEALL, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
        pMenu->EnableMenuItem(CPA_IDB_DEVICE_TILE_VERT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
        pMenu->EnableMenuItem(CPA_IDB_DEVICE_TILE_HORZ, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
        pMenu->EnableMenuItem(CPA_IDB_DEVICE_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
        pMenu->EnableMenuItem(CPA_IDM_DEVICE_CLOSEALL, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
    }
    if(GetParentFrame()->mbWantNew == FALSE)
        pMenu->EnableMenuItem(CPA_IDM_DEVICE_NEWDEVICE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);

    if(GetParentFrame()->mbWantTile == FALSE)
    {
        pMenu->EnableMenuItem(CPA_IDB_DEVICE_TILE_VERT, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
        pMenu->EnableMenuItem(CPA_IDB_DEVICE_TILE_HORZ, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
        pMenu->EnableMenuItem(CPA_IDB_DEVICE_CASCADE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
        pMenu->EnableMenuItem(CPA_IDB_DEVICE_MAXIMIZE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
        pMenu->EnableMenuItem(CPA_IDB_DEVICE_RESTORE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
    }
    if(GetParentFrame()->mbWantClose == FALSE)
    {
        pMenu->EnableMenuItem(CPA_IDM_DEVICE_CLOSE, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
        pMenu->EnableMenuItem(CPA_IDM_DEVICE_CLOSEALL, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
    }

    if
    (
        (!(GetParent()->GetParent()->IsKindOf(RUNTIME_CLASS(FRMSplitter))))
    ||  (mType != DEV_BACKGROUND)
    ||  (GetParentFrame()->mbWantSplit == FALSE)
    )
    {
        pMenu->EnableMenuItem(CPA_ID_DEVICEMENU_SPLITVERTICAL, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
        pMenu->EnableMenuItem(CPA_ID_DEVICEMENU_SPLITHORIZONTAL, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
    }
    else
    {
        if(GetParentSplitter()->GetRowCount() == 2)
            pMenu->EnableMenuItem(CPA_ID_DEVICEMENU_SPLITHORIZONTAL, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
        if(GetParentSplitter()->GetColumnCount() == 2)
            pMenu->EnableMenuItem(CPA_ID_DEVICEMENU_SPLITVERTICAL, MF_BYCOMMAND|MF_DISABLED|MF_GRAYED);
    }

    // register the popup menu for the tutorial module
    TUT_M_vGetTutDll    ();
    TUT_M_vRegisterMenu (this -> m_hWnd , pMenu -> m_hMenu , point . x , point . y);

	pMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON, point.x, point.y, this);
	oMenu.DestroyMenu();
}

void DEV_Device::OnNcLButtonDown(UINT HitTest, CPoint point)
{
    if((HitTest == HTSYSMENU) && (mType != DEV_BACKGROUND))
    {
    }
    else
    {
        // Refresh or not by game
        if(HitTest == HTMENU)
        {
            mbGameRefresh = mbGameRefresh ? FALSE : TRUE;
            DrawDeviceTitle();
            return;
        }

        if(!IsMaximize())
        {
            SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
            RedrawWindow();
            CWnd::OnNcLButtonDown(HitTest, point);
        }
    }
}

void DEV_Device::OnNcLButtonUp(UINT HitTest, CPoint point)
{
    if((HitTest == HTSYSMENU) && (mType != DEV_BACKGROUND))
    {
        if(GetParentFrame()->mbWantClose)
		{
            FRMBaseMenu *pParent = GetParentFrame();
		    SendMessage(WM_CLOSE, 0, 0);
			pParent->mfn_vUpdateDeviceToolBar();
		}
    }
    else
        CWnd::OnNcLButtonUp(HitTest, point);
}


//================================================================================
//================================================================================
BOOL DEV_Device::SwapFullScreen(BOOL Show /*=TRUE*/)
{

//	M_GetListOfAllDLL()->DeviceIsSwapping(GetParentMultiDevice(),this);

	if (!IsFullScreen())
	{
			//save the new pos for when we come back from fullscreen
			GetParentFrame()->GetWindowRect(m_stRectWhileFullscreen);
			g_oBaseFrame.ScreenToClient(&m_stRectWhileFullscreen);
	}


//		if (M_bEditorsActive() && M_GetMainApp()->m_bViewerOpened == TRUE)
//			return;
		if (!M_bEditorsActive())

		{
			if(!mbFullScreen)
			{
				M_GetMainWnd()->ShowWindow(FALSE);

				M_GetMainWnd()->fn_vShowGeneralInterface(FALSE);

			}
		}

	SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);

    WaitForSingleObject(M_GetMainApp()->m_hDrawSem, INFINITE);
	M_GetMainApp()->m_bFlagTaken = TRUE;
    //--------------------------------------------------------
    // Freeze all devices
    GetParentMultiDevice()->FreezeAll();


    if(!mbFullScreen)
    {
        FRMSplitter         *pSplit = &(M_GetMainWnd()->m_oSplitter);
        DEV_MultiDevice     *pSingle = (DEV_MultiDevice *) pSplit->GetPane(0, 0);
        if(pSplit->GetColumnCount() == 2)
        {
            pSingle = (DEV_MultiDevice *) pSplit->GetPane(0, 1);
            pSingle->FreezeAll();
            pSingle->EnableWindow(FALSE);
        }
        if(pSplit->GetRowCount() == 2)
        {
            pSingle = (DEV_MultiDevice *) pSplit->GetPane(1, 0);
            pSingle->FreezeAll();
            pSingle->EnableWindow(FALSE);

            if(pSplit->GetColumnCount() == 2)
            {
                pSingle = (DEV_MultiDevice *) pSplit->GetPane(1, 1);
                pSingle->FreezeAll();
                pSingle->EnableWindow(FALSE);
            }
        }
    }


    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);
	
    if(!mbFullScreen && Show)
	{
/*		if (!M_bEditorsActive())
			M_GetMainWnd()->fn_vShowGeneralInterface(FALSE);
		else*/
			M_GetMainWnd()->fn_vShowGeneralInterface(TRUE);
	}
//	GetParentFrame()->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




    // Unfreeze panes ?
    if(!mbFullScreen)
    {
        FRMSplitter         *pSplit = &M_GetMainWnd()->m_oSplitter;
        DEV_MultiDevice     *pSingle = (DEV_MultiDevice *) pSplit->GetPane(0, 0);
        if(pSplit->GetColumnCount() == 2)
        {
            pSingle = (DEV_MultiDevice *) pSplit->GetPane(0, 1);
            pSingle->UnfreezeAll();
            pSingle->EnableWindow(TRUE);
        }
        if(pSplit->GetRowCount() == 2)
        {
            pSingle = (DEV_MultiDevice *) pSplit->GetPane(1, 0);
            pSingle->UnfreezeAll();
            pSingle->EnableWindow(TRUE);

            if(pSplit->GetColumnCount() == 2)
            {
                pSingle = (DEV_MultiDevice *) pSplit->GetPane(1, 1);
                pSingle->UnfreezeAll();
                pSingle->EnableWindow(TRUE);
            }
        }
    }

	M_GetMainApp()->m_bFullScreenInEditor = IsFullScreen();

	if (!IsFullScreen() || M_bEditorsActive())
	{
//		RECT    r;
//		M_GetMainWnd()->GetWindowRect(&r);
//        r.left--;
//		M_GetMainWnd()->SetWindowPos(&wndTopMost,r.left,r.top,r.right,r.bottom, SWP_NOZORDER | SWP_SHOWWINDOW);		
//        r.left++;
		GetParentFrame()->SetParent(&g_oBaseFrame);
		if(!M_bEditorsActive())
		{
			CSize   ss(GetSystemMetrics(SM_CXMAXIMIZED), GetSystemMetrics(SM_CYMAXIMIZED));
			CRect	cs;
			cs.left = (ss.cx - 700) / 2;
			cs.top = (ss.cy - 550) / 2;
			cs.right = cs.left + 700;
			cs.bottom = cs.top + 550;
			GetParentFrame()->MoveWindow(cs);
		}
		else
		{
			GetParentFrame()->MoveWindow(m_stRectWhileFullscreen.left,
									 m_stRectWhileFullscreen.top,
									m_stRectWhileFullscreen.right - m_stRectWhileFullscreen.left+1,
									m_stRectWhileFullscreen.bottom - m_stRectWhileFullscreen.top+1,
									FALSE
									);
		}
//		M_GetMainDevice()->DrawObject();
		if(M_bEditorsActive())
			M_GetMainWnd()->fn_vShowGeneralInterface(TRUE);
		else
			M_GetMainWnd()->fn_vShowGeneralInterface(FALSE);
	}
	if(M_bEditorsActive())
	{
	    g_oFrameGest.mfn_vAWindowHasMoved(GetParentFrame(), FRM_C_MoveLeft);
		g_oFrameGest.mfn_vRefreshWindows(TRUE);
	}
	else
	{
		if(!IsFullScreen() && !IsWindowVisible())
			M_GetMainWnd()->ShowWindow(TRUE);
		else if (IsFullScreen() && IsWindowVisible())
			M_GetMainWnd()->ShowWindow(FALSE);
	}
	g_oBaseFrame.SetFocus();

	return TRUE;
}

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


void DEV_Device::SetMainWindowForRender(BOOL Show)
{
#ifdef USE_DIRECTX
	GLI_fn_vSetMainWindowForRender(m_hWnd);
#endif
}


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


void DEV_Device::OnCxtMenu1(void) // Game refresh
{
    mbGameRefresh = mbGameRefresh ? FALSE : TRUE;
    DrawDeviceTitle();
}
void DEV_Device::OnCxtMenu2(void) // Tile vert
{
	GetParentMultiDevice()->OnDeviceTileVert();
}
void DEV_Device::OnCxtMenu3(void) // Tile horiz
{
    GetParentMultiDevice()->OnDeviceTileHorz();
}
void DEV_Device::OnCxtMenu4(void) // Cascade
{
    GetParentMultiDevice()->OnDeviceCascade();
}
void DEV_Device::OnCxtMenu5(void) // Maximize
{
    GetParentMultiDevice()->OnMaximizeDevice();
}
void DEV_Device::OnCxtMenu6(void) // Restore
{
    GetParentMultiDevice()->OnRestoreDevice();
}
void DEV_Device::OnCxtMenu7(void) // Close
{
    GetParentMultiDevice()->OnCloseDevice();
}
void DEV_Device::OnCxtMenu8(void) // Close all
{
    GetParentMultiDevice()->OnCloseAllDevice();
}
void DEV_Device::OnCxtMenu9(void) // New
{
    GetParentMultiDevice()->OnOpenDevice();
}
void DEV_Device::OnCxtMenu10(void) // Split vertical
{
    GetParentSplitter()->MakeSplit(2);
}
void DEV_Device::OnCxtMenu11(void) // Split horizontal
{
    GetParentSplitter()->MakeSplit(1);
}

