/*=============================================================================
 *
 *  Filename:           CPAZnAtv.cpp
 *  Version:            1.0
 *  Date:               14/02/97
 *  Author:             Marc Trabucato
 *
 *  Description:        implementation of CPA_ZonesActivating class
 *
 *===========================================================================*/

#ifdef ACTIVE_EDITOR

#include "stdafx.h"

#include "ACP_Base.h"
#include "ITF.h"
#include "DPT.h"

#include "TAC.h"
#include "TFa.h"
#include "OAc.h"
#include "ErO.h"

#include "ACInterf.hpp"


/******************************************************************************
* Macros
******************************************************************************/
#define M_ForEachElement(p_oList,p_oElement,Pos)    \
            for( p_oElement = (p_oList) -> GetHeadElement( Pos ) ;    \
                 p_oElement ;                                       \
                 p_oElement = (p_oList) -> GetNextElement( Pos )      \
                )

#define M_CHAR(string)      ( (char*) (LPCTSTR) (string) )

/******************************************************************************
* Constants
******************************************************************************/
#define C_cNoZone   0
#define C_cZDd      1
#define C_cZDe      2
#define C_cZDm      4
#define C_cZDr      8


/*=============================================================================
 *
 *  Description:                implementation of CPA_ZdxIndex class
 *
 *===========================================================================*/

DeclareTemplateStatic(ZDX_tdxHandleToZdxIndexList)
DeclareTemplateStatic(ZDX_tdxHandleToZoneSetList)
DeclareTemplateStatic(ZDX_tdxHandleToCsaList)
DeclareTemplateStatic(ZDX_tdxHandleToZoneSetEncapsulation)


void del(ZDX_tdxHandleToZdxIndexList h)
{
	if (M_GetMainApp()->m_bLeavingApplication)
		return;

	fn_vFreeZdxIndexListElement(h);
}




// ----------------------------------------------------------------------------
// Description : init engine functions
// ----------------------------------------------------------------------------
void CPA_ZdxIndex::Init()
{
    CPA_EdMot<ZDX_tdxHandleToZdxIndexList>::Init(fn_p_stCreateZdxIndexListElement,NULL/*ZDX_fn_vCopyStruct_ZdxIndexListElement*/,del);
}

// ----------------------------------------------------------------------------
// Description : constructor
// ----------------------------------------------------------------------------
CPA_ZdxIndex::CPA_ZdxIndex(ZDX_tdxHandleToZdxIndexList _hEngineStruct)
             :CPA_EdMot<ZDX_tdxHandleToZdxIndexList>(_hEngineStruct)
{
    if( !_hEngineStruct && !GetStruct() )
        SetStruct(fn_p_stCreateZdxIndexListElement());
}

