/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"


#include <com/sun/star/awt/XVclContainerPeer.hpp>
#include <com/sun/star/beans/XPropertyChangeListener.hpp>

#include <cppuhelper/typeprovider.hxx>
#include <cppuhelper/implbase1.hxx>
#include <rtl/memory.h>
#include <rtl/uuid.h>

#include <toolkit/controls/unocontrolcontainer.hxx>
#include <toolkit/helper/property.hxx>
#include <toolkit/helper/servicenames.hxx>
#include <comphelper/sequence.hxx>

#include <tools/debug.hxx>
#include <tools/list.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>

#include <limits>
#include <map>
#include <boost/shared_ptr.hpp>

using namespace ::com::sun::star;

extern WorkWindow* lcl_GetDefaultWindow();

//	----------------------------------------------------
//	class UnoControlHolder
//	----------------------------------------------------
struct UnoControlHolder
{
	uno::Reference< awt::XControl > mxControl;
	::rtl::OUString                 msName;

public:
	UnoControlHolder( const ::rtl::OUString& rName, const uno::Reference< awt::XControl > & rControl )
	:	mxControl( rControl ),
		msName( rName )
	{
	}

    inline const ::rtl::OUString&                   getName() const { return msName; }
    inline const uno::Reference< awt::XControl >&   getControl() const { return mxControl; }
};

//DECLARE_LIST( UnoControlHolderList, UnoControlHolder* );

class UnoControlHolderList
{
public:
    typedef sal_Int32                                       ControlIdentifier;
private:
    typedef ::boost::shared_ptr< UnoControlHolder >         ControlInfo;
    typedef ::std::map< ControlIdentifier, ControlInfo >    ControlMap;

private:
    ControlMap  maControls;

public:
    UnoControlHolderList();
    ~UnoControlHolderList();

    /** adds a control with the given name to the list
        @param _rxControl
            the control to add. Must not be <NULL/>
        @param _pBName
            the name of the control, or <NULL/> if an automatic name should be generated
        @return
            the identifier of the newly added control
    */
    ControlIdentifier   addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName );

    /** returns the number of controls in the list
    */
    inline size_t       size() const { return maControls.size(); }

    /** determines whether or not the list is empty
    */
    inline bool         empty() const { return maControls.empty(); }

    /** retrieves all controls currently in the list
        @return
            the number of controls in the list
    */
    size_t  getControls( uno::Sequence< uno::Reference< awt::XControl > >& _out_rControls ) const;

    /** retrieves all identifiers of all controls currently in the list
        @return
            the number of controls in the list
    */
    size_t  getIdentifiers( uno::Sequence< sal_Int32 >& _out_rIdentifiers ) const;

    /** returns the first control which is registered under the given name
    */
    uno::Reference< awt::XControl >
            getControlForName( const ::rtl::OUString& _rName ) const;

    /** returns the identifier which a control is registered for, or -1 if the control
            isn't registered
    */
    ControlIdentifier
            getControlIdentifier( const uno::Reference< awt::XControl >& _rxControl );

    /** retrieves the control for a given id
        @param _nIdentifier
            the identifier for the control
        @param _out_rxControl
            takes the XControl upon successful return
        @return
            <TRUE/> if and only if a control with the given id is part of the list
    */
    bool    getControlForIdentifier( ControlIdentifier _nIdentifier, uno::Reference< awt::XControl >& _out_rxControl ) const;

    /** removes a control from the list, given by id
        @param _nId
            The identifier of the control to remove.
    */
    void    removeControlById( ControlIdentifier _nId );

    /** replaces a control from the list with another one
        @param _nId
            The identifier of the control to replace
        @param _rxNewControl
            the new control to put into the list
    */
    void    replaceControlById( ControlIdentifier _nId, const uno::Reference< awt::XControl >& _rxNewControl );

