//#################################################################################
//
// BASE CLASS OF YOUR DLL interface
//
//#################################################################################
#include "StdAfx.h"

#include "ACP_Base.h"
#include "ITF.h"
#include "IncMEC.h"
#define D_State_Define
#include "IncGAM.h"
#undef D_State_Define
#include "GLI.h"
#include "SCR.h"

#include "_Minterf.hpp"
#include "EMECStrg.hpp"
#include "EMECVwMn.hpp"

#include "Meca_Res.h"
#include "ErO.h"
#include "IncTUT.h"

#include "X:\CPA\Main\Inc\_EditID.h"

// infos
static CString g_csTMEName = C_szDLLMecaName;
static CString g_csTMEAuthor = "Y. Babitch";
static CString g_csTMEVersion = "V 4.0.2   18/03/99";
static CString g_csTMEFrenchHelpFile = "Meca.hlp";
static CString g_csTMEEnglishHelpFile = "";

BOOL g_bTipFirstTime = TRUE;


CPA_Meca_Interface *g_pclInterface;

#define C_EdMeca_MenuID_OpenID						31
#define C_EdMeca_MenuID_CloseID						32

#define C_EdMeca_MenuID_SaveDimensions				35

#define C_EdMeca_PopupID_Exit_Editor				41

// the DLL global definition
tdstDLLIdentity g_stMecaDLLIdentity; 

//--------------------------------------------------------------------------------
// CONSTRUCTOR.
// You must put here all your DLL interface definitions.
//--------------------------------------------------------------------------------
CPA_Meca_Interface::CPA_Meca_Interface(void)
{
	// ************************** private internal
	m_p_stDLLIdentity = &g_stMecaDLLIdentity;

	// Does your DLL can output in main game view ?
	m_stBaseDLLDefinition.bCanOutputIn3DView = FALSE;

	// Does your DLL can be refresh by engine ?
	m_stBaseDLLDefinition.bCanBeRefreshedByEngine = FALSE;

	// Specific Init.
	m_pclMecaMainFrame = NULL;

	m_csEditorVersion = "4.0.0 [" + CString(__DATE__) + "] (<using CTL version " + CTL_fn_csGetVersion() + ">)";

    SetEditorInfo(g_csTMEName, g_csTMEAuthor, g_csTMEVersion, g_csTMEFrenchHelpFile, g_csTMEEnglishHelpFile);

	SetCurrent(FALSE);

	//For errors
	ERROR_g_fn_vAddAModuleDescriptor(	g_c_csMecaModuleNameForErrors,
																		m_csEditorVersion,
																		"Yves BABITCH",
																		"01 48 18 53 74 (Montreuil)",
																		"ybabitch@ubisoft.fr",
																		"Daniel PALIX",
																		"04 50 51 26 63 (Annecy)",
																		"dpalix@ubisoft.fr",
																		"",
																		"",
																		""
																	);

	m_pri_pclSelectedCard = NULL;
}

//**************************************************************************************
void CPA_Meca_Interface::fn_vJustAfterRegistered(void)
{
	CString a_csTypes[] =
	{
		g_c_csMecaCardTypeName,
	};

	fn_vRegisterObjectsType(a_csTypes, 1);
}

//**************************************************************************************
void CPA_Meca_Interface::fn_vConstruct()
{
	//Windows constructions

	//Creates the main frame
	if ( m_pclMecaMainFrame == NULL )
	{
		m_pclMecaMainFrame = new CPA_Meca_MainFrame;

		m_pclMecaMainFrame->CreateBase(	"",
																		1,
																		2,
																		GetInterface()->GetMainWorld() );

		m_pclMecaMainFrame->mfn_vEnableCaption(FALSE);

		m_pclMecaMainFrame->m_iInitWidth = m_clDocument.m_ulEditorWidth;
		m_pclMecaMainFrame->m_bKeepPos = TRUE;
		
		m_pclMecaMainFrame->m_stWinRight.cLinkSame = FRM_C_MoveLeft;
	}

	ERROR_PREPARE_M(g_c_csMecaModuleNameForErrors,
									"Construction of Mechanics Editor",
									"CPA_Meca_Interface::fn_vConstruct()",
									E_ERROR_GRAVITY_FATAL,
									"Dialog List could not be created for this Editor");
	ERROR_ASSERT( m_clDocument.m_pclDialogList != NULL );

	m_clDocument.m_pclDialogList->fn_vInitAllLists();
	m_clDocument.m_pclDialogList->fn_vReinitDialog();

	//////////////
	//////////////
	//Registers for TUT Module
	TUT_M_vGetTutDll();

	TUT_M_vRegisterControl(m_pclMecaMainFrame->m_hWnd, "TME_MainFrame", TUT_e_Window);
	//End of Registers for TUT Module
	//////////////
}