// ----------------------------------------------------------------------------
// Description : destructor
// ----------------------------------------------------------------------------
CPA_ZdxIndex::~CPA_ZdxIndex()
{
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CPA_ZdxIndex::mfn_vSetIndex(unsigned short usIndex)
{
    if( GetStruct() )
    {
        //fn_vSetIndexOfZdxIndexList( GetStruct(), usIndex );
        GetStruct() -> uwZdxIndex = usIndex;
    }
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
unsigned short CPA_ZdxIndex::mfn_usGetIndex(void)
{
    return ( GetStruct() ? fn_uwGetIndexFromZdxIndexList( GetStruct() ) : -1 );
}



/*=============================================================================*
 *=============================================================================*
 *=============================================================================*
 *=============================================================================*
 *=============================================================================*
 *
 *
 *  Description:                implementation of CPA_ZonesActivating class
 *
 *
 *=============================================================================*
 *=============================================================================*
 *=============================================================================*
 *=============================================================================*
 *=============================================================================*/

// ----------------------------------------------------------------------------
// Description : init engine functions
// ----------------------------------------------------------------------------
void CPA_ZonesActivating::Init()
{
    CPA_EdMot<ZDX_tdxHandleToZoneSetList>::Init(fn_p_stCreateZoneSetListElement,NULL,fn_vFreeZoneSetListElement);
}

/*-----------------------------------------------------------------------------
 *  Description : save 'NewActivationZone' section
 *---------------------------------------------------------------------------*/
void CPA_ZonesActivating::fn_vCallBackSave( SCR_tdst_File_Description *_p_stFile, char *_p_szSectionName,
                                            void *_p_vData, SCR_tde_Ntfy_Action _eAction)
{
    CPA_ZonesActivating *p_oZA = (CPA_ZonesActivating*)_p_vData;
    char szActionName[SCR_CV_ui_Cfg_MaxLenName];
    char szIdName[SCR_CV_ui_Cfg_MaxLenName];
    char szSectionName[SCR_CV_ui_Cfg_MaxLenName];
    POSITION stPos;
    CPA_ZdxIndex *p_oZdxIndex;
	char szValue[10];
    unsigned int uiLastIndent = SCR_g_ui_SvL0_IndentationLevel;

    SCR_g_ui_SvL0_IndentationLevel = 1;
    switch ( _eAction )
    {
    case SCR_EA_Ntfy_AddSection:
    case SCR_EA_Ntfy_RebuildSection:
        // construct section name
        SCR_fn_v_RdL0_SplitSectionName( _p_szSectionName, NULL, szActionName, szIdName );
        SCR_fn_v_RdL0_ComputeSectionName( szSectionName, NULL, szActionName, szIdName );
        // save begin section
        SCR_M_SvL0_SaveBeginSection(_p_stFile, szSectionName, SCR_CC_C_Cfg_EOL );
        // save entries
        M_ForEachElement( &p_oZA -> m_oListOfZDxNameIdx, p_oZdxIndex, stPos )
        {
            SCR_M_SvL0_SaveEntry(_p_stFile, "ZdxIndex", SCR_CC_C_Cfg_NoChar );
            SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, itoa( p_oZdxIndex -> mfn_usGetIndex(), szValue, 10 ) );
        }
        // save end section
        SCR_M_SvL0_SaveEndSection(_p_stFile, SCR_CC_C_Cfg_EOL );
        SCR_M_SvL0_SaveBlankLine( _p_stFile );
        // update 'Existing section' bool
        p_oZA -> fn_vSectionSaved();
        break;
    case SCR_EA_Ntfy_DeleteSection:
        p_oZA -> fn_vSectionDeleted();
        break;
    }
    SCR_g_ui_SvL0_IndentationLevel = uiLastIndent;
}

// ----------------------------------------------------------------------------
// Description : constructor (to create a new element)
// ----------------------------------------------------------------------------
CPA_ZonesActivating::CPA_ZonesActivating( CPA_EditorBase *_p_oEditor, CPA_BaseObject *_p_oOwnerNamesList, CString _csName /*=""*/)
                    :CPA_SaveObject( _p_oEditor, C_szZATypeName, E_ss_Responsible, _p_oOwnerNamesList, TRUE,
                                     fn_szGetFamiliesDataPath(), CPA_ZonesActivating::fn_vCallBackSave),
                     CPA_EdMot<ZDX_tdxHandleToZoneSetList>()
{
    ASSERT( _p_oOwnerNamesList );
    // Section and File Name
    char szFileName[SCR_CV_ui_Cfg_MaxLenName];
    char szSectionName[SCR_CV_ui_Cfg_MaxLenName];
    char szReferencedSectionName[SCR_CV_ui_Cfg_MaxLenName];

    strcpy( szFileName, _p_oOwnerNamesList -> GetOwner() -> fn_p_szGetName() );
    strcat( szFileName, "\\" );
    strcat( szFileName, _p_oOwnerNamesList -> GetOwner() -> fn_p_szGetName() );
    strcat( szFileName, ".acz" );

    SCR_fn_v_RdL0_ComputeSectionName( szSectionName, szFileName, "ActivationZone", NULL );
    SCR_fn_v_RdL0_ComputeSectionName( szReferencedSectionName, szSectionName, "NewActivationZone", "" );
    SetReferencedSectionName( szReferencedSectionName );
    SetSectionData( this );

    SetExistingSection( FALSE );
    // Name
    if( fn_eRename( _csName ) != E_mc_None )
        SetDefaultValidName( _csName );

    fn_vUpdateSectionName();

    // Init Datas
    m_oListOfZDxNameIdx . SetEngineAnchor ( GetStruct() ? & GetStruct() -> hZdxIndexList : NULL ) ;
    m_oListOfZAListUsing . RemoveAll();
    //
    fn_vNotifySave();
}

// ----------------------------------------------------------------------------
// Description : constructor (to encapsulate an existing engine element)
// ----------------------------------------------------------------------------
CPA_ZonesActivating::CPA_ZonesActivating(CPA_EditorBase *_p_oEditor, CPA_BaseObject *_p_oOwnerNamesList, CString _csName,
                                         ZDX_tdxHandleToZoneSetList hZoneSetList)
                    :CPA_SaveObject( _p_oEditor, C_szZATypeName, E_ss_Responsible, _p_oOwnerNamesList, TRUE,
                                     fn_szGetFamiliesDataPath(), CPA_ZonesActivating::fn_vCallBackSave),
                     CPA_EdMot<ZDX_tdxHandleToZoneSetList>(hZoneSetList)
{
    ASSERT( _p_oOwnerNamesList );
    // Section and File Name
    char szFileName[SCR_CV_ui_Cfg_MaxLenName];
    char szSectionName[SCR_CV_ui_Cfg_MaxLenName];
    char szReferencedSectionName[SCR_CV_ui_Cfg_MaxLenName];

    strcpy( szFileName, _p_oOwnerNamesList -> GetOwner() -> fn_p_szGetName() );
    strcat( szFileName, "\\" );
    strcat( szFileName, _p_oOwnerNamesList -> GetOwner() -> fn_p_szGetName() );
    strcat( szFileName, ".acz" );
    SCR_fn_v_RdL0_ComputeSectionName( szSectionName, szFileName, "ActivationZone", NULL );
    SCR_fn_v_RdL0_ComputeSectionName( szReferencedSectionName, szSectionName, "NewActivationZone", "" );
    SetReferencedSectionName( szReferencedSectionName );
    SetSectionData( this );

    SetExistingSection( TRUE );
    // Name
    if( fn_eRename( _csName ) != E_mc_None )
        SetDefaultValidName( _csName );

    fn_vUpdateSectionName();

    // Init Datas
    m_oListOfZDxNameIdx . SetEngineAnchor ( GetStruct() ? & GetStruct() -> hZdxIndexList : NULL ) ;
    // fill list of ZdxIndex
    ZDX_tdxHandleToZdxIndexList hZdxIndexList;
    int iIndex = 0;
    LST2_M_StaticForEachElementOf( & GetStruct() -> hZdxIndexList, hZdxIndexList, iIndex)
    {
        CPA_ZdxIndex *p_ZdxIndex = new CPA_ZdxIndex( hZdxIndexList );
        m_oListOfZDxNameIdx . AddTail( p_ZdxIndex, FALSE );
    }

    m_oListOfZAListUsing . RemoveAll();
}

// ----------------------------------------------------------------------------
// Description : destructor
// ----------------------------------------------------------------------------
CPA_ZonesActivating::~CPA_ZonesActivating()
{
    if (M_GetMainApp()->m_bLeavingApplication == FALSE)
	{
		while( ! m_oListOfZDxNameIdx . IsEmpty() )
		{
			delete (m_oListOfZDxNameIdx . RemoveHead());
		}

		while( ! m_oListOfZAListUsing . IsEmpty() )
		{
			free( m_oListOfZAListUsing . RemoveHead() );
		}
	}
}

// ----------------------------------------------------------------------------
// Description : check unicity using family
// ----------------------------------------------------------------------------
tdeMissingCriteria CPA_ZonesActivating::fn_eCheckUnicity( const CString csNewName )
{
    CPA_BaseObject              *p_oFamily = GetOwner() -> GetOwner();
    CPA_List<CPA_BaseObject>     oList;
    long                         lNbObjects;

	if (csNewName.IsEmpty())
		return E_mc_NoName;
    //
    // search ZA with same name on invalid objects
    lNbObjects = GetInvalidObjectList() -> fn_lFindObjects( & oList, csNewName, GetType() );
    if( lNbObjects > 0 )
    {
        // find objects with same name
        // search object with same family
        POSITION xPos = oList . GetHeadPosition();
        while( xPos )
        {
            CPA_BaseObject* p_oZA = oList . GetNext( xPos );
            if( p_oZA -> GetOwner() -> GetOwner() == p_oFamily )
            {
                // find one object, invalid name
                return ( E_mc_OwnerUnicity );
            }
        }
    }
    oList . RemoveAll();
    // search ZA with same name on valid objects
    lNbObjects = GetBaseObjectList() -> fn_lFindObjects( & oList, csNewName, GetType() );
    if( lNbObjects > 0 )
    {
        // find objects with same name
        // search object with same family
        POSITION xPos = oList . GetHeadPosition();
        while( xPos )
        {
            CPA_BaseObject* p_oZA = oList . GetNext( xPos );
            if( p_oZA -> GetOwner() -> GetOwner() == p_oFamily )
            {
                // find one object, invalid name
                return ( E_mc_OwnerUnicity );
            }
        }
    }
    // ok
    return ( E_mc_None );
}

// ----------------------------------------------------------------------------
// Description : overload SetStruct function
// ----------------------------------------------------------------------------
void CPA_ZonesActivating::SetStruct(ZDX_tdxHandleToZoneSetList _hZdxIndexList)
{
    CPA_EdMot<ZDX_tdxHandleToZoneSetList>::SetStruct(_hZdxIndexList);
    m_oListOfZDxNameIdx . SetEngineAnchor ( GetStruct() ? & GetStruct() -> hZdxIndexList : NULL ) ;
}

// ----------------------------------------------------------------------------
// Description : set Activation of given zone
// ----------------------------------------------------------------------------
void CPA_ZonesActivating::mfn_vSetZoneActivation(unsigned short _usZoneIndex, BOOL _bActivation)
{
    if ( _usZoneIndex < ((CPA_tdoNameList*)GetOwner())->GetCount() )
    {
        POSITION stPos = mfn_xGetPosZoneActivation( _usZoneIndex );
        if( stPos && !_bActivation)
        {
            CPA_ZdxIndex *p_oZdxIndex = m_oListOfZDxNameIdx . GetAt( stPos );
            m_oListOfZDxNameIdx . RemoveAt( stPos );
            delete p_oZdxIndex;
        }
        else if( !stPos && _bActivation )
        {
            CPA_ZdxIndex *p_oZdxIndex = new CPA_ZdxIndex();
            p_oZdxIndex -> mfn_vSetIndex( _usZoneIndex );

			stPos = m_oListOfZDxNameIdx . GetHeadPosition();
			while( stPos && m_oListOfZDxNameIdx . GetAt( stPos ) -> mfn_usGetIndex() < _usZoneIndex )
			{
				m_oListOfZDxNameIdx . GetNext( stPos );
			}

			if( stPos )
				m_oListOfZDxNameIdx . InsertBefore( stPos, p_oZdxIndex );
			else
				m_oListOfZDxNameIdx . AddTail( p_oZdxIndex );
        }
    }
}

// ----------------------------------------------------------------------------
// Description : delete zone of given index and shift bigger indexes
// ----------------------------------------------------------------------------
void CPA_ZonesActivating::mfn_vRemoveZone(unsigned short _usZoneIndex)
{
    POSITION xPos = m_oListOfZDxNameIdx . GetHeadPosition();
    while ( xPos )
    {
        POSITION xCurPos = xPos;

        CPA_ZdxIndex    *p_oZdxIndex  = m_oListOfZDxNameIdx . GetNext( xPos );
        unsigned short   usCurrentIdx = p_oZdxIndex -> mfn_usGetIndex();
        //
        if( usCurrentIdx == _usZoneIndex )
        {
            // remove current index
            m_oListOfZDxNameIdx . RemoveAt( xCurPos );
            delete p_oZdxIndex;
        }
        else if( usCurrentIdx > _usZoneIndex )
        {
            // shift current index
            p_oZdxIndex -> mfn_vSetIndex( usCurrentIdx-1 );
        }
    }
}

// ----------------------------------------------------------------------------
// Description : insert zone of given index and shift bigger indexes
// ----------------------------------------------------------------------------
void CPA_ZonesActivating::mfn_vInsertZone(unsigned short _usZoneIndex)
{
    POSITION stPos = m_oListOfZDxNameIdx . GetHeadPosition();
    while ( stPos )
    {
        CPA_ZdxIndex    *p_oZdxIndex  = m_oListOfZDxNameIdx . GetNext( stPos );
        unsigned short   usCurrentIdx = p_oZdxIndex -> mfn_usGetIndex();
        //
        if( usCurrentIdx >= _usZoneIndex )
        {
            // shift current index
            p_oZdxIndex -> mfn_vSetIndex( usCurrentIdx+1 );
        }
    }
}

// ----------------------------------------------------------------------------
// Description : return  copy of current ZA
// ----------------------------------------------------------------------------
CPA_ZonesActivating *CPA_ZonesActivating::mfn_p_oDuplicateZA()
{
	CPA_ZonesActivating *p_oNewZA = new CPA_ZonesActivating( GetEditor(), GetOwner(), "CopyOf"+GetName() );

    POSITION stPos = m_oListOfZDxNameIdx . GetHeadPosition();
	while( stPos )
	{
		CPA_ZdxIndex *p_oZdxIndex = m_oListOfZDxNameIdx . GetNext( stPos );
		p_oNewZA -> mfn_vSetZoneActivation( p_oZdxIndex -> mfn_usGetIndex(), TRUE );
	}
	return p_oNewZA;
}

// ----------------------------------------------------------------------------
// Description : return POSITION of given zone
// ----------------------------------------------------------------------------
POSITION CPA_ZonesActivating::mfn_xGetPosZoneActivation(unsigned short _usZoneIndex)
{
    POSITION stPos = m_oListOfZDxNameIdx . GetHeadPosition();
    while ( stPos && ( m_oListOfZDxNameIdx . GetAt ( stPos ) -> mfn_usGetIndex() != _usZoneIndex ) )
    {
        m_oListOfZDxNameIdx . GetNext ( stPos );
    }
    return stPos;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CPA_ZonesActivating::mfn_vUsedByZAList(CPA_ZonesActivatingList *_p_oZAList, CPA_State *_p_oState)
{
    if( _p_oZAList -> GetOwner() != GetOwner() )
        return;

    if( fn_bIsValid() )
    {
        POSITION xPos = mfn_xGetZAListPos( _p_oZAList, _p_oState );

        if( xPos == NULL )
        {
            // create new
            tdstZAUsed *p_stUsed = (tdstZAUsed*) malloc( sizeof(tdstZAUsed) );
            p_stUsed -> p_oZAList = _p_oZAList;
            p_stUsed -> p_oState = _p_oState;
            m_oListOfZAListUsing . AddTail( p_stUsed );
        }
    }
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CPA_ZonesActivating::mfn_vDontUsedByZAList(CPA_ZonesActivatingList *_p_oZAList, CPA_State *_p_oState)
{
    if( _p_oZAList -> GetOwner() != GetOwner() )
        return;

    if( fn_bIsValid() )
    {
        POSITION xPos = mfn_xGetZAListPos( _p_oZAList, _p_oState );

        if( xPos != NULL )
        {
            // delete
            free( m_oListOfZAListUsing . GetAt( xPos ) );
            m_oListOfZAListUsing . RemoveAt( xPos );
        }
    }
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
POSITION CPA_ZonesActivating::mfn_xGetZAListPos(CPA_ZonesActivatingList *_p_oZAList, CPA_State *_p_oState)
{
    POSITION xPos = m_oListOfZAListUsing . GetHeadPosition();
    while( xPos )
    {
        tdstZAUsed *p_stUsed = m_oListOfZAListUsing . GetAt( xPos );
        if( ( p_stUsed -> p_oZAList == _p_oZAList ) && ( p_stUsed -> p_oState == _p_oState ) )
            break;
        m_oListOfZAListUsing . GetNext( xPos );
    }
    return xPos;
}

/*=============================================================================*
 *=============================================================================*
 *=============================================================================*
 *
 *  Description:                description of CPA_ActivationState class
 *
 *=============================================================================*
 *=============================================================================*
 *=============================================================================*/

// ----------------------------------------------------------------------------
// Description : init engine functions
// ----------------------------------------------------------------------------
void CPA_ActivationState::Init()
{
    CPA_EdMot<ZDX_tdxHandleToZoneSetEncapsulation>::Init(fn_p_stCreateZoneSetEncapsulation,NULL,fn_vFreeZoneSetEncapsulation);
}

// ----------------------------------------------------------------------------
// Description : constructor (new element)
// ----------------------------------------------------------------------------
CPA_ActivationState::CPA_ActivationState(CPA_ZonesActivatingList *_p_oZAList, CPA_State *_p_oState, CPA_ZonesActivating *_p_oZA,
                                         BOOL _bSectionExists)
                    :CPA_SectionObject("", fn_szGetFamiliesDataPath(), CPA_ActivationState::fn_vCallBackSave, NULL, _bSectionExists),
                     CPA_EdMot<ZDX_tdxHandleToZoneSetEncapsulation>()
{
    ASSERT( _p_oZAList );
    BOOL bCanDo = ( !_p_oZA || ( _p_oZAList -> GetOwner() == _p_oZA -> GetOwner() ) );

    if( !bCanDo )
    {
		CString csMessage1 = "Create a CPA_ActivationState (" + _p_oZAList -> GetName() + ", " + (_p_oZA ? _p_oZA -> GetName() : "NO ZA") + ", " + (_p_oState ? _p_oState -> GetName() : "NO STATE") + ")";
		CString csMessage2 = "CPA_ActivationState::CPA_ActivationState";
		CString csMessage3 = "ZAList and ZA haven\'t same NamesList";

        ERROR_PREPARE_M( C_szTACModuleNameErO, csMessage1, csMessage2, E_ERROR_GRAVITY_FATAL, csMessage3 );
        ERROR_ASSERT(0);
    }
    else
    {
        // datas
        m_p_oZAList = _p_oZAList;
        m_p_oZA = _p_oZA;
        m_p_oState = _p_oState;
        //
        char szSectionName[SCR_CV_ui_Cfg_MaxLenName];
        // Referenced Section Name
        mfn_vComputeReferencedSectionName( szSectionName, _p_oState );
        SetReferencedSectionName( szSectionName );
        SetSectionData( this );
        //
        m_p_oState -> mfn_vAddOnZAList( m_p_oZAList, m_p_oZA );
		mfn_bUpdate( NULL );
    }
}

// ----------------------------------------------------------------------------
// Description : constructor (existing element)
// ----------------------------------------------------------------------------
CPA_ActivationState::CPA_ActivationState(CPA_ZonesActivatingList *_p_oZAList, ZDX_tdxHandleToZoneSetEncapsulation _hZoneSetEncapsulation /*=NULL*/)
                    :CPA_SectionObject("", fn_szGetFamiliesDataPath(), CPA_ActivationState::fn_vCallBackSave, NULL, TRUE),
                     CPA_EdMot<ZDX_tdxHandleToZoneSetEncapsulation>(_hZoneSetEncapsulation)
{
    ASSERT( _p_oZAList );
    ASSERT( _hZoneSetEncapsulation );
    // init datas
    m_p_oZAList = _p_oZAList;
    m_p_oZA = NULL;
    m_p_oState = NULL;
    // update datas
	mfn_vInitZA();
	mfn_vInitState();
}

// ----------------------------------------------------------------------------
// Description : copy constructor
// ----------------------------------------------------------------------------
CPA_ActivationState::CPA_ActivationState(CPA_ActivationState &_r_oSource)
                    :CPA_SectionObject(_r_oSource),
                     CPA_EdMot<ZDX_tdxHandleToZoneSetEncapsulation>(_r_oSource . GetStruct())
{
    SetExistingSection( FALSE );
	SetSectionData( this );
    // datas
    m_p_oZAList = _r_oSource . m_p_oZAList;
    m_p_oZA = _r_oSource . m_p_oZA;
    m_p_oState = _r_oSource . m_p_oState;
    //
    m_p_oState -> mfn_vAddOnZAList( m_p_oZAList, m_p_oZA );
}

// ----------------------------------------------------------------------------
// Description : init editor ZA with engine Encapsulation ZA
// ----------------------------------------------------------------------------
void CPA_ActivationState::mfn_vInitZA(void)
{
	ASSERT( m_p_oZAList );
	ASSERT( GetStruct() );

    if( GetStruct() -> p_stZoneSetList )
    {
        m_p_oZA = (CPA_ZonesActivating*)m_p_oZAList -> GetEditor() -> GetBaseObject( GetStruct() -> p_stZoneSetList, C_szZATypeName, m_p_oZAList -> GetOwner() );
		if( m_p_oZA )
		{
			if( m_p_oZA -> GetOwner() != m_p_oZAList -> GetOwner() )
			{
				CString csMessage1 = "Try to Create a CPA_ActivationState";
				CString csMessage2 = "CPA_ActivationState::mfn_vInitZA";
				CString csMessage3 = "ZA hasn\'t same NamesList as ZAList";

				ERROR_PREPARE_M( C_szTACModuleNameErO, csMessage1, csMessage2, E_ERROR_GRAVITY_FATAL, csMessage3 );
				ERROR_ASSERT(0);
			}
		}
		else
		{
			CString csMessage1 = "Try to Create a CPA_ActivationState";
			CString csMessage2 = "CPA_ActivationState::mfn_vInitZA";
			CString csMessage3 = "Can't find editor ZA corresponding to engine ZA";

			ERROR_PREPARE_M( C_szTACModuleNameErO, csMessage1, csMessage2, E_ERROR_GRAVITY_FATAL, csMessage3 );
			ERROR_ASSERT(0);
		}
    }
	else
		SetExistingSection( FALSE );
}

// ----------------------------------------------------------------------------
// Description : init editor state with engine Encapsulation state
// ----------------------------------------------------------------------------
void CPA_ActivationState::mfn_vInitState(void)
{
	ASSERT( m_p_oZAList );
	ASSERT( GetStruct() );

    tdxHandleToState hState = NULL;
    CPA_Family      *p_oFamily = (CPA_Family*)m_p_oZAList -> GetOwner() -> GetOwner();
    unsigned short   uwI;

    LST2_M_StaticGetElementNumber( & p_oFamily -> GetStruct() -> hForStateArray, hState, GetStruct() -> uwIndex, uwI );
    if( hState )
    {
        m_p_oState = (CPA_State*)m_p_oZAList -> GetEditor() -> GetBaseObject( hState, C_szStateTypeName, p_oFamily );
		if( m_p_oState )
		{
			//
			char szSectionName[SCR_CV_ui_Cfg_MaxLenName];
			// Referenced Section Name
			mfn_vComputeReferencedSectionName( szSectionName, m_p_oState );
			SetReferencedSectionName( szSectionName );
			SetSectionData( this );
			//
			m_p_oState -> mfn_vAddOnZAList( m_p_oZAList, m_p_oZA );
			if( m_p_oZA )
				m_p_oZA -> mfn_vUsedByZAList( m_p_oZAList, m_p_oState );
		}
		else
		{
			CString csMessage1 = "Try to Create a CPA_ActivationState";
			CString csMessage2 = "CPA_ActivationState::mfn_vInitState";
			CString csMessage3 = "Can't find editor state corresponding to engine state";

			ERROR_PREPARE_M( C_szTACModuleNameErO, csMessage1, csMessage2, E_ERROR_GRAVITY_FATAL, csMessage3 );
			ERROR_ASSERT(0);
		}
    }
    else
    {
        CString csMessage1 = "Try to Create a CPA_ActivationState";
		CString csMessage2 = "CPA_ActivationState::mfn_vInitState";
        CString csMessage3 = "tdstZoneSetEncapsulation has no state";

        ERROR_PREPARE_M( C_szTACModuleNameErO, csMessage1, csMessage2, E_ERROR_GRAVITY_FATAL, csMessage3 );
        ERROR_ASSERT(0);
    }
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CPA_ActivationState::mfn_vComputeReferencedSectionName( char * _p_szSectionName, CPA_State *_p_oState )
{
    if( _p_oState != NULL)
        SCR_fn_v_RdL0_ComputeSectionName( _p_szSectionName, (char*)(LPCTSTR)m_p_oZAList -> fn_csComputeReferencedSectionName(m_p_oZAList -> GetName()), "AddActivation", _p_oState -> fn_p_szGetName() );
    else
        SCR_fn_v_RdL0_ComputeSectionName( _p_szSectionName, (char*)(LPCTSTR)m_p_oZAList -> fn_csComputeReferencedSectionName(m_p_oZAList -> GetName()), "AddActivation", NULL );

}
// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CPA_ActivationState::mfn_vSetZA(CPA_ZonesActivating *_p_oZA)
{
    BOOL bCanDo = ( !_p_oZA || ( m_p_oZAList -> GetOwner() == _p_oZA -> GetOwner() ) );

    if( !bCanDo )
    {
		CString csMessage1 = "Set ZA to CPA_ActivationState (" + m_p_oZAList -> GetName() + ", " + (_p_oZA ? _p_oZA -> GetName() : "NO ZA" ) + ", " + (m_p_oState ? m_p_oState -> GetName() : "NO STATE" ) + ")";
		CString csMessage2 = "CPA_ActivationState::mfn_vSetZA";
		CString csMessage3 = "ZA hasn\'t same NamesList as ZAList";

        ERROR_PREPARE_M( C_szTACModuleNameErO, csMessage1, csMessage2, E_ERROR_GRAVITY_FATAL, csMessage3);
        ERROR_ASSERT(0);
        return ;
    }

    if( m_p_oZA )
    {
        // previous ZA exists
        if( _p_oZA && ( m_p_oZA != _p_oZA ) )
        {
            // ZA changed
            if( GetCurrentNotification() == SCR_EA_Ntfy_DeleteSection )
                fn_vRestoreSection();
            else
                fn_vWriteSection();
            // update link
            m_p_oState -> mfn_vAddOnZAList( m_p_oZAList, _p_oZA );
        }
        else
        {
            // ZA deleted
            fn_vDeleteSection();
            // delete previous link
            m_p_oState -> mfn_vDelOnZAList( m_p_oZAList );
        }
    }
    else
    {
        // no previous ZA
        if( _p_oZA )
        {
            // new ZA
            if( GetCurrentNotification() == SCR_EA_Ntfy_DeleteSection )
                fn_vRestoreSection();
// Shaitan => state list in the level
            else if (!m_p_oState->GetEditor()->GetInterface()->fn_bIsLoadingWorld())
// End Shaitan => state list in the level
                fn_vWriteSection();
            // add link
            m_p_oState -> mfn_vAddOnZAList( m_p_oZAList, _p_oZA );
        }
    }
    m_p_oZA = _p_oZA;
	mfn_bUpdate( NULL );
}

// ----------------------------------------------------------------------------
// Description : update engine datas with editor datas
// ----------------------------------------------------------------------------
BOOL CPA_ActivationState::mfn_bUpdate(CPA_ZonesActivating *_p_oDefaultZA)
{
    BOOL bOK = FALSE;

    // update State Index
    if( m_p_oState )
    {
        tdxHandleToState hState = (m_p_oState ? m_p_oState -> GetStruct() : NULL );
        tdxHandleToState hStateTmp;
        unsigned short uwIndex;
        LST2_M_StaticWhatElementNumber(hState, hStateTmp, uwIndex);
        GetStruct() -> uwIndex = uwIndex;
        bOK = TRUE;
    }
    // update ZA
    if( m_p_oZA )
    {
        GetStruct() -> p_stZoneSetList = m_p_oZA -> GetStruct();
    }
    else if ( _p_oDefaultZA )
    {
        GetStruct() -> p_stZoneSetList = _p_oDefaultZA -> GetStruct();
    }
    return bOK;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
CPA_State* CPA_ActivationState::mfn_p_oGetState(void)
{
    return m_p_oState;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
CPA_ZonesActivating* CPA_ActivationState::mfn_p_oGetZA(void)
{
    return m_p_oZA;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
CPA_ZonesActivatingList* CPA_ActivationState::mfn_p_oGetZAList(void)
{
    return m_p_oZAList;
}

/*-----------------------------------------------------------------------------
 *  Description : save 'AddActivation' subsection
 *---------------------------------------------------------------------------*/
void CPA_ActivationState::fn_vCallBackSave( SCR_tdst_File_Description *_p_stFile, char *_p_szSectionName,
                                            void *_p_vData, SCR_tde_Ntfy_Action _eAction)
{
	// HORROR HORROR
	if( _eAction == SCR_EA_Ntfy_DeleteSection )
		return;
	// HORROR HORROR


    CPA_ActivationState     *p_oActSt   = (CPA_ActivationState*)_p_vData;
    CPA_State               *p_oState   = p_oActSt -> mfn_p_oGetState();
    CPA_ZonesActivating     *p_oZA      = p_oActSt -> mfn_p_oGetZA();
    CPA_ZonesActivatingList *p_oZAList  = p_oActSt -> mfn_p_oGetZAList();

    char                     szActionName[SCR_CV_ui_Cfg_MaxLenName];
    char                     szIdName[SCR_CV_ui_Cfg_MaxLenName];
    char                     szSectionName[SCR_CV_ui_Cfg_MaxLenName];
    char                     szZARef[SCR_CV_ui_Cfg_MaxLenName];
    char                     szBuffer[SCR_CV_ui_Cfg_MaxLenName];


    switch ( _eAction )
    {
    case SCR_EA_Ntfy_AddSection:
    case SCR_EA_Ntfy_RebuildSection:
        if ( p_oZAList && p_oState && p_oZA )
        {
            BOOL bCanSave = ( p_oZAList -> GetOwner() == p_oZA -> GetOwner() );

            if( !bCanSave )
            {
				CString csMessage1 = "Save CPA_ActivationState (" + p_oZAList -> GetName() + ", " + p_oZA -> GetName() + ", " + p_oState -> GetName() + ")";
				CString csMessage2 = "CPA_ActivationState::fn_vCallBackSave";
				CString csMessage3 = "ZA hasn\'t same NamesList as ZAList";

				ERROR_PREPARE_M( C_szTACModuleNameErO, csMessage1, csMessage2, E_ERROR_GRAVITY_FATAL, csMessage3);
                ERROR_ASSERT(0);
                return;
            }

            // construct section name
            SCR_fn_v_RdL0_SplitSectionName( _p_szSectionName, NULL, szActionName, szIdName );
            //SCR_fn_v_RdL0_ComputeSectionName( szSectionName, NULL, szActionName, szIdName );
            SCR_fn_v_RdL0_ComputeSectionName( szSectionName, NULL, szActionName, p_oState -> fn_p_szGetName() );
            // indent subsection
            SCR_g_ui_SvL0_IndentationLevel+=2;
            // save begin section
            SCR_M_SvL0_SaveBeginSection(_p_stFile, szSectionName, SCR_CC_C_Cfg_EOL );
            // save entry
            if( p_oState && p_oZA )
            {
                SCR_M_SvL0_SaveEntry(_p_stFile, "ActivationZone", SCR_CC_C_Cfg_NoChar );
                // construct ZA Reference
                SCR_fn_v_RdL0_ComputeSectionName( szBuffer, "*", "ActivationZone", NULL );
                SCR_fn_v_RdL0_ComputeSectionName( szZARef, szBuffer, "NewActivationZone", p_oZA -> fn_p_szGetName() );
                SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 2, szZARef, M_CHAR( p_oState -> GetReferencedSectionName() ) );
            }
            // save end section
            SCR_M_SvL0_SaveEndSection(_p_stFile, SCR_CC_C_Cfg_EOL );
            // restore indent
            SCR_g_ui_SvL0_IndentationLevel-=2;
            // update 'Existing section' bool
            p_oActSt -> fn_vSectionSaved();
            // SECURE
            if( strcmp( szIdName, p_oState -> fn_p_szGetName() ) )
            {
                p_oActSt -> mfn_vComputeReferencedSectionName( szSectionName, p_oState );
                p_oActSt -> SetReferencedSectionName( szSectionName );
            }
        }
        else
        {
            BOOL bPreviousExistence = p_oActSt -> fn_bSectionExists();
            p_oActSt -> fn_vSectionSaved();
            p_oActSt -> SetExistingSection( bPreviousExistence );
        }
        break;
    case SCR_EA_Ntfy_DeleteSection:
        p_oActSt -> fn_vSectionDeleted();
        break;
    }
}
/*=============================================================================*
 *=============================================================================*
 *=============================================================================*
 *
 *  Description:                description of CPA_ZonesActivatingList class
 *
 *=============================================================================*
 *=============================================================================*
 *=============================================================================*/



void del(ZDX_tdxHandleToCsaList h)
{
	if (M_GetMainApp()->m_bLeavingApplication)
		return;

	fn_vFreeCsaListElement(h);
}



// ----------------------------------------------------------------------------
// Description : init engine functions
// ----------------------------------------------------------------------------
void CPA_ZonesActivatingList::Init()
{
    CPA_EdMot<ZDX_tdxHandleToCsaList>::Init(fn_p_stCreateCsaListElement,NULL,del);
}

/*-----------------------------------------------------------------------------
 *  Description : save 'CreateNewArrayOfZoneSet' section
 *---------------------------------------------------------------------------*/
void CPA_ZonesActivatingList::fn_vCallBackSave( SCR_tdst_File_Description *_p_stFile, char *_p_szSectionName,
                                                void *_p_vData, SCR_tde_Ntfy_Action _eAction)
{
    CPA_ZonesActivatingList *p_oZAList = (CPA_ZonesActivatingList*)_p_vData;
    CPA_tdoNameList         *p_oNmList = p_oZAList -> mfn_p_oGetZDxNameList();
    char                     szActionName[SCR_CV_ui_Cfg_MaxLenName];
    char                     szIdName[SCR_CV_ui_Cfg_MaxLenName];
    char                     szSectionName[SCR_CV_ui_Cfg_MaxLenName];
    CPA_tdoNameList         *p_oNamesList = (CPA_tdoNameList*)p_oZAList -> GetOwner();
    unsigned int             uiLastIndent = SCR_g_ui_SvL0_IndentationLevel;
    CPA_Family              *p_oFamily = (CPA_Family*) p_oNamesList -> GetOwner();

    SCR_g_ui_SvL0_IndentationLevel = 1;
    switch ( _eAction )
    {
    case SCR_EA_Ntfy_AddSection:
    case SCR_EA_Ntfy_RebuildSection:
        // construct section name
        SCR_fn_v_RdL0_SplitSectionName( _p_szSectionName, NULL, szActionName, szIdName );
        SCR_fn_v_RdL0_ComputeSectionName( szSectionName, NULL, szActionName, szIdName );
        // save begin section
        SCR_M_SvL0_SaveBeginSection(_p_stFile, szSectionName, SCR_CC_C_Cfg_EOL );
        // save end section
        SCR_M_SvL0_SaveEndSection(_p_stFile, SCR_CC_C_Cfg_EOL );
        SCR_M_SvL0_SaveBlankLine( _p_stFile );
        // update 'Existing section' bool
        p_oZAList -> fn_vSectionSaved();
        break;
    case SCR_EA_Ntfy_DeleteSection:
        p_oZAList -> fn_vSectionDeleted();
        break;
    }
    SCR_g_ui_SvL0_IndentationLevel = uiLastIndent;
}

// ----------------------------------------------------------------------------
// Description : constructor
// ----------------------------------------------------------------------------
CPA_ZonesActivatingList::CPA_ZonesActivatingList(CPA_EditorBase *_p_oEditor, CPA_BaseObject *_p_oOwnerNamesList,
                                                 CString _csName /*=""*/,
                                                 ZDX_tdxHandleToCsaList _hEngineCsaList /*=NULL*/)
                        :CPA_SaveObject( _p_oEditor, C_szZAListTypeName, E_ss_Responsible, _p_oOwnerNamesList, TRUE,
                                        fn_szGetFamiliesDataPath(), CPA_ZonesActivatingList::fn_vCallBackSave),
                         CPA_EdMot<ZDX_tdxHandleToCsaList>(_hEngineCsaList)
{
    ASSERT( _p_oOwnerNamesList );
    // Section and File Name
    char szFileName[SCR_CV_ui_Cfg_MaxLenName];
    char szSectionName[SCR_CV_ui_Cfg_MaxLenName];
    char szReferencedSectionName[SCR_CV_ui_Cfg_MaxLenName];

    strcpy( szFileName, _p_oOwnerNamesList -> GetOwner() -> fn_p_szGetName() );
    strcat( szFileName, "\\" );
    strcat( szFileName, _p_oOwnerNamesList -> GetOwner() -> fn_p_szGetName() );
    strcat( szFileName, ".acz" );
    SCR_fn_v_RdL0_ComputeSectionName( szSectionName, szFileName, "ArrayOfZoneSet", NULL );
    SCR_fn_v_RdL0_ComputeSectionName( szReferencedSectionName, szSectionName, "CreateNewArrayOfZoneSet", "" );
    SetReferencedSectionName( szReferencedSectionName );
    SetSectionData( this );

    SetExistingSection( _hEngineCsaList != NULL );
    //
    // create engine data
    if( GetStruct() == NULL )
    {
        SetStruct(fn_p_stCreateCsaListElement());
    }
    //
    // Name
    if( fn_eRename( _csName ) != E_mc_None )
        SetDefaultValidName( _csName );

    fn_vUpdateSectionName();

	CPA_Family *p_oFamily = (CPA_Family*) _p_oOwnerNamesList -> GetOwner();

    // update data
	m_oListOfZAState . SetEngineAnchor ( GetStruct() ? & GetStruct() -> hZoneSetEncapsulationList : NULL ) ;
	m_oListOfUnusedZAState . RemoveAll();
    if( !_hEngineCsaList )
	{
        fn_vNotifySave();
        // fill list with default ZA
        mfn_vUpdateEditorList();
	}
	else
	{
        // existing object
        ASSERT( LST2_M_StaticGetNumberOfElements( & GetStruct() -> hZoneSetEncapsulationList ) <= LST2_M_StaticGetNumberOfElements( & p_oFamily -> GetStruct() -> hForStateArray ) );
	}
    m_bMustBeUpdated = FALSE;
}

// ----------------------------------------------------------------------------
// Description : destructor
// ----------------------------------------------------------------------------
CPA_ZonesActivatingList::~CPA_ZonesActivatingList()
{
    if (M_GetMainApp()->m_bLeavingApplication == FALSE)
	{
		while( ! m_oListOfZAState . IsEmpty() )
		{
			delete (m_oListOfZAState . RemoveHead());
		}

		while( ! m_oListOfUnusedZAState . IsEmpty() )
		{
			free( m_oListOfUnusedZAState . RemoveHead() );
		}
	}
}

void CPA_ZonesActivatingList::SetStruct(ZDX_tdxHandleToCsaList hCsaList)
{
	CPA_EdMot<ZDX_tdxHandleToCsaList>::SetStruct(hCsaList);
	m_oListOfZAState . SetEngineAnchor ( GetStruct() ? & GetStruct() -> hZoneSetEncapsulationList : NULL );
}

// ----------------------------------------------------------------------------
// Description : check unicity using family
// ----------------------------------------------------------------------------
tdeMissingCriteria CPA_ZonesActivatingList::fn_eCheckUnicity( const CString csNewName )
{
    CPA_BaseObject              *p_oFamily = GetOwner() -> GetOwner();
    CPA_List<CPA_BaseObject>     oList;
    long                         lNbObjects;

	if (csNewName.IsEmpty())
		return E_mc_NoName;

    // search ZAList with same name on invalid objects
    lNbObjects = GetInvalidObjectList() -> fn_lFindObjects( & oList, csNewName, GetType() );
    if( lNbObjects > 0 )
    {
        // find objects with same name
        // search object with same family
        POSITION xPos = oList . GetHeadPosition();
        while( xPos )
        {
            CPA_BaseObject* p_oZAList = oList . GetNext( xPos );
            if( p_oZAList -> GetOwner() -> GetOwner() == p_oFamily )
            {
                // find one object, invalid name
                return ( E_mc_OwnerUnicity );
            }
        }
    }
    oList . RemoveAll();
    // search ZAList with same name on valid objects
    lNbObjects = GetBaseObjectList() -> fn_lFindObjects( & oList, csNewName, GetType() );
    if( lNbObjects > 0 )
    {
        // find objects with same name
        // search object with same family
        POSITION xPos = oList . GetHeadPosition();
        while( xPos )
        {
            CPA_BaseObject* p_oZAList = oList . GetNext( xPos );
            if( p_oZAList -> GetOwner() -> GetOwner() == p_oFamily )
            {
                // find one object, invalid name
                return ( E_mc_OwnerUnicity );
            }
        }
    }
    // ok
    return ( E_mc_None );
}

// ----------------------------------------------------------------------------
// Description : overload fn_vNotify function
// ----------------------------------------------------------------------------
void CPA_ZonesActivatingList::fn_vNotifySave()
{
    CPA_ActivationState *p_oStZA = NULL;
    POSITION            xPos;

    CPA_SaveObject::fn_vNotifySave();
    M_ForEachElement( & m_oListOfZAState, p_oStZA, xPos )
    {
        p_oStZA -> fn_vWriteSection();
    }
}

// ----------------------------------------------------------------------------
// Description : overload fn_vNotify function
// ----------------------------------------------------------------------------
void CPA_ZonesActivatingList::fn_vNotifyUnSave()
{
    CPA_ActivationState *p_oStZA = NULL;
    POSITION            xPos;

    CPA_SaveObject::fn_vNotifyUnSave();
    M_ForEachElement( & m_oListOfZAState, p_oStZA, xPos )
    {
        p_oStZA -> fn_vDeleteSection();
    }
}

// ----------------------------------------------------------------------------
// Description : overload fn_vNotify function
// ----------------------------------------------------------------------------
void CPA_ZonesActivatingList::fn_vNotifyRestore()
{
    CPA_ActivationState *p_oStZA = NULL;
    POSITION            xPos;

    CPA_SaveObject::fn_vNotifyRestore();
    M_ForEachElement( & m_oListOfZAState, p_oStZA, xPos )
    {
        p_oStZA -> fn_vRestoreSection();
    }
}

// ----------------------------------------------------------------------------
// Description : overload fn_vNotify function
// ----------------------------------------------------------------------------
void CPA_ZonesActivatingList::fn_vNotifyRename()
{
    CPA_ActivationState *p_oStZA = NULL;
    POSITION            xPos;
    char                szSectionName[SCR_CV_ui_Cfg_MaxLenName];

    M_ForEachElement( & m_oListOfZAState, p_oStZA, xPos )
    {
        p_oStZA -> mfn_vComputeReferencedSectionName( szSectionName, p_oStZA -> mfn_p_oGetState() );
        p_oStZA -> fn_vRenameSection( szSectionName );
    }
    CPA_SaveObject::fn_vNotifyRename();
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CPA_ZonesActivatingList::fn_vUpdateReference ( CPA_SaveObject *_p_oObject )
{
    if ( _p_oObject -> fn_bIsOfType( C_szStateTypeName ) )
    {
        CPA_ActivationState *p_StZA = mfn_p_oGetActivationStateFromState( (CPA_State*) _p_oObject );
        p_StZA -> fn_vWriteSection();
    }
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CPA_ZonesActivatingList::mfn_vFillZAList(void)
{
	CPA_Family *p_oFamily = (CPA_Family*)GetOwner() -> GetOwner();

    // existing object
    ASSERT( LST2_M_StaticGetNumberOfElements( & GetStruct() -> hZoneSetEncapsulationList ) <= LST2_M_StaticGetNumberOfElements( & p_oFamily -> GetStruct() -> hForStateArray ) );

    // fill List with existing tdstZoneSetEncapsulationList
    ZDX_tdxHandleToZoneSetEncapsulation hEncapsulation;
    int iIndex = 0;
    LST2_M_StaticForEachElementOf( & GetStruct() -> hZoneSetEncapsulationList, hEncapsulation, iIndex)
    {
        CPA_ActivationState *p_oActSt = new CPA_ActivationState( this, hEncapsulation );
        m_oListOfZAState . AddTail( p_oActSt, FALSE );	// already on engine list
    }
    // fill list with default ZA
    mfn_vUpdateEditorList();
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
int CPA_ZonesActivatingList::mfn_iGetNbZDxNames(void)
{
    return mfn_p_oGetZDxNameList() -> GetCount();
}

// ----------------------------------------------------------------------------
// Description : write all ActivationState using given ZA
// ----------------------------------------------------------------------------
void CPA_ZonesActivatingList::mfn_vZARenamed(CPA_ZonesActivating *_p_oZA)
{
    CPA_ActivationState *p_oStZA = NULL;
    POSITION            xPos;

    M_ForEachElement( & m_oListOfZAState, p_oStZA, xPos )
    {
        if( p_oStZA -> mfn_p_oGetZA() == _p_oZA )
            p_oStZA -> fn_vWriteSection();
    }
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CPA_ZonesActivatingList::mfn_vStateRenamed(CPA_State *_p_oState)
{
    CPA_ActivationState *p_oStZA = mfn_p_oGetActivationStateFromState( _p_oState );

    if ( p_oStZA != NULL )
    {
        char szReferencedSectionName[SCR_CV_ui_Cfg_MaxLenName];

        p_oStZA -> mfn_vComputeReferencedSectionName( szReferencedSectionName, _p_oState );
        p_oStZA -> fn_vRenameSection( szReferencedSectionName );
    }
}

// ----------------------------------------------------------------------------
// Description : append ZA associated with given state
// ----------------------------------------------------------------------------
void CPA_ZonesActivatingList::mfn_vSetZAFromState(CPA_ZonesActivating *_p_oZA, CPA_State *_p_oState)
{
	ASSERT( _p_oState );
    BOOL bCanDo = ( !_p_oZA || ( GetOwner() == _p_oZA -> GetOwner() ) );

    if( !bCanDo )
    {
		CString csMessage1 = "Set ZA to State (" + GetName() + ", " + (_p_oZA ? _p_oZA -> GetName() : "NO ZA") + ", " + _p_oState -> GetName() + ")";
		CString csMessage2 = "CPA_ZonesActivatingList::mfn_vSetZAFromState()";
		CString csMessage3 = "ZA hasn\'t same NamesList as ZAList";

        ERROR_PREPARE_M( C_szTACModuleNameErO, csMessage1, csMessage2, E_ERROR_GRAVITY_WARNING, csMessage3 );
        ERROR_ASSERT(0);
        return ;
    }
    CPA_ActivationState *p_oStZA        = mfn_p_oGetActivationStateFromState( _p_oState, TRUE );
    CPA_ZonesActivating *p_oPreviousZA  = p_oStZA -> mfn_p_oGetZA();

    if ( p_oPreviousZA != _p_oZA )
    {
        // delete previous ZA
        if( p_oPreviousZA )
            p_oPreviousZA -> mfn_vDontUsedByZAList( this, _p_oState );
        // add new za
        p_oStZA -> mfn_vSetZA( _p_oZA );
        if( _p_oZA )
            _p_oZA -> mfn_vUsedByZAList( this, _p_oState );

        m_bMustBeUpdated = TRUE;
    }
}

// ----------------------------------------------------------------------------
// Description : remove State from ZAList
// ----------------------------------------------------------------------------
void CPA_ZonesActivatingList::mfn_vRemoveState(CPA_State *_p_oState)
{
    POSITION xPos = mfn_xGetPosActivationStateFromState( _p_oState );
    if( xPos )
    {
        CPA_ActivationState *p_oStZA = m_oListOfZAState . GetAt( xPos );
        p_oStZA -> fn_vDeleteSection();
        m_oListOfZAState . RemoveAt( xPos );
		m_oListOfUnusedZAState . AddTail( p_oStZA );
    }
}

// ----------------------------------------------------------------------------
// Description : append ZA associated with given state
// ----------------------------------------------------------------------------
CPA_ZonesActivating *CPA_ZonesActivatingList::mfn_p_oGetZAFromState(CPA_State *_p_oState)
{
    CPA_ActivationState *p_oStZA        = mfn_p_oGetActivationStateFromState( _p_oState );
    return p_oStZA -> mfn_p_oGetZA();
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
CPA_ActivationState *CPA_ZonesActivatingList::mfn_p_oGetActivationStateFromState(CPA_State *_p_oState, BOOL _bWithUnused /*=FALSE*/)
{
    CPA_ActivationState *p_oStZA = NULL;
    POSITION             xPos    = mfn_xGetPosActivationStateFromState( _p_oState );

    if( xPos )
        return m_oListOfZAState . GetAt( xPos );
    //
    if( _p_oState != NULL )
    {
		if( _bWithUnused )
		{
			// search on unused
			xPos = mfn_xGetPosUnusedActivationStateFromState( _p_oState );
			if( xPos )
			{
				p_oStZA = m_oListOfUnusedZAState . GetAt( xPos );
				// swap from one list to another
				m_oListOfUnusedZAState . RemoveAt( xPos );
				mfn_vInsertActivationState( p_oStZA );
				//
				return p_oStZA;
			}
		}
        // create new StZA
        p_oStZA = new CPA_ActivationState( this, _p_oState, NULL, FALSE);
        mfn_vInsertActivationState( p_oStZA );
    }
    return p_oStZA;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
POSITION CPA_ZonesActivatingList::mfn_xGetPosActivationStateFromState(CPA_State *_p_oState)
{
    CPA_ActivationState *p_oStZA = NULL;
    POSITION            xPos;

    xPos = m_oListOfZAState . GetHeadPosition();
    while ( xPos )
    {
        p_oStZA = m_oListOfZAState . GetAt( xPos );
        if( p_oStZA -> mfn_p_oGetState() == _p_oState )
            return xPos;
        m_oListOfZAState . GetNext( xPos );
    }
    return NULL;
}

// ----------------------------------------------------------------------------
// Description : construct Engine List with local Map
// ----------------------------------------------------------------------------
BOOL CPA_ZonesActivatingList::mfn_bUpdate()
{
    BOOL bOK = TRUE;

    CPA_ZonesActivating *p_oDefaultZA = (CPA_ZonesActivating*)((CPA_tdoNameList*)GetOwner()) -> m_fnp_oGetDefaultZA();
    CPA_ActivationState *p_oStZA = NULL;
    POSITION            xPos;

    M_ForEachElement( & m_oListOfZAState, p_oStZA, xPos )
    {
        bOK &= p_oStZA -> mfn_bUpdate( p_oDefaultZA );
    }
    return bOK;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
void CPA_ZonesActivatingList::mfn_vUpdateEditorList(void)
{
    POSITION            stPos;
    CPA_Family          *p_oFamily    = (CPA_Family*)GetOwner()->GetOwner();
    CPA_ZonesActivating *p_oDefaultZA = (CPA_ZonesActivating*) ((CPA_tdoNameList*)GetOwner()) -> m_fnp_oGetDefaultZA();
	/*
    if( p_oDefaultZA == NULL )
        return;
	*/
    BOOL bCanDo = ( !p_oDefaultZA || ( GetOwner() == p_oDefaultZA -> GetOwner() ) );
    if( !bCanDo )
    {
		CString csMessage1 = "Fill Empty states with default ZA : default ZA error ( ZAList : " + GetName() + ", ZA : " + p_oDefaultZA -> GetName() + ")";
		CString csMessage2 = "CPA_ZonesActivatingList::mfn_vSetZAFromState()";
		CString csMessage3 = "ZA hasn\'t same NamesList as ZAList";

        ERROR_PREPARE_M( C_szTACModuleNameErO, csMessage1, csMessage2, E_ERROR_GRAVITY_FATAL, csMessage3 );
        ERROR_ASSERT( 0 );
        return ;
    }
    // fill engine list of ZA
    stPos = p_oFamily -> m_oListOfStates . GetHeadPosition();
    while ( stPos )
    {
        CPA_State           *p_oState   = p_oFamily -> m_oListOfStates . GetNext( stPos );
        CPA_ZonesActivating *p_oZA      = mfn_p_oGetZAFromState( p_oState );

        if( p_oZA == NULL )
            mfn_vSetZAFromState( p_oDefaultZA, p_oState );
    }
}

// ----------------------------------------------------------------------------
// Description : return a copy of ZA List
// ----------------------------------------------------------------------------
CPA_ZonesActivatingList *CPA_ZonesActivatingList::mfn_p_oDuplicateZAList()
{
    CPA_ZonesActivatingList *p_oNewZAList   = new CPA_ZonesActivatingList( GetEditor(), GetOwner(), "CopyOf"+GetName() );
    CPA_ActivationState     *p_oStZA        = NULL;
    POSITION                xPos;

    M_ForEachElement( & m_oListOfZAState, p_oStZA, xPos )
    {
        p_oNewZAList -> mfn_vSetZAFromState( p_oStZA -> mfn_p_oGetZA(), p_oStZA -> mfn_p_oGetState() );
    }
	return p_oNewZAList;
}

// ----------------------------------------------------------------------------
// Description : find CPA_ZoneActivating using given ZdxIndexList
// ----------------------------------------------------------------------------
CPA_ZonesActivating *CPA_ZonesActivatingList::mfn_p_oGetZAWithEngineZdxIndexList(LST2_M_StaticAnchorDeclaration(ZDX_tdxHandleToZdxIndexList) hEngineZdxIndexListList, BOOL _bUseOwner /*=TRUE*/)
{
    CPA_List<CPA_BaseObject> oList;

    if( _bUseOwner )
        GetEditor() -> fn_lFindObjects( &oList, "", C_szZATypeName, GetOwner() );
    else
        GetEditor() -> fn_lFindObjects( &oList, "", C_szZATypeName );

    POSITION xPos = oList . GetHeadPosition();
    while ( xPos )
    {
        CPA_ZonesActivating *p_oZA = (CPA_ZonesActivating*) oList . GetNext( xPos );
        if( p_oZA && !memcmp( & p_oZA -> GetStruct() -> hZdxIndexList, &hEngineZdxIndexListList, sizeof hEngineZdxIndexListList ) )
            return p_oZA;
    }
    return NULL;
}

// ----------------------------------------------------------------------------
// Description : return existing Default ZA, or search next default ZA
// ----------------------------------------------------------------------------
CPA_ZonesActivating *CPA_ZonesActivating::mfn_p_oGetDefaultZA(void)
{
    CPA_ZonesActivating *p_oZAResult;
    CPA_List<CPA_BaseObject> oList;

    p_oZAResult = (CPA_ZonesActivating*) ((CPA_tdoNameList*)GetOwner()) -> m_fnp_oGetDefaultZA() ;
    if( p_oZAResult != NULL )
        return p_oZAResult;

    if( GetEditor() -> fn_lFindObjects(&oList, "", C_szZATypeName, GetOwner()) > 0 )
    {
        return (CPA_ZonesActivating*) oList . GetHead();
    }
    return NULL;
}

// ----------------------------------------------------------------------------
// Description :
// ----------------------------------------------------------------------------
POSITION CPA_ZonesActivatingList::mfn_xGetPosUnusedActivationStateFromState(CPA_State *_p_oState)
{
    CPA_ActivationState *p_oStZA = NULL;
    POSITION            xPos;

    xPos = m_oListOfUnusedZAState . GetHeadPosition();
    while ( xPos )
    {
        p_oStZA = m_oListOfUnusedZAState . GetAt( xPos );
        if( p_oStZA -> mfn_p_oGetState() == _p_oState )
            return xPos;
        m_oListOfUnusedZAState . GetNext( xPos );
    }
    return NULL;
}

void CPA_ZonesActivatingList::mfn_vInsertActivationState(CPA_ActivationState *_p_oStZA, BOOL _bEngine /*=TRUE*/)
{
	if( _p_oStZA )
	{
		unsigned short uwIndex = _p_oStZA -> GetStruct() -> uwIndex;
		CPA_ActivationState *p_oCurrentStZA;
		POSITION xPos = m_oListOfZAState . GetTailPosition();
		while( xPos )
		{
			p_oCurrentStZA = m_oListOfZAState . GetAt( xPos );
			if( p_oCurrentStZA -> GetStruct() -> uwIndex < uwIndex )
			{
				m_oListOfZAState . InsertAfter( xPos , _p_oStZA , _bEngine );
				break;
			}
			m_oListOfZAState . GetPrev( xPos );
		}
		if( xPos == NULL )
		{
			m_oListOfZAState . AddTail( _p_oStZA , _bEngine );
		}
	}
}

#endif // ACTIVE_EDITORee