private:
    /** adds a control
    @param _rxControl
        the control to add to the container
    @param _pName
        pointer to the name of the control. Might be <NULL/>, in this case, a name is generated.
    @return
        the identifier of the newly inserted control
    */
    ControlIdentifier impl_addControl(
        const uno::Reference< awt::XControl >& _rxControl,
        const ::rtl::OUString*  _pName
    );

    /** finds a free identifier
        @throw uno::RuntimeException
            if no free identifier can be found
    */
    ControlIdentifier impl_getFreeIdentifier_throw();

    /** finds a free name
        @throw uno::RuntimeException
            if no free name can be found
    */
    ::rtl::OUString impl_getFreeName_throw();
};

//------------------------------------------------------------------------
UnoControlHolderList::UnoControlHolderList()
{
}

//------------------------------------------------------------------------
UnoControlHolderList::~UnoControlHolderList()
{
}

//------------------------------------------------------------------------
UnoControlHolderList::ControlIdentifier UnoControlHolderList::addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName )
{
    return impl_addControl( _rxControl, _pName );
}

//------------------------------------------------------------------------
size_t UnoControlHolderList::getControls( uno::Sequence< uno::Reference< awt::XControl > >& _out_rControls ) const
{
    _out_rControls.realloc( maControls.size() );
    uno::Reference< awt::XControl >* pControls = _out_rControls.getArray();
    for (   ControlMap::const_iterator loop = maControls.begin();
            loop != maControls.end();
            ++loop, ++pControls
        )
        *pControls = loop->second->getControl();
    return maControls.size();
}

//------------------------------------------------------------------------
size_t UnoControlHolderList::getIdentifiers( uno::Sequence< sal_Int32 >& _out_rIdentifiers ) const
{
    _out_rIdentifiers.realloc( maControls.size() );
    sal_Int32* pIndentifiers = _out_rIdentifiers.getArray();
    for (   ControlMap::const_iterator loop = maControls.begin();
            loop != maControls.end();
            ++loop, ++pIndentifiers
        )
        *pIndentifiers = loop->first;
    return maControls.size();
}

//------------------------------------------------------------------------
uno::Reference< awt::XControl > UnoControlHolderList::getControlForName( const ::rtl::OUString& _rName ) const
{
    for (   ControlMap::const_iterator loop = maControls.begin();
            loop != maControls.end();
            ++loop
        )
        if ( loop->second->getName() == _rName )
            return loop->second->getControl();
    return uno::Reference< awt::XControl >();
}

//------------------------------------------------------------------------
UnoControlHolderList::ControlIdentifier UnoControlHolderList::getControlIdentifier( const uno::Reference< awt::XControl >& _rxControl )
{
    for (   ControlMap::iterator loop = maControls.begin();
            loop != maControls.end();
            ++loop
        )
    {
        if ( loop->second->getControl().get() == _rxControl.get() )
            return loop->first;
    }
    return -1;
}

//------------------------------------------------------------------------
bool UnoControlHolderList::getControlForIdentifier( UnoControlHolderList::ControlIdentifier _nIdentifier, uno::Reference< awt::XControl >& _out_rxControl ) const
{
    ControlMap::const_iterator pos = maControls.find( _nIdentifier );
    if ( pos == maControls.end() )
        return false;
    _out_rxControl = pos->second->getControl();
    return true;
}

//------------------------------------------------------------------------
void UnoControlHolderList::removeControlById( UnoControlHolderList::ControlIdentifier _nId )
{
    ControlMap::iterator pos = maControls.find( _nId );
    DBG_ASSERT( pos != maControls.end(), "UnoControlHolderList::removeControlById: invalid id!" );
    if ( pos == maControls.end() )
        return;

    maControls.erase( pos );
}