//**************************************************************************************
void CPA_Meca_Interface::fn_vLevelChanges()
{
	//Researches for existing Mechanics (loaded by Motor)
	m_fn_pclGetDocument()->m_fn_vSearchForLoadedCards();

	//Loads others
	m_fn_pclGetDocument()->m_fn_vLoadUnloadedCards();

	//Displays in the Editor
	m_fn_pclGetDocument()->m_fn_vReInitDisplay();
}

//**************************************************************************************
void CPA_Meca_Interface::fn_vAfterSaveAll(void)
{
	m_fn_pclGetDocument()->m_pclControlView->m_fn_vUpdateCardsName();
}

//**************************************************************************************
BOOL CPA_Meca_Interface::fn_bLoadBaseObject(CPA_BaseObject *p_oObject)
{
	ERROR_PREPARE_M(g_c_csMecaModuleNameForErrors,
									"Trying to load a mechanical Card",
									"CPA_Meca_Interface::fn_bLoadBaseObject(...)",
									E_ERROR_GRAVITY_FATAL,
									"The given object is not of the right type");
	ERROR_ASSERT( p_oObject->fn_bIsOfType(C_szMecaCardTypeName) );

					//Loads the Card
	return ((CPA_Meca_Card *)p_oObject)->m_fn_bLoadIfUnloaded();
}

//**************************************************************************************
tdePermission CPA_Meca_Interface::fn_eAcceptNewEditor(CPA_EditorBase *pNewEditor)
{
	return C_Allow;
}

//**************************************************************************************
BOOL CPA_Meca_Interface::fn_bCanActivateEditor(CPA_List<CPA_BaseObject> *pParams)
{
	return TRUE;
}

//**************************************************************************************
void CPA_Meca_Interface::fn_vOnActivateEditor(CPA_List<CPA_BaseObject> *pParams,
																							BOOL bBackActivated)
{
	m_fn_vShowEditor();
}

//**************************************************************************************
BOOL CPA_Meca_Interface::fn_bCanCloseEditor(void)
{
	return TRUE;
}

//**************************************************************************************
void CPA_Meca_Interface::fn_vOnCloseEditor(void)
{

}

//**************************************************************************************
void CPA_Meca_Interface::fn_vBeforeEngine(void)
{
	m_fn_vHideEditor();
//ANNECY jt {
	CPA_BaseObject* poBaseObject;
	Position xPos;
	CPA_BaseObjectList* poListOfCard = GetInterface()->GetMainWorld()->fn_p_oGetOriginalObjectList (g_c_csMecaCardTypeName);
	
	for ( poBaseObject = poListOfCard->GetHeadElement(xPos); xPos; poBaseObject = poListOfCard->GetNextElement(xPos) )
	{
		if ( poBaseObject->fn_bIsValid() )
		{
			CPA_Meca_Card* poCard = (CPA_Meca_Card*)poBaseObject;
			if (poCard->m_bDataCreated)
			{
				if (poCard->m_fn_pclGetCardType()->m_fn_csGetCardTypeName()=="Base Cards")
				{
					DNM_tdstMecBaseIdCard *pMecCard = (DNM_tdstMecBaseIdCard *)poCard->m_fn_pvGetBaseAddress();
					DNM_M_vBaseIdCardSetSlopeLimit ( pMecCard, MTH_M_xTan (MTH_M_xDegToRad (DNM_M_xBaseIdCardGetSlopeLimit(pMecCard))) );
				}
			}
		}
	}

//ENDANNECY jt }
}

