//===========================================================================
// A3dKeyboardConfDlg.cpp : implementation of Keyboard Configuration Dialog
//
// Version			1.0
// Creation date	21/10/96
// Author:			Philippe Touillaud
//
// Revision date
// Author:			
//
// (c) Ubi Pictures 1996
//
//===========================================================================

#include "stdafx.h"

#ifdef ACTIVE_EDITOR

#include "itf/A3dKeybo.hpp"
#include "itf/CPAkacnf.hpp"
#include "itf/CPARes.h"

/////////////////////////////////////////////////////////////////////////////
// A3d_KeyboardConfDlg dialog

// Constructor
A3d_KeyboardConfDlg::A3d_KeyboardConfDlg(CWnd *pParent, CString szName)
	: CDialog(A3d_KeyboardConfDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(A3d_KeyboardConfDlg)
	m_bCheckCtrl = FALSE;
	m_bCheckShift = FALSE;
	m_bCheckAlt = FALSE; /* CPA2 Corneliu Babiuc (ALT Key) 14-05-98 */
	m_uiCEditValue = 0;
	//}}AFX_DATA_INIT

	m_p_oKeyStringList = NULL;
	m_cCombinatedKey = 0;
	m_cCurrentKey = 0;
    m_szName = szName;
}


void A3d_KeyboardConfDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(A3d_KeyboardConfDlg)
	DDX_Control(pDX, IDC_A3D_KDBCONF_UNMODIFTEXT, m_oUnmodifCStatic);
	DDX_Control(pDX, IDC_A3D_KDBCONF_KEYPRESS, m_oVKDetector);
	DDX_Control(pDX, IDC_A3D_KBDCONF_LIST, m_oKeyConfCListBox);
	DDX_Check(pDX, IDC_A3D_KBDCONF_CHECK_CTRL, m_bCheckCtrl);
	DDX_Check(pDX, IDC_A3D_KBDCONF_CHECK_SHIFT, m_bCheckShift);
	DDX_Check(pDX, IDC_A3D_KBDCONF_CHECK_ALT, m_bCheckAlt); /* CPA2 Corneliu Babiuc (ALT Key) 14-05-98 */
	DDX_Text(pDX, IDC_A3D_KBDCONF_EDIT_KEY, m_uiCEditValue);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(A3d_KeyboardConfDlg, CDialog)
	//{{AFX_MSG_MAP(A3d_KeyboardConfDlg)
	ON_BN_CLICKED(IDC_A3D_KBDCONF_CHECK_CTRL, mfn_vOnCheckCtrl)
	ON_BN_CLICKED(IDC_A3D_KBDCONF_CHECK_SHIFT, mfn_vOnCheckShift)
	ON_BN_CLICKED(IDC_A3D_KBDCONF_CHECK_ALT, mfn_vOnCheckAlt) /* CPA2 Corneliu Babiuc (ALT Key) 14-05-98 */
	ON_LBN_SELCHANGE(IDC_A3D_KBDCONF_LIST, mfn_vOnSelchangeConfList)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()



// Overrides
BOOL A3d_KeyboardConfDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();

    SetWindowText(m_szName);
	mfn_vBuildStringList();
	m_oKeyConfCListBox.SetTabStops(128);
	m_oKeyConfCListBox.SetCurSel(0);
	mfn_vReadKeyDef();
	UpdateData(FALSE);
    GetDlgItem(IDC_A3D_KDBCONF_KEYPRESS)->SetFocus();
	return FALSE;
}

BOOL A3d_KeyboardConfDlg::UpdateData(BOOL bSaveToClass)
{
	BOOL bReturn;
	if (bSaveToClass)
	{
		bReturn = CDialog::UpdateData(TRUE);
	}
	else
	{
		bReturn = CDialog::UpdateData(FALSE);
	}

	return bReturn;
}



