/*=========================================================================
*
* CPABaseO.cpp		- CPA_BaseObject : implementation
*
*
* Version			1.0
* Creation date		20.06.97
* Revision date
*
* Shaitan
*=======================================================================*/
#include "stdafx.h"

#ifdef ACTIVE_EDITOR

#include "itf/CPABaseO.hpp"

#include "acp_base.h"

#include "itf/CPAEditB.hpp"

#include "itf/NameMngr.hpp"
#include "itf/CPAInter.hpp"

//#################################################################################
// INITS
//#################################################################################

/*===========================================================================
	Constructor
=========================================================================*/
CPA_BaseObject::CPA_BaseObject (CPA_EditorBase *pEditor, const CString csType, CPA_BaseObject *pOwner, BOOL bAvailable)
{
	// init parameters
    m_p_oEditor = pEditor;
    m_p_oOwner = pOwner;
    m_p_oBaseObjectList = pEditor->GetBaseObjectList(csType);
    m_p_oInvalidObjectList = pEditor->GetInvalidObjectList(csType);

	m_bIsAvailable = bAvailable;
		
	// NAME IS NOT VALID
	m_csName.Empty();
	m_p_szName = NULL;
	m_bIsValid = FALSE;
}


/*===========================================================================
	Copy-Constructor
=========================================================================*/
CPA_BaseObject::CPA_BaseObject (CPA_BaseObject &r_oSource)
{
	// init parameters
    m_p_oEditor = r_oSource.m_p_oEditor;
    m_p_oOwner = r_oSource.m_p_oOwner;
    m_p_oBaseObjectList = r_oSource.m_p_oBaseObjectList;
    m_p_oInvalidObjectList = r_oSource.m_p_oInvalidObjectList;

	m_bIsAvailable = r_oSource.m_bIsAvailable;

	// NAME IS NOT VALID
	m_csName.Empty();
	m_p_szName = NULL;
	m_bIsValid = FALSE;
}

/*===========================================================================
	Destructor
=========================================================================*/
CPA_BaseObject::~CPA_BaseObject (void)
{
	// remove object from corresponding BaseObjectList
	fn_bUnRegister();
}

/*===========================================================================
	Owner
=========================================================================*/
BOOL CPA_BaseObject::fn_bSetOwner (CPA_BaseObject *pNewOwner)
{
	// can only be initialised once
	if (m_p_oOwner != NULL)
		return FALSE;

	// update BaseObjectList if the object is into the list
    if (! m_csName.IsEmpty())
    {
	    if (m_bIsValid)
			m_p_oBaseObjectList->fn_vBeforeChangingObjectOwner(this, pNewOwner);
		else
			m_p_oInvalidObjectList->fn_vBeforeChangingObjectOwner(this, pNewOwner);
    }

	// update owner
	m_p_oOwner = pNewOwner;


	return TRUE;
}

/*===========================================================================
	Data
=========================================================================*/
void CPA_BaseObject::fn_vUpdateData (void *pNewData)
{
	// update BaseObjectList if the object is into the list
    if (! m_csName.IsEmpty())
    {
	    if (m_bIsValid)
			m_p_oBaseObjectList->fn_vBeforeChangingObjectData(this, pNewData);
		else
			m_p_oInvalidObjectList->fn_vBeforeChangingObjectData(this, pNewData);
    }
}



/*===========================================================================
	MainWorld
=========================================================================*/
CPA_MainWorld * CPA_BaseObject::GetMainWorld (void)
{
	return GetEditor()->GetMainWorld();
}

/*===========================================================================
	Type
=========================================================================*/
CString CPA_BaseObject::GetType (void)
{
	if (m_p_oBaseObjectList == NULL)
		return ("");
	return m_p_oBaseObjectList->fn_csGetTypeName();
}

char * CPA_BaseObject::fn_p_szGetType (void)
{
	return m_p_oBaseObjectList->fn_szGetTypeName();	
}

//#################################################################################
// PRIVATE FUNCTIONS
//#################################################################################