//**************************************************************************************
void CPA_Meca_Interface::fn_vBeforeEditor(void)
{
	if ( fn_bIsCurrentEditor() ) 
		m_fn_vShowEditor();
//ANNECY jt {
	CPA_BaseObject* poBaseObject;
	Position xPos;
	CPA_BaseObjectList* poListOfCard = GetInterface()->GetMainWorld()->fn_p_oGetOriginalObjectList (g_c_csMecaCardTypeName);
	
	for ( poBaseObject = poListOfCard->GetHeadElement(xPos); xPos; poBaseObject = poListOfCard->GetNextElement(xPos) )
	{
		if ( poBaseObject->fn_bIsValid() )
		{
			CPA_Meca_Card* poCard = (CPA_Meca_Card*)poBaseObject;
			if (poCard->m_bDataCreated)
			{
				if (poCard->m_fn_pclGetCardType()->m_fn_csGetCardTypeName()=="Base Cards")
				{
					DNM_tdstMecBaseIdCard *pMecCard = (DNM_tdstMecBaseIdCard *)poCard->m_fn_pvGetBaseAddress();
					DNM_M_vBaseIdCardSetSlopeLimit ( pMecCard, MTH_M_xRadToDeg ( MTH_M_xATan (DNM_M_xBaseIdCardGetSlopeLimit(pMecCard))) );
					poCard->m_pri_fn_vGetAllMotorValues();

				}
			}
		}
	}

//ENDANNECY jt }
}

//**************************************************************************************
void CPA_Meca_Interface::fn_vHasLostFocus(void)
{

}

//**************************************************************************************
BOOL CPA_Meca_Interface::fn_bHasGainedFocus(void)
{
	// display Tip of the Day
	GetInterface()->fn_vDisplayTipOfDay("Mechanics", "TME", g_bTipFirstTime);
	g_bTipFirstTime = FALSE;

	return TRUE;
}

//**************************************************************************************
//Begin Mircea Dunka 31 Aug 1998 - DialogBar interface
void CPA_Meca_Interface::fn_vDefineDlgBarBtnIcon (tde_DlgBarCategory wCategory, tds_DlgBarBtn *_pDlgBarBtn)
{
	if(wCategory == C_DlgBarCategoryEditor)
	{
		_pDlgBarBtn->hIcon = ::LoadIcon((HINSTANCE)(GetDLLIdentity()->hModule), MAKEINTRESOURCE(IDI_TME_DLGBAR_ICON));
		CString oCst;
        oCst = C_szDLLMecaName;
        if( (M_GetMainApp()) && (M_GetMainApp()->mp_oAppKeyboard) )
        {
            oCst += "  (";
            oCst += M_GetMainApp()->mp_oAppKeyboard->mfn_oConvertIniStringToKeyString((const CString*)&CString("Activate Mechanic Editor"));
			oCst += ")";
        }
		strcpy(_pDlgBarBtn->szToolTip, (char*)(LPCTSTR)oCst);
		_pDlgBarBtn->uID = (UINT)this;
	}
}
//end Mircea Dunka 31 Aug 1998

//**************************************************************************************
BOOL CPA_Meca_Interface::fn_bDefineSubMenu(EDT_SubMenu *_p_oEDTSubMenu)
{
	if ( _p_oEDTSubMenu->GetSubMenuType() == C_SubMenuEditor )
	{
		CString csMenuDescString;
		CString csMenuAccelString = M_GetMainApp()->mp_oAppKeyboard->mfn_oConvertIniStringToKeyString((const CString*)&CString("Activate Mechanic Editor"));

		csMenuDescString.Format("%s\t%s", C_szDLLMecaName, csMenuAccelString);

		if ( fn_bIsCurrentEditor() )
			_p_oEDTSubMenu->AddAnEntry(this, M_MAKECHAR(csMenuDescString), C_EdMeca_MenuID_CloseID, TRUE);
		else
			_p_oEDTSubMenu->AddAnEntry(this, M_MAKECHAR(csMenuDescString), C_EdMeca_MenuID_OpenID, FALSE);
	}
	else if ( _p_oEDTSubMenu->GetSubMenuType() == C_SubMenuPreference )
	{
		if ( fn_bIsCurrentEditor() )
			_p_oEDTSubMenu->AddAnEntry(this, "Save dimensions (Mechanics)", C_EdMeca_MenuID_SaveDimensions, FALSE);
	}

	return TRUE;
}