//===========================================================================
//		Description:	inits the string list in the CListBox
//      Creation date:  21 oct 96
//      Author:			Philippe Touillaud
//---------------------------------------------------------------------------
//      Revision date:  
//      Author:			
//===========================================================================
void A3d_KeyboardConfDlg::mfn_vBuildStringList(void)
{	
	CString 		oCurrent;
	POSITION		stPos;
	
	ASSERT(m_p_oKeyStringList != NULL);

	// builds the string in the CListBox
	stPos = m_p_oKeyStringList->GetHeadPosition();
    while(stPos != NULL)
	{
    	oCurrent = m_p_oKeyStringList->GetAt(stPos);
  		m_oKeyConfCListBox.AddString((LPCTSTR)oCurrent);
    	m_p_oKeyStringList->GetNext(stPos);
    }
}



//===========================================================================
//		Description:	reads the selected string in the CListBox, and
//						changes the associated controls.
//      Creation date:  26 oct 96
//      Author:			Philippe Touillaud
//---------------------------------------------------------------------------
//      Revision date:  
//      Author:			
//===========================================================================
void A3d_KeyboardConfDlg::mfn_vReadKeyDef(void)
{
	CString oKeyDef;
	CString& r_oKeyDef = oKeyDef;	// reference, to call GetText

	char	        cFlags;
	unsigned short	uwAction;	// just for the fonction call

	m_oKeyConfCListBox.GetText(m_oKeyConfCListBox.GetCurSel(), r_oKeyDef);
	m_cCurrentKey = m_p_oKAConfig->mfn_cConvertStringInKeyDef(&oKeyDef,	&cFlags, &uwAction);

	m_bCheckShift	= m_p_oKAConfig->mfn_bIsShiftSet(cFlags);
	m_bCheckCtrl	= m_p_oKAConfig->mfn_bIsCtrlSet(cFlags);
//CPA2 Corneliu Babiuc (Alt key) 14-05-98
	m_bCheckAlt		= m_p_oKAConfig->mfn_bIsAltSet(cFlags);
//END CPA2 Corneliu Babiuc (Alt key) 14-05-98

    if((m_cCurrentKey == VK_SHIFT) || (m_cCurrentKey == VK_CONTROL)
//CPA2 Corneliu Babiuc (Alt key) 14-05-98
		|| (m_cCurrentKey == VK_MENU) )
    {
		GetDlgItem(IDC_A3D_KBDCONF_CHECK_ALT)->EnableWindow(FALSE);
//END CPA2 Corneliu Babiuc (Alt key) 14-05-98
        GetDlgItem(IDC_A3D_KBDCONF_CHECK_CTRL)->EnableWindow(FALSE);
        GetDlgItem(IDC_A3D_KBDCONF_CHECK_SHIFT)->EnableWindow(FALSE);
    }
    else
    {
        GetDlgItem(IDC_A3D_KBDCONF_CHECK_CTRL)->EnableWindow(TRUE);
        GetDlgItem(IDC_A3D_KBDCONF_CHECK_SHIFT)->EnableWindow(TRUE);
//CPA2 Corneliu Babiuc (Alt key) 14-05-98
		GetDlgItem(IDC_A3D_KBDCONF_CHECK_ALT)->EnableWindow(TRUE);
//END CPA2 Corneliu Babiuc (Alt key) 14-05-98
    }

	if (m_p_oKAConfig->mfn_bIsReserved(m_cCurrentKey))
	{
		m_oUnmodifCStatic.ShowWindow(SW_SHOW);
		m_oVKDetector.ShowWindow(SW_HIDE);
	}
	else
	{
		m_oUnmodifCStatic.ShowWindow(SW_HIDE);
		m_oVKDetector.ShowWindow(SW_SHOW);
	}
    mfn_vShowKeyTyped(m_cCurrentKey, cFlags);
    GetDlgItem(IDC_A3D_KDBCONF_KEYPRESS)->SetFocus();
}



