// Implementation file for the definition of an enum characteristic
///////////////////////////////////////////////////////////////////////
#include "StdAfx.h"

#include "Data\CTL_DatE.hpp"

#include "Others\CTL_EnLi.hpp"
#include "Others\CTL_Pub.hpp"

//External Modules
#include "CTL_ErO.hpp"
//End of External Modules

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//**************************************************************************
//Constructor / Destructor
CTL_Editor_EnumData::CTL_Editor_EnumData(CTL_Editor_EnumDescriptor *pclEnumDescriptor,
																				 CString csScriptName,
																				 CTL_Editor_DataList *_pclParentList,
																				 CTL_Editor_Data *pclCurrentBaseData /*= NULL*/)
										: CTL_Editor_Data(CTL_DATA_TYPE__ENUM,
																			csScriptName,
																			_pclParentList,
																			pclCurrentBaseData)
{
 	m_pclCurrentValue = NULL;	 
	m_pclKeepedValueForUndo = NULL;
	m_pclEnumDescriptor = pclEnumDescriptor;
}

//**************************************************************************
CTL_Editor_EnumData::~CTL_Editor_EnumData()
{

}

//Member functions

//**************************************************************************************
//Function called to Init the data
void CTL_Editor_EnumData::m_fn_vInitData()
{

}

//**************************************************************************
//Function called to read associated motor's data
void CTL_Editor_EnumData::m_fn_vGetMotorData()
{
	BOOL bMustReadData =	TRUE;
	if ( m_pro_td_p_fn_bDataMustBeRead != NULL )
		bMustReadData =	m_pro_td_p_fn_bDataMustBeRead(this);

	if ( bMustReadData )
	{
		long lEnumValue;
		switch (m_pclEnumDescriptor->m_fn_ucGetEnumSize())
		{
		case 0:
			char bTempValue;
			CTL_fn_vGetMemory(m_pub_fn_pvGetMotorData(), &bTempValue, 0);
			lEnumValue = bTempValue;
			break;
		case 1:
			char cTempValue;
			CTL_fn_vGetMemory(m_pub_fn_pvGetMotorData(), &cTempValue, 1);
			lEnumValue = cTempValue;
			break;
		case 2:
			short wTempValue;
			CTL_fn_vGetMemory(m_pub_fn_pvGetMotorData(), &wTempValue, 2);
			lEnumValue = wTempValue;
			break;
		case 4:
			CTL_fn_vGetMemory(m_pub_fn_pvGetMotorData(), &lEnumValue, 4);
			break;
		}

		//Calls Modification function if needed
		if ( m_pro_td_p_fn_vDataModifWhenRead != NULL )
			m_pro_td_p_fn_vDataModifWhenRead(this);

		//Updates current value (pointer)
		BOOL bFound = FALSE;
		CTL_Editor_EnumElement	*m_pclCurrentElement;

		if ( m_pclEnumDescriptor != NULL )
		{
			POSITION pos = m_pclEnumDescriptor->GetHeadPosition();
			while ( (pos != NULL) && (!bFound) )
			{
				m_pclCurrentElement = m_pclEnumDescriptor->GetNext(pos);
				bFound = ( m_pclCurrentElement->m_pub_fn_lGetValue() == lEnumValue );
			}
		}

		if ( bFound )
			m_pclCurrentValue = m_pclCurrentElement;
		else
		{	
			if ( m_pclEnumDescriptor->GetCount() > 0 )
				m_pclCurrentValue = m_pclEnumDescriptor->GetHead();
			else
				m_pclCurrentValue = NULL;
		}
	}
} 

//**************************************************************************
//Function called to update associated motor's data
void CTL_Editor_EnumData::m_fn_vUpdateMotorData(CTL_tdeUpdateReason eReason,
																								long _lUserDefinedReason /*= 0*/)
{
	BOOL bMustWriteData = TRUE;
	if ( m_pro_td_p_fn_bDataMustBeWritten != NULL )
		bMustWriteData = m_pro_td_p_fn_bDataMustBeWritten(this);

	if ( bMustWriteData )
	{
		//Calls Modification function if needed
		if ( m_pro_td_p_fn_vDataModifWhenWrite != NULL )
			m_pro_td_p_fn_vDataModifWhenWrite(this);
	
		ERROR_ASSERT( m_pub_fn_pvGetMotorData() != NULL );

		if ( m_pclCurrentValue != NULL )
		{
			switch ( m_pclEnumDescriptor->m_fn_ucGetEnumSize() )
			{
				case 0:
				{
					char cTempValue = (char)m_pclCurrentValue->m_pub_fn_lGetValue();
					CTL_fn_vSetMemory(m_pub_fn_pvGetMotorData(), &cTempValue, 0);
				}
				break;
				case 1:
				{
					char cTempValue = (char)m_pclCurrentValue->m_pub_fn_lGetValue();
					CTL_fn_vSetMemory(m_pub_fn_pvGetMotorData(), &cTempValue, 1);
				}
				break;
				case 2:
				{
					short sTempValue = (short)m_pclCurrentValue->m_pub_fn_lGetValue();
					CTL_fn_vSetMemory(m_pub_fn_pvGetMotorData(), &sTempValue, 2);
				}
				break;
				case 4:
					{
						long lValue = m_pclCurrentValue->m_pub_fn_lGetValue();
						CTL_fn_vSetMemory(m_pub_fn_pvGetMotorData(), &lValue, 4);
					}
				break;
			}
		
		//Calls Modification function if needed
		if ( m_pro_td_p_fn_vDataModifWhenRead != NULL )
			m_pro_td_p_fn_vDataModifWhenRead(this);

		//Special changes
			m_fn_vDataHasBeenChanged(eReason, _lUserDefinedReason);
		}
	}
}