//**************************************************************************************
void CPA_Meca_Interface::_OnSubMenuCommand(	EDT_SubMenu *_p_oEDTSubMenu,
																						UINT uiMsgID)
{
	switch (uiMsgID)
	{
		case C_EdMeca_MenuID_OpenID:
			if ( !fn_bIsCurrentEditor() )
				GetMainWorld()->fn_bActivateEditor(this, NULL);
			break;

		case C_EdMeca_MenuID_CloseID:
			if ( fn_bIsCurrentEditor() )
				GetMainWorld()->fn_bCloseEditor(this);
			break;

		case C_EdMeca_MenuID_SaveDimensions:
			if ( fn_bIsCurrentEditor() )
				m_clDocument.m_pub_fn_bSavePreferences();
			break;
	}
}

//**************************************************************************************
//**************************************************************************************
// Popup
//**************************************************************************************
BOOL CPA_Meca_Interface::fn_bDefinePopupMenu(EDT_PopUpMenu *pPopup,
																						 CPA_List<CPA_SuperObject> *pSelection,
																						 BOOL bIsAlone)
{
	BOOL bReturn = FALSE;
	
	if ( !bIsAlone )
	{
		if ( fn_bIsCurrentEditor() )
		{
			pPopup->AddAnEntry(this, "Exit Mechanics Editor", C_EdMeca_PopupID_Exit_Editor);

			bReturn = TRUE;
		}
	}

	return bReturn;
}

//**************************************************************************************
void CPA_Meca_Interface::_OnPopUpMenuCommand(UINT m_IDCmdMsg)
{
	switch (m_IDCmdMsg)
	{
		case C_EdMeca_PopupID_Exit_Editor:
			if ( fn_bIsCurrentEditor() )
				GetMainWorld()->fn_bCloseEditor(this);
		break;
	}
}

//**************************************************************************************
//**************************************************************************************
//Lists Dialog
//**************************************************************************************

#define C_szCards		"Cards"

//**************************************************************************************
void CPA_Meca_Interface::GetListsForDialog(CPA_DialogList *pDialog)
{
	pDialog->fn_vAddANewList(C_szCards, &(m_clDocument.m_clListOfCards));
}

//**************************************************************************************
void CPA_Meca_Interface::fn_vInitDefaultParameters(CPA_DialogList *pDialog)
{
	pDialog->SetDefaultButtonState(FALSE);
	pDialog->SetDefaultTestName("<< No Filter >>");
	pDialog->SetDefaultTypeName(C_szCards);
}

//**************************************************************************************
void CPA_Meca_Interface::fn_vSetANewTest(	CPA_DialogList *pDialog,
																					CString csCurrentList)
{
	CString csButtonText = "All cards";
	BOOL bButtonMustBeEnabled = TRUE;
	BOOL bButtonState = FALSE;
	
	if ( csCurrentList.Compare(C_szCards) == 0 )
	{
		if ( m_fn_pclGetDocument()->m_pclCurrentCardType != NULL )
			csButtonText = CString("Cards of type '") 
										+ m_fn_pclGetDocument()->m_pclCurrentCardType->m_fn_csGetCardTypeName() 
										+ CString("'");
		else
			csButtonText = "All cards";

		bButtonMustBeEnabled = TRUE;
		bButtonState = TRUE;
	}																							

	pDialog->fn_vInitButtonTest((char *)LPCTSTR(csButtonText),
															bButtonState,
															bButtonMustBeEnabled);
}

//**************************************************************************************
BOOL CPA_Meca_Interface::fn_bTestFunction(CString csCurrentType,
																					CString csTestName,
																					CPA_BaseObject *pEdObj)
{
	BOOL bReturnValue = TRUE;

	if	( csCurrentType.Compare(C_szCards) == 0 )
	{
		if ( m_fn_pclGetDocument()->m_pclCurrentCardType != NULL )
			bReturnValue = ( ((CPA_Meca_Card *)pEdObj)->m_fn_pclGetCardType() == m_fn_pclGetDocument()->m_pclCurrentCardType );
	}

	return bReturnValue;
}