//===========================================================================
//		Description:	Updates the selected string in the CListBox with the
//						new values chosen (tests if the values are correct
//						before updating: if the key is already used, no change
//						is made , and the user is warned).
//      Creation date:  26 oct 96
//      Author:			Philippe Touillaud
//---------------------------------------------------------------------------
//      Revision date:  
//      Author:			
//===========================================================================
void A3d_KeyboardConfDlg::mfn_vUpdateKeyDef(char cKey, char cFlags)
{
	CString oKeyDef;
	CString& r_oKeyDef = oKeyDef;	// reference, to call GetText

	char	        cOldKey;
	char	        cOldFlags;
	unsigned short	uwAction;
	int		        iIndexSelect;	// 0 based index of current selection

	iIndexSelect = m_oKeyConfCListBox.GetCurSel();
	m_oKeyConfCListBox.GetText(iIndexSelect, r_oKeyDef);
	cOldKey = m_p_oKAConfig->mfn_cConvertStringInKeyDef(&oKeyDef,	&cOldFlags, &uwAction);

	
	// Modification of the key def (if the new choice is valid)
	if ( m_p_oKAConfig->mfn_bKeyIsUsedOutside(cKey ,cFlags) )
	{	// key is used by windows, or by an accelerator table
		AfxMessageBox("Reserved key !");
		SetActiveWindow();	// regains the focus on dialog

		// restore the original key def
		mfn_vReadKeyDef();

		// The possible key up message is swallowed by the MessageBox ():
		// mfn_vResetsCombinatedKey isn't called as it should be.
		m_cCombinatedKey = 0;
        return;
	}

	if ( mfn_bKeyIsUsed(cKey ,cFlags) )
	{	// key is used in the application list
		if ( (cKey != cOldKey) || (cFlags != cOldFlags) )
		{
			// the new key chosen is already used : warn the user
			int iRes = AfxMessageBox("Already used !", MB_OKCANCEL); //IDM_A3D_USEDKEY);
            if(iRes == IDCANCEL)
            {
			    SetActiveWindow();	// regains the focus on dialog		

			    // and restore the original key def
			    mfn_vReadKeyDef();
			    m_cCombinatedKey = 0;
                return;
            }
		}
	}

	// the key is valid: we change the definition
		// in the CListBox
	oKeyDef = m_p_oKAConfig->mfn_oConvertKeyDefInString(cKey, cFlags, uwAction);

	m_oKeyConfCListBox.DeleteString(iIndexSelect);
	m_oKeyConfCListBox.InsertString(iIndexSelect, (LPCTSTR)oKeyDef);
	m_oKeyConfCListBox.SetCurSel(iIndexSelect);

		// in the String List, mirror of the CListBox list
	m_p_oKeyStringList->SetAt(m_p_oKeyStringList->FindIndex(iIndexSelect), oKeyDef);
}



//===========================================================================
//		Description:	Checks if a key is already used in the current list
//						(m_p_oKeyStringList).
//      Creation date:  30 oct 96
//      Author:			Philippe Touillaud
//---------------------------------------------------------------------------
//      Revision date:  
//      Author:			
//===========================================================================
BOOL A3d_KeyboardConfDlg::mfn_bKeyIsUsed(char cKey ,char cFlags)
{
	BOOL bIsUsed = FALSE;	// result returned

	CString 	oCurrent;
	POSITION	stPos;
	char		cCurrentKey;
	char		cCurrentFlags;
	unsigned short		uwAction;		// only used for the function call
	
	ASSERT(m_p_oKeyStringList != NULL);

	// tests the list
	stPos = m_p_oKeyStringList->GetHeadPosition();
    while(stPos != NULL)
	{
    	oCurrent = m_p_oKeyStringList->GetAt(stPos);
		cCurrentKey = m_p_oKAConfig->mfn_cConvertStringInKeyDef(&oCurrent,	&cCurrentFlags, &uwAction);

		if ( (cCurrentKey == cKey) && (cCurrentFlags == cFlags) )
		{
			bIsUsed = TRUE;
		}
		
    	m_p_oKeyStringList->GetNext(stPos);
    }
	
	return bIsUsed;
}