/*===========================================================================
*		Description:	register object in corresponding BaseObjectList
*		Creation date:	20.06.97
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
BOOL CPA_BaseObject::fn_bRegister (void)
{
	// default => is valid
	m_bIsValid = TRUE;
	// register in list
	return m_p_oBaseObjectList->fn_bAddObject(this);
}

/*===========================================================================
*		Description:	unregister object from corresponding BaseObjectList
*		Creation date:	20.06.97
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
BOOL CPA_BaseObject::fn_bUnRegister (void)
{
	// valid => remove from base list
	if (m_bIsValid)
		return m_p_oBaseObjectList->fn_bRemoveObject(this);
	// invalid => remove from invalid list
	else
		return m_p_oInvalidObjectList->fn_bRemoveObject(this);
}

/*===========================================================================
*		Description:	rename object and register it if necessary
*		Creation date:	20.06.97
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
void CPA_BaseObject::fn_vDoRename (const CString csNewName)
{
	BOOL bFirstRegister;

	bFirstRegister = m_csName.IsEmpty();

	// update BaseObjectList
	if (!bFirstRegister)
	{
		if (m_bIsValid)
			m_p_oBaseObjectList->fn_vBeforeChangingObjectName(this, (char*)(LPCTSTR) csNewName);
		else
			m_p_oInvalidObjectList->fn_vBeforeChangingObjectName(this, (char*)(LPCTSTR) csNewName);
	}
	// update name
	m_csName = csNewName;
	m_p_szName = (char*)(LPCTSTR) m_csName;

	// if necessary, register object
	if (bFirstRegister)
		fn_bRegister();

}


//#################################################################################
// VALIDITY
//#################################################################################

/*===========================================================================
*		Description:	validate object (if initialised) and update corresponding list
*		Creation date:	20.06.97
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
BOOL CPA_BaseObject::fn_bValidate (void)
{
	BOOL bResult;
	
	// cannot validate an object without name
	if (m_csName.IsEmpty())
		return FALSE;

	// update flag
	m_bIsValid = TRUE;

	// switch from invalid list to base list
	bResult = m_p_oInvalidObjectList->fn_bRemoveObject(this);
	bResult = m_p_oBaseObjectList->fn_bAddObject(this);

	return bResult;
}

/*===========================================================================
*		Description:	invalidate object and update corresponding list
*		Creation date:	20.06.97
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
BOOL CPA_BaseObject::fn_bUnValidate (void)
{
	BOOL bResult;
	
	// update flag
	m_bIsValid = FALSE;

	// switch from invalid list to base list
	bResult = m_p_oBaseObjectList->fn_bRemoveObject(this);
	bResult = m_p_oInvalidObjectList->fn_bAddObject(this);

	return bResult;
}

//#################################################################################
// DEFAULT NAME
//#################################################################################

/*===========================================================================
*		Description:	ask the list for a default name, and check unicity criteria
*		Creation date:	20.06.97
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
CString CPA_BaseObject::GetDefaultUniqueName (const CString csDefaultBaseName /*=""*/)
{
	CString       csNewName;
    CPA_Interface *pInterface;

	pInterface = GetEditor()->GetInterface();

    do {
        csNewName = pInterface->GetPrefixedName( GetBaseObjectList() -> GetNewName(csDefaultBaseName) );
    } while( fn_eCheckUnicity(csNewName) != E_mc_None );

    return csNewName;
}

/*===========================================================================
*		Description:	rename object with default name, according to unicity criteria
*		Creation date:	20.06.97
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
void CPA_BaseObject::SetDefaultUniqueName (const CString csDefaultBaseName /*= ""*/)
{
	CString csNewName;

	csNewName = GetDefaultUniqueName(csDefaultBaseName);
	fn_vDoRename(csNewName);
}


//#################################################################################
// UNICITY
//#################################################################################

/*===========================================================================
*		Description:	check type
*		Creation date:	20.06.97
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
BOOL CPA_BaseObject::fn_bIsOfType (const CString csTypeName)
{
	return ((csTypeName.IsEmpty()) || (csTypeName.CompareNoCase(GetType()) == 0));
}

/*===========================================================================
*		Description:	default unicity criteria => Type + Name
*		Creation date:	20.06.97
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
tdeMissingCriteria CPA_BaseObject::fn_eCheckDefaultUnicity (const CString csNewName)
{
	CPA_List<CPA_BaseObject> oListObjects;
	long					 lNbObjects;
	
	if (csNewName.IsEmpty())
		return E_mc_NoName;
	
	// check BaseObjectList => unicity Name + Type
	lNbObjects = m_p_oBaseObjectList->fn_lFindObjects(NULL, csNewName, GetType());
	if (lNbObjects > 0) 
		return E_mc_TypeUnicity;

	// check InvalidObjectList => unicity Name + Type
	lNbObjects = m_p_oInvalidObjectList->fn_lFindObjects(NULL, csNewName, GetType());
	if (lNbObjects > 0) 
		return E_mc_TypeUnicity;
	
	// no objection
	return E_mc_None;
}

/*===========================================================================
*		Description:	current unicity criteria => Type + Name + Owner
*		Creation date:	20.06.97
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
tdeMissingCriteria CPA_BaseObject::fn_eCheckUnicityWithOwner (const CString csNewName)
{
	long					 lNbObjects;
	
	if (csNewName.IsEmpty())
		return E_mc_NoName;
	
	// check ReachableObjectList => unicity Name + Type
	lNbObjects = m_p_oBaseObjectList->fn_lFindObjects(NULL, csNewName, GetType(), m_p_oOwner);
	if (lNbObjects > 0) 
		return E_mc_OwnerUnicity;

	// check InvalidObjectList => unicity Name + Type
	lNbObjects = m_p_oInvalidObjectList->fn_lFindObjects(NULL, csNewName, GetType(), m_p_oOwner);
	if (lNbObjects > 0) 
		return E_mc_OwnerUnicity;
	
	// no objection
	return E_mc_None;
}

//#################################################################################
// RENAME
//#################################################################################

/*===========================================================================
*		Description:	check unicity criteria and rename object
*		Creation date:	20.06.97
*		Author:			Shaitan
*---------------------------------------------------------------------------
*		Revision date:       Author:
*=========================================================================*/
tdeMissingCriteria CPA_BaseObject::fn_eRename (const CString csNewName)
{
	tdeMissingCriteria	eResult;
	CPA_Interface		*pInterface;
	CString				csName;
	
	pInterface = m_p_oEditor->GetInterface();

	// not loading => check prefix
	if ((!pInterface->fn_bIsLoadingWorld())&&(!csNewName.IsEmpty()))
		csName = pInterface->GetPrefixedName(csNewName);
	else
		csName = csNewName;
	
	// check unicity
    eResult = fn_eCheckUnicity(csName);

	// rename object
	if (eResult == E_mc_None)
		fn_vDoRename(csName);

	// loading => register conflict
	else if ((eResult != E_mc_NoName)&&(pInterface->fn_bIsLoadingWorld()))
	{
		pInterface->fn_vAddRenamedObject();
		g_oNameManager.fn_vRegisterConflict(this, csName, eResult);
	}

	return eResult;
}

#endif // ACTIVE_EDITOR