//------------------------------------------------------------------------
void UnoControlHolderList::replaceControlById( ControlIdentifier _nId, const uno::Reference< awt::XControl >& _rxNewControl )
{
    DBG_ASSERT( _rxNewControl.is(), "UnoControlHolderList::replaceControlById: invalid new control!" );

    ControlMap::iterator pos = maControls.find( _nId );
    DBG_ASSERT( pos != maControls.end(), "UnoControlHolderList::replaceControlById: invalid id!" );
    if ( pos == maControls.end() )
        return;

    pos->second.reset( new UnoControlHolder( pos->second->getName(), _rxNewControl ) );
}

//------------------------------------------------------------------------
UnoControlHolderList::ControlIdentifier UnoControlHolderList::impl_addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName )
{
    DBG_ASSERT( _rxControl.is(), "UnoControlHolderList::impl_addControl: invalid control!" );

    ::rtl::OUString sName = _pName ? *_pName : impl_getFreeName_throw();
    sal_Int32 nId = impl_getFreeIdentifier_throw();

    maControls[ nId ] = ControlInfo( new UnoControlHolder( sName, _rxControl ) );
    return nId;
}

//------------------------------------------------------------------------
UnoControlHolderList::ControlIdentifier UnoControlHolderList::impl_getFreeIdentifier_throw()
{
    for ( ControlIdentifier candidateId = 0; candidateId < ::std::numeric_limits< ControlIdentifier >::max(); ++candidateId )
    {
        ControlMap::const_iterator existent = maControls.find( candidateId );
        if ( existent == maControls.end() )
            return candidateId;
    }
    throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "out of identifiers" ) ), NULL );
}

//------------------------------------------------------------------------
::rtl::OUString UnoControlHolderList::impl_getFreeName_throw()
{
    ::rtl::OUString name( RTL_CONSTASCII_USTRINGPARAM( "control_" ) );
    for ( ControlIdentifier candidateId = 0; candidateId < ::std::numeric_limits< ControlIdentifier >::max(); ++candidateId )
    {
        ::rtl::OUString candidateName( name + ::rtl::OUString::valueOf( candidateId ) );
        ControlMap::const_iterator loop = maControls.begin();
        for ( ; loop != maControls.end(); ++loop )
        {
            if ( loop->second->getName() == candidateName )
                break;
        }
        if ( loop == maControls.end() )
            return candidateName;
    }
    throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "out of identifiers" ) ), NULL );
}
//	----------------------------------------------------
//	Function to set the controls' visibility according
//	to the dialog's "Step" property
//	----------------------------------------------------
void implUpdateVisibility
(
	sal_Int32 nDialogStep,
	uno::Reference< awt::XControlContainer > xControlContainer
)
{
	uno::Sequence< uno::Reference< awt::XControl > >
		aCtrls = xControlContainer->getControls();
	const uno::Reference< awt::XControl >* pCtrls = aCtrls.getConstArray();
	sal_uInt32 nCtrls = aCtrls.getLength();
	sal_Bool bCompleteVisible = (nDialogStep == 0);
	for( sal_uInt32 n = 0; n < nCtrls; n++ )
	{
		uno::Reference< awt::XControl > xControl = pCtrls[ n ];

		sal_Bool bVisible = bCompleteVisible;
		if( !bVisible )
		{
			uno::Reference< awt::XControlModel > xModel( xControl->getModel() );
			uno::Reference< beans::XPropertySet > xPSet
				( xModel, uno::UNO_QUERY );
			uno::Reference< beans::XPropertySetInfo >
				xInfo = xPSet->getPropertySetInfo();
			::rtl::OUString aPropName(RTL_CONSTASCII_USTRINGPARAM( "Step" ) );
			sal_Int32 nControlStep = 0;
			if ( xInfo->hasPropertyByName( aPropName ) )
			{
				uno::Any aVal = xPSet->getPropertyValue( aPropName );
				aVal >>= nControlStep;
			}
			bVisible = (nControlStep == 0) || (nControlStep == nDialogStep);
		}

		uno::Reference< awt::XWindow> xWindow
			( xControl, uno::UNO_QUERY );
		if( xWindow.is() )
			xWindow->setVisible( bVisible );
	}
}