//************************************************************************
//Function called to update data with another one
void CTL_Editor_EnumData::m_fn_vUpdateData(CTL_Editor_Data *pclSourceData,
																					 CTL_tdeUpdateReason eReason,
																					 long _lUserDefinedReason /*= 0*/)
{
	ERROR_ASSERT(pclSourceData->m_pub_fn_tdeGetDataType() == m_pub_fn_tdeGetDataType());

	m_pclCurrentValue = ((CTL_Editor_EnumData *)pclSourceData)->m_pclCurrentValue;
	
	m_fn_vUpdateMotorData(eReason, _lUserDefinedReason);
}

//************************************************************************
//Function called to get a string representing the value of the data
CStringList *CTL_Editor_EnumData::m_fn_pcslFormatDataValueString()
{
	m_csStringList.RemoveAll();

	CString csStringToReturn = "!! Unknown !!";
	if ( m_pclCurrentValue != NULL )
		csStringToReturn.Format("%s", LPCTSTR(m_pclCurrentValue->m_pub_fn_csGetElementName()));

	m_csStringList.AddTail(csStringToReturn);

	return &m_csStringList;
}

//************************************************************************
//Function called to set the value of the data according to a string representing it
void CTL_Editor_EnumData::m_fn_vSetValueWithString(CStringList *pcslValueStringList)
{
	ERROR_ASSERT(pcslValueStringList->GetCount() == 1);
	CString csValueString = pcslValueStringList->GetHead();
	
	m_pclCurrentValue = m_pclEnumDescriptor->m_fn_pclGetElementFromString(csValueString);

	m_fn_vUpdateMotorData();
}

//************************************************************************
//Function called to look if data has been modified (by motor for example)
void CTL_Editor_EnumData::m_fn_vLookIfDataHasBeenModified()
{				  
	m_fn_vGetMotorData();

	m_pub_fn_vSetDataHasChanged(m_pclCurrentValue != m_pclOldValue);

	if ( m_pub_fn_bGetDataHasChanged() )
		m_pclOldValue = m_pclCurrentValue;
}

//Undo
//************************************************************************
//Function called to save the current Value (for Undo)
void CTL_Editor_EnumData::m_fn_vKeepCurrentValue()
{
	m_pclKeepedValueForUndo = m_pclCurrentValue;
}
 
//************************************************************************
//Function called to validate Undo for the current change
void CTL_Editor_EnumData::m_fn_vRegisterUndoAction()
{
/*	if ( m_pclKeepedValueForUndo->m_pub_fn_lGetValue() != m_pclCurrentValue->m_pub_fn_lGetValue() )
	{
		EdActors_ActorEnumDataModif *pclModif = new EdActors_ActorEnumDataModif(this, 
																																						m_pclKeepedValueForUndo,
																																						m_pclCurrentValue);
		m_pclParentActor->m_clUndoManager.AskFor(pclModif);
	}
*/
}

//************************************************************************
CTL_Editor_EnumDescriptor *CTL_Editor_EnumData::m_fn_pclGetEnumDescriptor()
{
	return m_pclEnumDescriptor;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method	: mfn_bEqualsModifiedDataOldValue 
// Date		: 98/06/24
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description	:
// Author		: Stegaru Cristian - CPA
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification	: 
// Date			:
// By			:
//////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CTL_Editor_EnumData::mfn_bEqualsModifiedDataOldValue (CTL_Editor_Data *pModifiedData)
{
	ASSERT (pModifiedData);

	ERROR_ASSERT(pModifiedData->m_pub_fn_tdeGetDataType() == m_pub_fn_tdeGetDataType());

	return m_pclCurrentValue == ((CTL_Editor_EnumData *)pModifiedData)->m_pclOldValue;
}