//===========================================================================
//		Description:	This fonction is called by the child caption
//						(A3dVKeyTypedDetect) when a key is pressed in it.
//						It processes the change.
//      Creation date:  30 oct 96
//      Author:			Philippe Touillaud
//---------------------------------------------------------------------------
//      Revision date:  
//      Author:			
//===========================================================================
void A3d_KeyboardConfDlg::mfn_vDetectKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	CString oKeyString;
	char	cFlags;

	// parameters of OnKeyDown. nChar is the virtual key code.
	UpdateData(TRUE);
	
	m_uiCEditValue = nChar;
//CPA2 Corneliu Babiuc	
	if (nChar != VK_MENU)
		cFlags = cFlags;
//CPA2 Corneliu Babiuc
	if ( m_p_oKAConfig->mfn_bIsCombined(nChar) )
	{
		m_cCombinatedKey = nChar;
        cFlags = 0;
		mfn_vUpdateKeyDef(nChar, cFlags);
		mfn_vShowKeyTyped(nChar, cFlags);
	}

	else if ( m_p_oKAConfig->mfn_bIsReserved(nChar) )
	{
		AfxMessageBox("System key !"); //IDM_A3D_SYSTEMKEY);
		SetActiveWindow();	// regains the focus on dialog
	}

	else
	{
		cFlags = 0;
		m_p_oKAConfig->mfn_vSetFlag(m_cCombinatedKey, &cFlags);
		mfn_vUpdateKeyDef(nChar, cFlags);
		mfn_vShowKeyTyped(nChar, cFlags);
	}

	mfn_vReadKeyDef();
	UpdateData(FALSE);
}



//===========================================================================
//		Description:	This fonction is called by the child caption
//						(A3dVKeyTypedDetect) when a key is released in it.
//						The purpose is to manage combination keys
//      Creation date:  30 oct 96
//      Author:			Philippe Touillaud
//---------------------------------------------------------------------------
//      Revision date:  
//      Author:			
//===========================================================================
void A3d_KeyboardConfDlg::mfn_vResetsCombinatedKey(char cChar)
{
	if ( m_p_oKAConfig->mfn_bIsCombined(cChar) )
	{
		m_cCombinatedKey = 0;
	}
}



//===========================================================================
//		Description:	Shows the key typed (decoded) in the caption
//      Creation date:  30 oct 96
//      Author:			Philippe Touillaud
//---------------------------------------------------------------------------
//      Revision date:  
//      Author:			
//===========================================================================
void A3d_KeyboardConfDlg::mfn_vShowKeyTyped(char cChar, char cFlags)
{
	CString oKey;

	if ( m_p_oKAConfig->mfn_bIsShiftSet(cFlags) )
	{
		oKey = "Shift+";
	}

	if ( m_p_oKAConfig->mfn_bIsCtrlSet(cFlags) )
	{
		oKey = "Ctrl+";
	}
//CPA2 Corneliu Babiuc (ALT key) 14-05-98	
	if ( m_p_oKAConfig->mfn_bIsAltSet(cFlags) )
	{
		oKey = "Alt+";
	}
//END CPA2 Corneliu Babiuc (ALT key) 14-05-98
	
	oKey += m_p_oKAConfig->mfn_oKeyToIniString(cChar, 0);
	m_oVKDetector.ResetContent();
	m_oVKDetector.AddString(( LPCTSTR)oKey );
}


/////////////////////////////////////////////////////////////////////////////
// A3d_KeyboardConfDlg message handlers