//	----------------------------------------------------
//	class DialogStepChangedListener
//	----------------------------------------------------
typedef ::cppu::WeakImplHelper1< beans::XPropertyChangeListener > PropertyChangeListenerHelper;

class DialogStepChangedListener: public PropertyChangeListenerHelper
{
private:
	uno::Reference< awt::XControlContainer > mxControlContainer;

public:
	DialogStepChangedListener( uno::Reference< awt::XControlContainer > xControlContainer )
		: mxControlContainer( xControlContainer ) {}

	// XEventListener
	virtual void SAL_CALL disposing( const	lang::EventObject& Source ) throw( uno::RuntimeException);

	// XPropertyChangeListener
	virtual void SAL_CALL propertyChange( const  beans::PropertyChangeEvent& evt ) throw( uno::RuntimeException);

};

void SAL_CALL DialogStepChangedListener::disposing( const  lang::EventObject& /*_rSource*/)
	throw( uno::RuntimeException)
{
	mxControlContainer.clear();
}

void SAL_CALL DialogStepChangedListener::propertyChange( const	beans::PropertyChangeEvent& evt )
	throw( uno::RuntimeException)
{
	// evt.PropertyName HAS to be "Step" because we only use the listener for that
	sal_Int32 nDialogStep = 0;
	evt.NewValue >>= nDialogStep;
	implUpdateVisibility( nDialogStep, mxControlContainer );
}

//	----------------------------------------------------
//	class UnoControlContainer
//	----------------------------------------------------
UnoControlContainer::UnoControlContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_factory )
    :UnoControlContainer_Base( i_factory )
    ,maCListeners( *this )
{
	mpControls = new UnoControlHolderList;
}

UnoControlContainer::UnoControlContainer( const uno::Reference< lang::XMultiServiceFactory >& i_factory, const uno::Reference< awt::XWindowPeer >& xP )
	:UnoControlContainer_Base( i_factory )
    ,maCListeners( *this )
{
	setPeer( xP );
	mbDisposePeer = sal_False;
	mpControls = new UnoControlHolderList;
}

UnoControlContainer::~UnoControlContainer()
{
    DELETEZ( mpControls );
}

void UnoControlContainer::ImplActivateTabControllers()
{
	sal_uInt32 nCount = maTabControllers.getLength();
	for ( sal_uInt32 n = 0; n < nCount; n++ )
	{
		maTabControllers.getArray()[n]->setContainer( this );
		maTabControllers.getArray()[n]->activateTabOrder();
	}
}

// lang::XComponent
void UnoControlContainer::dispose(	) throw(uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	lang::EventObject aDisposeEvent;
	aDisposeEvent.Source = static_cast< uno::XAggregation* >( this );

    // DG: zuerst der Welt mitteilen, dass der Container wegfliegt. Dieses ist um einiges
	// schneller wenn die Welt sowohl an den Controls als auch am Container horcht
	maDisposeListeners.disposeAndClear( aDisposeEvent );
	maCListeners.disposeAndClear( aDisposeEvent );


	uno::Sequence< uno::Reference< awt::XControl > > aCtrls = getControls();
	uno::Reference< awt::XControl >* pCtrls = aCtrls.getArray();
	uno::Reference< awt::XControl >* pCtrlsEnd = pCtrls + aCtrls.getLength();

	for( ; pCtrls < pCtrlsEnd; ++pCtrls )
	{
		removingControl( *pCtrls );
		// Control wegwerfen
		(*pCtrls)->dispose();
	}


	// alle Strukturen entfernen
    DELETEZ( mpControls );
    mpControls = new UnoControlHolderList;

	UnoControlBase::dispose();
}

// lang::XEventListener
void UnoControlContainer::disposing( const lang::EventObject& _rEvt ) throw(uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	uno::Reference< awt::XControl >  xControl( _rEvt.Source, uno::UNO_QUERY );
	if ( xControl.is() )
		removeControl( xControl );

	UnoControlBase::disposing( _rEvt );
}