//**************************************************************************************
BOOL CPA_Meca_Interface::fn_bOnButtonTest(CPA_DialogList *pDialog,
																					CString csTypeName,
																					tdeListDrawMode eDraw)
{
	BOOL bReturnValue = FALSE;

	//Shows all Cards
	m_fn_pclGetDocument()->m_pclCurrentCardType	= NULL;
	pDialog->fn_vUpdateSelection(E_lrm_ReinitList);

	pDialog->fn_vInitButtonTest("All cards",
															TRUE,
															TRUE);

	return bReturnValue;
}

//***********************************************************************
BOOL CPA_Meca_Interface::fn_bOnSelChangeComboList(CPA_DialogList *pDialog,
																									CString csTypeName)
{
	if ( csTypeName.CompareNoCase(C_szCards) == 0 )
	{
		//Shows all Cards
		m_fn_pclGetDocument()->m_pclCurrentCardType	= NULL;
		pDialog->fn_vUpdateSelection(E_lrm_ReinitList);
	
		pDialog->fn_vInitButtonTest("All cards",
																TRUE,
																TRUE);
	}

	return FALSE;
}

//***********************************************************************
BOOL CPA_Meca_Interface::fn_bOnSelChangeListObjects(CPA_DialogList *pDialog,
																										CString csTypeName,
																										CPA_BaseObject *pSelectedObject,
																										BOOL bUnselect)
{
	if ( csTypeName.CompareNoCase(C_szCards) == 0 )
	{
		//Displays Card
		CPA_Meca_Card *pclCard = (CPA_Meca_Card *)pSelectedObject;

		if ( bUnselect )
			m_pri_pclSelectedCard = NULL;
		else
		{
			if ( pclCard->fn_bIsAvailable() )
			{
				m_fn_pclGetDocument()->m_fn_vEditCard(pclCard);
				m_pri_pclSelectedCard = pclCard;
			}
//			else
//				if ( m_fn_pclGetDocument()->m_pclCurrentCardType != NULL )
//					m_pri_pclSelectedCard = m_fn_pclGetDocument()->m_pclCurrentCardType	->m_fn_pclGetEditedCard();
		}

		pDialog->fn_vUpdateSelection(E_lrm_ChangeSelection);
	}

	return TRUE;
}

//***********************************************************************
CPA_BaseObject *CPA_Meca_Interface::GetDialogSelection(	CPA_DialogList *pDialog,
																												CString csTypeName,
																												tdeListDrawMode eDrawMode)
{
	if ( csTypeName.CompareNoCase(C_szCards) == 0 )
		return m_pri_pclSelectedCard;

	return NULL;
}

//**************************************************************************************
//**************************************************************************************
//**************************************************************************************
// Specific members

//***********************************************************************
void CPA_Meca_Interface::m_fn_vShowEditor()
{
	g_oFrameGest.mfn_vSetRefresh(FALSE);

	if ( m_pclMecaMainFrame != NULL )
		g_oFrameGest.mfn_vActivateWindow(m_pclMecaMainFrame);

	g_oFrameGest.mfn_vSetRefresh(TRUE);
}

//***********************************************************************
void CPA_Meca_Interface::m_fn_vHideEditor()
{						  
	g_oFrameGest.mfn_vSetRefresh(FALSE);

	if ( m_pclMecaMainFrame != NULL )
		g_oFrameGest.mfn_vDisactivateWindow(m_pclMecaMainFrame);

	g_oFrameGest.mfn_vSetRefresh(TRUE);
}

//**************************************************************************************
CPA_Meca_MyDocument *CPA_Meca_Interface::m_fn_pclGetDocument()
{
	ERROR_ASSERT ( AfxIsValidAddress(&m_clDocument, sizeof(CPA_Meca_MyDocument)) );

	return &m_clDocument;
}

//**************************************************************************************

long CPA_Meca_Interface::OnQueryAction(CPA_EditorBase * /*p_oSender*/, WPARAM _wParam, LPARAM _lParam)
{
	switch (_wParam )
	{
	case Cw_TME_Query_updateAfterLoading:
		//Researches for existing Mechanics (loaded by Motor)
		m_fn_pclGetDocument()->m_fn_vUpdateUnLoadedCards();
		break;
	}
	return 0L;
}