void A3d_KeyboardConfDlg::mfn_vOnCheckCtrl() 
{
	char cFlags = 0;

	UpdateData(TRUE);

	// Mutual exclusion between Shift and Ctrl
	if (m_bCheckCtrl)
	{
		m_bCheckShift = FALSE;
//CPA2 Corneliu Babiuc (ALT key) 14-05-98
		//and now exclude ALT key
		m_bCheckAlt = FALSE;
//END CPA2 Corneliu Babiuc (ALT key) 14-05-98
		m_p_oKAConfig->mfn_vSetCtrl(&cFlags);
	}

	if (m_bCheckShift)
	{
		m_p_oKAConfig->mfn_vSetShift(&cFlags);	
	}

//CPA2 Corneliu Babiuc (ALT key) 14-05-98
	if (m_bCheckAlt)
	{
		m_p_oKAConfig->mfn_vSetAlt(&cFlags);	
	}
//END CPA2 Corneliu Babiuc (ALT key) 14-05-98

	mfn_vUpdateKeyDef(m_cCurrentKey, cFlags);
	UpdateData(FALSE);
    mfn_vShowKeyTyped(m_cCurrentKey, cFlags);
    GetDlgItem(IDC_A3D_KDBCONF_KEYPRESS)->SetFocus();
}


void A3d_KeyboardConfDlg::mfn_vOnCheckShift() 
{
	char cFlags = 0;

	UpdateData(TRUE);

	// Mutual exclusion between Shift and Ctrl
	if (m_bCheckShift)
	{
		m_bCheckCtrl = FALSE;
//CPA2 Corneliu Babiuc (ALT key) 14-05-98
		//and now exclude ALT key
		m_bCheckAlt = FALSE;
//END CPA2 Corneliu Babiuc (ALT key) 14-05-98
		m_p_oKAConfig->mfn_vSetShift(&cFlags);	
	}

	if (m_bCheckCtrl)
	{
		m_p_oKAConfig->mfn_vSetCtrl(&cFlags);
	}

//CPA2 Corneliu Babiuc (ALT key) 14-05-98
	if (m_bCheckAlt)
	{
		m_p_oKAConfig->mfn_vSetAlt(&cFlags);	
	}
//END CPA2 Corneliu Babiuc (ALT key) 14-05-98

	mfn_vUpdateKeyDef(m_cCurrentKey, cFlags);
	UpdateData(FALSE);
    mfn_vShowKeyTyped(m_cCurrentKey, cFlags);
    GetDlgItem(IDC_A3D_KDBCONF_KEYPRESS)->SetFocus();
}

//CPA2 Corneliu Babiuc (ALT key) 14-05-98
void A3d_KeyboardConfDlg::mfn_vOnCheckAlt() 
{
	char cFlags = 0;

	UpdateData(TRUE);

	// Mutual exclusion between Alt, Shift and Ctrl 
	if (m_bCheckAlt)
	{
		m_bCheckCtrl = FALSE;
		//and now exclude ALT key
		m_bCheckShift = FALSE;
		m_p_oKAConfig->mfn_vSetAlt(&cFlags);	
	}

	if (m_bCheckCtrl)
	{
		m_p_oKAConfig->mfn_vSetCtrl(&cFlags);
	}

	if (m_bCheckShift)
	{
		m_p_oKAConfig->mfn_vSetShift(&cFlags);	
	}

	mfn_vUpdateKeyDef(m_cCurrentKey, cFlags);
	UpdateData(FALSE);
    mfn_vShowKeyTyped(m_cCurrentKey, cFlags);
    GetDlgItem(IDC_A3D_KDBCONF_KEYPRESS)->SetFocus();
}
//END CPA2 Corneliu Babiuc (ALT key) 14-05-98


void A3d_KeyboardConfDlg::mfn_vOnSelchangeConfList() 
{
	// adapts controls values (check buttons) to de selected key def
	UpdateData(TRUE);	
	mfn_vReadKeyDef();
	UpdateData(FALSE);
}

#endif // ACTIVE_EDITOR