// container::XContainer
void UnoControlContainer::addContainerListener( const uno::Reference< container::XContainerListener >& rxListener ) throw(uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	maCListeners.addInterface( rxListener );
}

void UnoControlContainer::removeContainerListener( const uno::Reference< container::XContainerListener >& rxListener ) throw(uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	maCListeners.removeInterface( rxListener );
}


::sal_Int32 SAL_CALL UnoControlContainer::insert( const uno::Any& _rElement ) throw (lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

    uno::Reference< awt::XControl > xControl;
    if ( !( _rElement >>= xControl ) || !xControl.is() )
        throw lang::IllegalArgumentException(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Elements must support the XControl interface." ) ),
            *this,
            1
        );

    return impl_addControl( xControl, NULL );
}

void SAL_CALL UnoControlContainer::removeByIdentifier( ::sal_Int32 _nIdentifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

    uno::Reference< awt::XControl > xControl;
    if ( !mpControls->getControlForIdentifier( _nIdentifier, xControl ) )
        throw container::NoSuchElementException(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "There is no element with the given identifier." ) ),
            *this
        );

    impl_removeControl( _nIdentifier, xControl, NULL );
}

void SAL_CALL UnoControlContainer::replaceByIdentifer( ::sal_Int32 _nIdentifier, const uno::Any& _rElement ) throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

    uno::Reference< awt::XControl > xExistentControl;
    if ( !mpControls->getControlForIdentifier( _nIdentifier, xExistentControl ) )
        throw container::NoSuchElementException(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "There is no element with the given identifier." ) ),
            *this
        );

    uno::Reference< awt::XControl > xNewControl;
    if ( !( _rElement >>= xNewControl ) )
        throw lang::IllegalArgumentException(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Elements must support the XControl interface." ) ),
            *this,
            1
        );

    removingControl( xExistentControl );

    mpControls->replaceControlById( _nIdentifier, xNewControl );

    addingControl( xNewControl );

    impl_createControlPeerIfNecessary( xNewControl );

    if ( maCListeners.getLength() )
	{
		container::ContainerEvent aEvent;
		aEvent.Source = *this;
        aEvent.Accessor <<= _nIdentifier;
		aEvent.Element <<= xNewControl;
        aEvent.ReplacedElement <<= xExistentControl;
		maCListeners.elementReplaced( aEvent );
	}
}

uno::Any SAL_CALL UnoControlContainer::getByIdentifier( ::sal_Int32 _nIdentifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

    uno::Reference< awt::XControl > xControl;
    if ( !mpControls->getControlForIdentifier( _nIdentifier, xControl ) )
        throw container::NoSuchElementException();
    return uno::makeAny( xControl );
}

uno::Sequence< ::sal_Int32 > SAL_CALL UnoControlContainer::getIdentifiers(  ) throw (uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

    uno::Sequence< ::sal_Int32 > aIdentifiers;
    mpControls->getIdentifiers( aIdentifiers );
    return aIdentifiers;
}

// container::XElementAccess
uno::Type SAL_CALL UnoControlContainer::getElementType(  ) throw (uno::RuntimeException)
{
    return awt::XControlModel::static_type();
}

::sal_Bool SAL_CALL UnoControlContainer::hasElements(  ) throw (uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
    return !mpControls->empty();
}

// awt::XControlContainer
void UnoControlContainer::setStatusText( const ::rtl::OUString& rStatusText ) throw(uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	// In der Parenthierarchie nach unten gehen
	uno::Reference< awt::XControlContainer >  xContainer( mxContext, uno::UNO_QUERY );
	if( xContainer.is() )
		xContainer->setStatusText( rStatusText );
}

uno::Sequence< uno::Reference< awt::XControl > > UnoControlContainer::getControls(  ) throw(uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
    uno::Sequence< uno::Reference< awt::XControl > > aControls;
    mpControls->getControls( aControls );
    return aControls;
}

uno::Reference< awt::XControl > UnoControlContainer::getControl( const ::rtl::OUString& rName ) throw(uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
    return mpControls->getControlForName( rName );
}

void UnoControlContainer::addingControl( const uno::Reference< awt::XControl >& _rxControl )
{
	if ( _rxControl.is() )
	{
		uno::Reference< uno::XInterface > xThis;
		OWeakAggObject::queryInterface( ::getCppuType( static_cast< uno::Reference< uno::XInterface >* >( NULL ) ) ) >>= xThis;

		_rxControl->setContext( xThis );
		_rxControl->addEventListener( this );
	}
}

void UnoControlContainer::impl_createControlPeerIfNecessary( const uno::Reference< awt::XControl >& _rxControl )
{
    OSL_PRECOND( _rxControl.is(), "UnoControlContainer::impl_createControlPeerIfNecessary: invalid control, this will crash!" );

    // if the container already has a peer, then also create a peer for the control
    uno::Reference< awt::XWindowPeer > xMyPeer( getPeer() );

    if( xMyPeer.is() )
	{
        _rxControl->createPeer( NULL, xMyPeer );
		ImplActivateTabControllers();
	}

}

sal_Int32 UnoControlContainer::impl_addControl( const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pName )
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
    UnoControlHolderList::ControlIdentifier id = mpControls->addControl( _rxControl, _pName );

    addingControl( _rxControl );

    impl_createControlPeerIfNecessary( _rxControl );

	if ( maCListeners.getLength() )
	{
		container::ContainerEvent aEvent;
		aEvent.Source = *this;
        _pName ? ( aEvent.Accessor <<= *_pName ) : ( aEvent.Accessor <<= (sal_Int32)id );
		aEvent.Element <<= _rxControl;
		maCListeners.elementInserted( aEvent );
	}

    return id;
}

void UnoControlContainer::addControl( const ::rtl::OUString& rName, const uno::Reference< awt::XControl >& rControl ) throw(uno::RuntimeException)
{
	if ( rControl.is() )
        impl_addControl( rControl, &rName );
}

void UnoControlContainer::removingControl( const uno::Reference< awt::XControl >& _rxControl )
{
	if ( _rxControl.is() )
	{
		_rxControl->removeEventListener( this );
		_rxControl->setContext( NULL );
	}
}

void UnoControlContainer::impl_removeControl( sal_Int32 _nId, const uno::Reference< awt::XControl >& _rxControl, const ::rtl::OUString* _pNameAccessor )
{
#ifdef DBG_UTIL
    {
        uno::Reference< awt::XControl > xControl;
        bool bHas = mpControls->getControlForIdentifier( _nId, xControl );
        DBG_ASSERT( bHas && xControl == _rxControl, "UnoControlContainer::impl_removeControl: inconsistency in the parameters!" );
    }
#endif
	removingControl( _rxControl );

    mpControls->removeControlById( _nId );

    if ( maCListeners.getLength() )
	{
		container::ContainerEvent aEvent;
		aEvent.Source = *this;
        _pNameAccessor ? ( aEvent.Accessor <<= *_pNameAccessor ) : ( aEvent.Accessor <<= _nId );
		aEvent.Element <<= _rxControl;
		maCListeners.elementRemoved( aEvent );
	}
}

void UnoControlContainer::removeControl( const uno::Reference< awt::XControl >& _rxControl ) throw(uno::RuntimeException)
{
	if ( _rxControl.is() )
	{
		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

        UnoControlHolderList::ControlIdentifier id = mpControls->getControlIdentifier( _rxControl );
        if ( id != -1 )
            impl_removeControl( id, _rxControl, NULL );
	}
}



// awt::XUnoControlContainer
void UnoControlContainer::setTabControllers( const uno::Sequence< uno::Reference< awt::XTabController > >& TabControllers ) throw(uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	maTabControllers = TabControllers;
}

uno::Sequence< uno::Reference< awt::XTabController > > UnoControlContainer::getTabControllers(  ) throw(uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	return maTabControllers;
}

void UnoControlContainer::addTabController( const uno::Reference< awt::XTabController >& TabController ) throw(uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	sal_uInt32 nCount = maTabControllers.getLength();
	maTabControllers.realloc( nCount + 1 );
	maTabControllers[ nCount ] = TabController;
}

void UnoControlContainer::removeTabController( const uno::Reference< awt::XTabController >& TabController ) throw(uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	sal_uInt32 nCount = maTabControllers.getLength();
	const uno::Reference< awt::XTabController >* pLoop = maTabControllers.getConstArray();
	for ( sal_uInt32 n = 0; n < nCount; ++n, ++pLoop )
	{
		if( pLoop->get() == TabController.get() )
		{
			::comphelper::removeElementAt( maTabControllers, n );
			break;
		}
	}
}

// awt::XControl
void UnoControlContainer::createPeer( const uno::Reference< awt::XToolkit >& rxToolkit, const uno::Reference< awt::XWindowPeer >& rParent ) throw(uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	if( !getPeer().is() )
	{
		sal_Bool bVis = maComponentInfos.bVisible;
		if( bVis )
			UnoControl::setVisible( sal_False );
		// eigenes Peer erzeugen
		UnoControl::createPeer( rxToolkit, rParent );

		// alle Peers der Childs erzeugen
		if ( !mbCreatingCompatiblePeer )
		{
			// Evaluate "Step" property
			uno::Reference< awt::XControlModel > xModel( getModel() );
			uno::Reference< beans::XPropertySet > xPSet
				( xModel, uno::UNO_QUERY );
			uno::Reference< beans::XPropertySetInfo >
				xInfo = xPSet->getPropertySetInfo();
			::rtl::OUString aPropName(RTL_CONSTASCII_USTRINGPARAM( "Step" ) );
			if ( xInfo->hasPropertyByName( aPropName ) )
			{
				::com::sun::star::uno::Any aVal = xPSet->getPropertyValue( aPropName );
				sal_Int32 nDialogStep = 0;
				aVal >>= nDialogStep;
				uno::Reference< awt::XControlContainer > xContainer =
					SAL_STATIC_CAST( awt::XControlContainer*, this );
				implUpdateVisibility( nDialogStep, xContainer );

				uno::Reference< beans::XPropertyChangeListener > xListener =
					SAL_STATIC_CAST( beans::XPropertyChangeListener*,
						new DialogStepChangedListener( xContainer ) );
				xPSet->addPropertyChangeListener( aPropName, xListener );
			}

			uno::Sequence< uno::Reference< awt::XControl > > aCtrls = getControls();
			sal_uInt32 nCtrls = aCtrls.getLength();
			for( sal_uInt32 n = 0; n < nCtrls; n++ )
				aCtrls.getArray()[n]->createPeer( rxToolkit, getPeer() );

			uno::Reference< awt::XVclContainerPeer >  xC( getPeer(), uno::UNO_QUERY );
            OSL_ENSURE(xC.is(),"Peer isn't valid. Please check!");

			xC->enableDialogControl( sal_True );
			ImplActivateTabControllers();
		}

		if( bVis && !isDesignMode() )
			UnoControl::setVisible( sal_True );
	}
}


// awt::XWindow
void UnoControlContainer::setVisible( sal_Bool bVisible ) throw(uno::RuntimeException)
{
	::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

	UnoControl::setVisible( bVisible );
	if( !mxContext.is() && bVisible )
		// Es ist ein TopWindow, also automatisch anzeigen
		createPeer( uno::Reference< awt::XToolkit > (), uno::Reference< awt::XWindowPeer > () );
}
