/**************************************************************
 * 
 * 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_svx.hxx"
#include <svx/AccessibleControlShape.hxx>
#include <svx/AccessibleShapeInfo.hxx>
#include "svx/DescriptionGenerator.hxx"
#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/form/FormComponentType.hpp>
#include <com/sun/star/reflection/XProxyFactory.hpp>
#include <com/sun/star/container/XContainer.hpp>
#include <comphelper/processfactory.hxx>
#include <unotools/accessiblestatesethelper.hxx>
#include <svx/svdouno.hxx>
#include "svx/unoapi.hxx"
#include <svx/ShapeTypeHandler.hxx>
#include <svx/SvxShapeTypes.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <comphelper/accessiblewrapper.hxx>
#include <svx/svdview.hxx>
#include <svx/svdpagv.hxx>
#include "svx/svdstr.hrc"
#include <algorithm>
#ifndef _COMPHELPER_PROPERTY_HXX_
#include <comphelper/property.hxx>
#endif
#ifndef _COMPHELPER_TYPES_HXX_
#include <comphelper/types.hxx>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XCHILD_HPP_
#include <com/sun/star/container/XChild.hpp>
#endif
#ifndef _UTL_ACCESSIBLERELATIONSETHELPER_HXX_
#include <unotools/accessiblerelationsethelper.hxx>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HPP_
#include <com/sun/star/accessibility/AccessibleRelationType.hpp>
#endif
using namespace ::comphelper;
using namespace ::accessibility;
using namespace	::com::sun::star::accessibility;
using namespace	::com::sun::star::uno;
using namespace	::com::sun::star::awt;
using namespace	::com::sun::star::beans;
using namespace	::com::sun::star::util;
using namespace	::com::sun::star::lang;
using namespace	::com::sun::star::reflection;
using namespace	::com::sun::star::drawing;
using namespace	::com::sun::star::container;

//--------------------------------------------------------------------
namespace
{
	//................................................................
	const ::rtl::OUString& lcl_getNamePropertyName( )
	{
		static ::rtl::OUString s_sNamePropertyName( RTL_CONSTASCII_USTRINGPARAM( "Name" ) );
		return s_sNamePropertyName;
	}
	//................................................................
	const ::rtl::OUString& lcl_getDescPropertyName( )
	{
		static ::rtl::OUString s_sDescPropertyDesc( RTL_CONSTASCII_USTRINGPARAM( "HelpText" ) );
		return s_sDescPropertyDesc;
	}
	//................................................................
	const ::rtl::OUString& lcl_getLabelPropertyName( )
	{
		static ::rtl::OUString s_sLabelPropertyLabel( RTL_CONSTASCII_USTRINGPARAM( "Label" ) );
		return s_sLabelPropertyLabel;
	}
	//................................................................
	const ::rtl::OUString& lcl_getLabelControlPropertyName( )
	{
		static ::rtl::OUString s_sLabelControlPropertyLabel( RTL_CONSTASCII_USTRINGPARAM( "LabelControl" ) );
		return s_sLabelControlPropertyLabel;
	}
	//................................................................
	// return the property which should be used as AccessibleName
	const ::rtl::OUString& lcl_getPreferredAccNameProperty( const Reference< XPropertySetInfo >& _rxPSI )
	{
		if ( _rxPSI.is() && _rxPSI->hasPropertyByName( lcl_getLabelPropertyName() ) )
			return lcl_getLabelPropertyName();
		else
			return lcl_getNamePropertyName();
	}

	//................................................................
	// determines whether or not a state which belongs to the inner context needs to be forwarded to the "composed"
	// context
	sal_Bool	isComposedState( const sal_Int16 _nState )
	{
		return	(	( AccessibleStateType::INVALID != _nState )
				&&	( AccessibleStateType::DEFUNC != _nState )
				&&	( AccessibleStateType::ICONIFIED != _nState )
				&&	( AccessibleStateType::RESIZABLE != _nState )
				&&	( AccessibleStateType::SELECTABLE != _nState )
				&&	( AccessibleStateType::SHOWING != _nState )
				&&	( AccessibleStateType::MANAGES_DESCENDANTS != _nState )
				&&	( AccessibleStateType::VISIBLE != _nState )
				);
	}

	//................................................................
	/** determines whether the given control is in alive mode
	*/
	inline	sal_Bool	isAliveMode( const Reference< XControl >& _rxControl )
	{
		OSL_PRECOND( _rxControl.is(), "AccessibleControlShape::isAliveMode: invalid control" );
		return _rxControl.is() && !_rxControl->isDesignMode();
	}
}

//=============================================================================
//= AccessibleControlShape
//=============================================================================

//-----------------------------------------------------------------------------
AccessibleControlShape::AccessibleControlShape (
    const AccessibleShapeInfo& rShapeInfo,
    const AccessibleShapeTreeInfo& rShapeTreeInfo)
    :      AccessibleShape (rShapeInfo, rShapeTreeInfo)
	,	m_bListeningForName( sal_False )
	,	m_bListeningForDesc( sal_False )
	,	m_bMultiplexingStates( sal_False )
    ,   m_bDisposeNativeContext( sal_False )
    ,   m_bWaitingForControl( sal_False )
{
	m_pChildManager = new OWrappedAccessibleChildrenManager( getProcessServiceFactory() );
	m_pChildManager->acquire();

	osl_incrementInterlockedCount( &m_refCount );
	{
		m_pChildManager->setOwningAccessible( this );
	}
	osl_decrementInterlockedCount( &m_refCount );
}

//-----------------------------------------------------------------------------
AccessibleControlShape::~AccessibleControlShape (void)
{
	m_pChildManager->release();
	m_pChildManager = NULL;

	if ( m_xControlContextProxy.is() )
		m_xControlContextProxy->setDelegator( NULL );
	m_xControlContextProxy.clear();
    m_xControlContextTypeAccess.clear();
    m_xControlContextComponent.clear();
		// this should remove the _only_ three "real" reference (means not delegated to
		// ourself) to this proxy, and thus delete it
}

//-----------------------------------------------------------------------------
SdrObject* AccessibleControlShape::getSdrObject() const
{
    return GetSdrObjectFromXShape (mxShape);
}

namespace {
    Reference< XContainer > lcl_getControlContainer( const Window* _pWin, const SdrView* _pView )
    {
        Reference< XContainer > xReturn;
        DBG_ASSERT( _pView, "lcl_getControlContainer: invalid view!" );
        if ( _pView  && _pView->GetSdrPageView())
        {
			xReturn = xReturn.query( _pView->GetSdrPageView()->GetControlContainer( *_pWin ) );
        }
        return xReturn;
    }
}

//-----------------------------------------------------------------------------
void AccessibleControlShape::Init()
{
	AccessibleShape::Init();

	OSL_ENSURE( !m_xControlContextProxy.is(), "AccessibleControlShape::Init: already initialized!" );
	try
	{
		// What we need to do here is merge the functionality of the AccessibleContext of our UNO control
		// with our own AccessibleContext-related functionality.
		//
		// The problem is that we do not know the interfaces our "inner" context supports - this may be any
		// XAccessibleXXX interface (or even any other) which makes sense for it.
		//
		// In theory, we could implement all possible interfaces ourself, and re-route all functionality to
		// the inner context (except those we implement ourself, like XAccessibleComponent). But this is in no
		// way future-proof - as soon as an inner context appears which implements an additional interface,
		// we would need to adjust our implementation to support this new interface, too. Bad idea.
		//
		// The usual solution for such a problem is aggregation. Aggregation means using UNO's own meachnisms
		// for merging an inner with an outer component, and get a component which behaves as it is exactly one.
		// This is what XAggregation is for. Unfortunately, aggregation requires _exact_ control over the ref count
		// of the inner object, which we do not have at all.
		// Bad, too.
		//
		// But there is a solution: com.sun.star.reflection.ProxyFactory. This service is able to create a proxy
		// for any component, which supports _exactly_ the same interfaces as the component. In addition, it can
		// be aggregated, as by definition the proxy's ref count is exactly 1 when returned from the factory.
		// Sounds better. Though this yields the problem of slightly degraded performance, it's the only solution
		// I'm aware of at the moment .....
		//
		// 98750 - 30.04.2002 - fs@openoffice.org
		//

		// get the control which belongs to our model (relative to our view)
		const Window* pViewWindow = maShapeTreeInfo.GetWindow();
		SdrUnoObj* pUnoObjectImpl = PTR_CAST( SdrUnoObj, getSdrObject() );
        SdrView* pView = maShapeTreeInfo.GetSdrView();
		OSL_ENSURE( pView && pViewWindow && pUnoObjectImpl, "AccessibleControlShape::Init: no view, or no view window, no SdrUnoObj!" );

		if ( pView && pViewWindow && pUnoObjectImpl )
		{
			// .................................................................
			// get the context of the control - it will be our "inner" context
			m_xUnoControl = pUnoObjectImpl->GetUnoControl( *pView, *pViewWindow );

            if ( !m_xUnoControl.is() )
            {
                // the control has not yet been created. Though speaking strictly, it is a bug that
                // our instance here is created without an existing control (because an AccessibleControlShape
                // is a representation of a view object, and can only live if the view it should represent
                // is complete, which implies a living control), it's by far the easiest and most riskless way
                // to fix this here in this class.
                // Okay, we will add as listener to the control container where we expect our control to appear.
                OSL_ENSURE( !m_bWaitingForControl, "AccessibleControlShape::Init: already waiting for the control!" );

                Reference< XContainer > xControlContainer = lcl_getControlContainer( pViewWindow, maShapeTreeInfo.GetSdrView() );
                OSL_ENSURE( xControlContainer.is(), "AccessibleControlShape::Init: unable to find my ControlContainer!" );
                if ( xControlContainer.is() )
                {
                    xControlContainer->addContainerListener( this );
                    m_bWaitingForControl = sal_True;
                }
            }
            else
            {
			    Reference< XModeChangeBroadcaster > xControlModes( m_xUnoControl, UNO_QUERY );
			    Reference< XAccessible > xControlAccessible( xControlModes, UNO_QUERY );
			    Reference< XAccessibleContext > xNativeControlContext;
			    if ( xControlAccessible.is() )
				    xNativeControlContext = xControlAccessible->getAccessibleContext();
			    OSL_ENSURE( xNativeControlContext.is(), "AccessibleControlShape::Init: no AccessibleContext for the control!" );
			    m_aControlContext = WeakReference< XAccessibleContext >( xNativeControlContext );

			    // .................................................................
			    // add as listener to the context - we want to multiplex some states
			    if ( isAliveMode( m_xUnoControl ) && xNativeControlContext.is() )
			    {	// (but only in alive mode)
				    startStateMultiplexing( );
			    }

			    // now that we have all information about our control, do some adjustments
			    adjustAccessibleRole();
			    initializeComposedState();

			    // some initialization for our child manager, which is used in alive mode only
			    if ( isAliveMode( m_xUnoControl ) )
			    {
				    Reference< XAccessibleStateSet > xStates( getAccessibleStateSet( ) );
				    OSL_ENSURE( xStates.is(), "AccessibleControlShape::AccessibleControlShape: no inner state set!" );
				    m_pChildManager->setTransientChildren( !xStates.is() || xStates->contains( AccessibleStateType::MANAGES_DESCENDANTS ) );
			    }

			    // .................................................................
			    // finally, aggregate a proxy for the control context
			    // first a factory for the proxy
			    Reference< XProxyFactory > xFactory;
			    xFactory = xFactory.query( createProcessComponent( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.reflection.ProxyFactory" ) ) ) );
			    OSL_ENSURE( xFactory.is(), "AccessibleControlShape::Init: could not create a proxy factory!" );
			    // then the proxy itself
			    if ( xFactory.is() && xNativeControlContext.is() )
			    {
				    m_xControlContextProxy = xFactory->createProxy( xNativeControlContext );
                    OSL_VERIFY( xNativeControlContext->queryInterface( ::getCppuType( &m_xControlContextTypeAccess ) ) >>= m_xControlContextTypeAccess );
                    OSL_VERIFY( xNativeControlContext->queryInterface( ::getCppuType( &m_xControlContextComponent ) ) >>= m_xControlContextComponent );

				    // aggregate the proxy
				    osl_incrementInterlockedCount( &m_refCount );
				    if ( m_xControlContextProxy.is() )
				    {
					    // At this point in time, the proxy has a ref count of exactly one - in m_xControlContextProxy.
					    // Remember to _not_ reset this member unles the delegator of the proxy has been reset, too!
					    m_xControlContextProxy->setDelegator( *this );
				    }
				    osl_decrementInterlockedCount( &m_refCount );

				    m_bDisposeNativeContext = sal_True;

				    // Finally, we need to add ourself as mode listener to the control. In case the mode switches,
				    // we need to dispose ourself.
				    xControlModes->addModeChangeListener( this );
			    }
            }
		}
	}
	catch( const Exception& )
	{
		OSL_ENSURE( sal_False, "AccessibleControlShape::Init: could not \"aggregate\" the controls XAccessibleContext!" );
	}
}

//-----------------------------------------------------------------------------
Reference< XAccessibleContext > SAL_CALL AccessibleControlShape::getAccessibleContext(void) throw (RuntimeException)
{
	return AccessibleShape::getAccessibleContext ();
}


//-----------------------------------------------------------------------------
void SAL_CALL AccessibleControlShape::grabFocus(void)  throw (RuntimeException)
{
	if ( !m_xUnoControl.is() || !isAliveMode( m_xUnoControl ) )
	{
		// in design mode, we simply forward the request to the base class
		AccessibleShape::grabFocus();
	}
	else
	{
		Reference< XWindow > xWindow( m_xUnoControl, UNO_QUERY );
		OSL_ENSURE( xWindow.is(), "AccessibleControlShape::grabFocus: invalid control!" );
		if ( xWindow.is() )
			xWindow->setFocus();
	}
}

//-----------------------------------------------------------------------------
::rtl::OUString SAL_CALL AccessibleControlShape::getImplementationName(void) throw (RuntimeException)
{
	return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.accessibility.AccessibleControlShape" ) );
}

//-----------------------------------------------------------------------------
::rtl::OUString AccessibleControlShape::CreateAccessibleBaseName(void) throw (RuntimeException)
{
    ::rtl::OUString sName;

    ShapeTypeId nShapeType = ShapeTypeHandler::Instance().GetTypeId (mxShape);
    switch (nShapeType)
    {
        case DRAWING_CONTROL:
            sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("ControlShape"));
            break;
        default:
            sName = ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("UnknownAccessibleControlShape"));
            Reference< XShapeDescriptor > xDescriptor (mxShape, UNO_QUERY);
            if (xDescriptor.is())
                sName += ::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM(": "))
                    + xDescriptor->getShapeType();
    }

    return sName;
}




//--------------------------------------------------------------------
::rtl::OUString
    AccessibleControlShape::CreateAccessibleDescription (void)
    throw (RuntimeException)
{
    DescriptionGenerator aDG (mxShape);
    ShapeTypeId nShapeType = ShapeTypeHandler::Instance().GetTypeId (mxShape);
    switch (nShapeType)
    {
        case DRAWING_CONTROL:
		{
			// check if we can obtain the "Desc" property from the model
			::rtl::OUString sDesc( getControlModelStringProperty( lcl_getDescPropertyName() ) );
			if ( !sDesc.getLength() )
			{	// no -> use the default
				aDG.Initialize (STR_ObjNameSingulUno);
				aDG.AddProperty (::rtl::OUString::createFromAscii ("ControlBackground"),
					DescriptionGenerator::COLOR,
					::rtl::OUString());
				aDG.AddProperty (::rtl::OUString::createFromAscii ("ControlBorder"),
					DescriptionGenerator::INTEGER,
					::rtl::OUString());
			}
			// ensure that we are listening to the Name property
			m_bListeningForDesc = ensureListeningState( m_bListeningForDesc, sal_True, lcl_getDescPropertyName() );
		}
		break;

        default:
            aDG.Initialize (::rtl::OUString::createFromAscii (
                "Unknown accessible control shape"));
            Reference< XShapeDescriptor > xDescriptor (mxShape, UNO_QUERY);
            if (xDescriptor.is())
            {
                aDG.AppendString (::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("service name=")));
                aDG.AppendString (xDescriptor->getShapeType());
            }
    }

    return aDG();
}

//--------------------------------------------------------------------
IMPLEMENT_FORWARD_REFCOUNT( AccessibleControlShape, AccessibleShape )
IMPLEMENT_GET_IMPLEMENTATION_ID( AccessibleControlShape )

//--------------------------------------------------------------------
void SAL_CALL AccessibleControlShape::propertyChange( const PropertyChangeEvent& _rEvent ) throw (RuntimeException)
{
	::osl::MutexGuard aGuard( maMutex );

	// check if it is the name or the description
	if	(	_rEvent.PropertyName.equals( lcl_getNamePropertyName() )
		||	_rEvent.PropertyName.equals( lcl_getLabelPropertyName( ) )
		)
	{
		SetAccessibleName(
            CreateAccessibleName(),
            AccessibleContextBase::AutomaticallyCreated);
	}
	else if ( _rEvent.PropertyName.equals( lcl_getDescPropertyName() ) )
	{
		SetAccessibleDescription(
            CreateAccessibleDescription(),
            AccessibleContextBase::AutomaticallyCreated);
	}
#if OSL_DEBUG_LEVEL > 0
	else
	{
		OSL_ENSURE( sal_False, "AccessibleControlShape::propertyChange: where did this come from?" );
	}
#endif
}

//--------------------------------------------------------------------
Any SAL_CALL AccessibleControlShape::queryInterface( const Type& _rType ) throw (RuntimeException)
{
	Any aReturn = AccessibleShape::queryInterface( _rType );
	if ( !aReturn.hasValue() )
	{
		aReturn = AccessibleControlShape_Base::queryInterface( _rType );
		if ( !aReturn.hasValue() && m_xControlContextProxy.is() )
			aReturn = m_xControlContextProxy->queryAggregation( _rType );
	}
	return aReturn;
}

//--------------------------------------------------------------------
Sequence< Type > SAL_CALL AccessibleControlShape::getTypes() throw (RuntimeException)
{
	Sequence< Type > aShapeTypes = AccessibleShape::getTypes();
	Sequence< Type > aOwnTypes = AccessibleControlShape_Base::getTypes();

	Sequence< Type > aAggregateTypes;
    if ( m_xControlContextTypeAccess.is() )
		aAggregateTypes = m_xControlContextTypeAccess->getTypes();

	Sequence< Type > aAllTypes = concatSequences( aShapeTypes, aOwnTypes, aAggregateTypes );

	// remove duplicates
	Type* pBegin = aAllTypes.getArray();
	Type* pEnd = pBegin + aAllTypes.getLength();
	while ( pBegin != pEnd )
	{
		Type aThisRoundType = *pBegin;
		if ( ++pBegin != pEnd )
		{
			pEnd = ::std::remove( pBegin, pEnd, aThisRoundType );
			// now all types between begin and (the old) end which equal aThisRoundType
			// are moved behind the new end
		}
	}
	aAllTypes.realloc( pEnd - aAllTypes.getArray() );

	return aAllTypes;
}

//--------------------------------------------------------------------
void SAL_CALL AccessibleControlShape::notifyEvent( const AccessibleEventObject& _rEvent ) throw (RuntimeException)
{
	if ( AccessibleEventId::STATE_CHANGED == _rEvent.EventId )
	{
		// multiplex this change
		sal_Int16 nLostState( 0 ), nGainedState( 0 );
		_rEvent.OldValue >>= nLostState;
		_rEvent.NewValue >>= nGainedState;

		// don't multiplex states which the inner context is not resposible for
		if	( isComposedState( nLostState ) )
			AccessibleShape::ResetState( nLostState );

		if	( isComposedState( nGainedState ) )
			AccessibleShape::SetState( nGainedState );
	}
	else
	{
		AccessibleEventObject aTranslatedEvent( _rEvent );

		{
			::osl::MutexGuard aGuard( maMutex );

            // let the child manager translate the event
			aTranslatedEvent.Source = *this;
			m_pChildManager->translateAccessibleEvent( _rEvent, aTranslatedEvent );

            // see if any of these notifications affect our child manager
			m_pChildManager->handleChildNotification( _rEvent );
		}

		FireEvent( aTranslatedEvent );
	}
}

//--------------------------------------------------------------------
void SAL_CALL AccessibleControlShape::modeChanged( const ModeChangeEvent& _rSource ) throw (RuntimeException)
{
	// did it come from our inner context (the real one, not it's proxy!)?
    OSL_TRACE ("AccessibleControlShape::modeChanged");
	Reference< XControl > xSource( _rSource.Source, UNO_QUERY );	// for faster compare
	if ( xSource.get() == m_xUnoControl.get() )
	{
		// If our "pseudo-aggregated" inner context does not live anymore,
		// we don't want to live, too.  This is accomplished by asking our
		// parent to replace this object with a new one.  Disposing this
		// object and sending notifications about the replacement are in
		// the responsibility of our parent.
		OSL_VERIFY( mpParent->ReplaceChild ( this, mxShape, mnIndex, maShapeTreeInfo ) );
	}
#if OSL_DEBUG_LEVEL > 0
	else
		OSL_ENSURE( sal_False, "AccessibleControlShape::modeChanged: where did this come from?" );
#endif
}

//--------------------------------------------------------------------
void SAL_CALL AccessibleControlShape::disposing (const EventObject& _rSource) throw (RuntimeException)
{
	AccessibleShape::disposing( _rSource );
}

//--------------------------------------------------------------------
sal_Bool AccessibleControlShape::ensureListeningState(
		const sal_Bool _bCurrentlyListening, const sal_Bool _bNeedNewListening,
		const ::rtl::OUString& _rPropertyName )
{
	if ( ( _bCurrentlyListening == _bNeedNewListening ) || !ensureControlModelAccess() )
		//  nothing to do
		return _bCurrentlyListening;

	try
	{
		if ( !m_xModelPropsMeta.is() || m_xModelPropsMeta->hasPropertyByName( _rPropertyName ) )
		{
			// add or revoke as listener
			if ( _bNeedNewListening )
				m_xControlModel->addPropertyChangeListener( _rPropertyName, static_cast< XPropertyChangeListener* >( this ) );
			else
				m_xControlModel->removePropertyChangeListener( _rPropertyName, static_cast< XPropertyChangeListener* >( this ) );
		}
		else
			OSL_ENSURE( sal_False, "AccessibleControlShape::ensureListeningState: this property does not exist at this model!" );
	}
	catch( const Exception& e )
	{
		(void)e;    // make compiler happy
		OSL_ENSURE( sal_False, "AccessibleControlShape::ensureListeningState: could not change the listening state!" );
	}

	return _bNeedNewListening;
}

//--------------------------------------------------------------------
sal_Int32 SAL_CALL AccessibleControlShape::getAccessibleChildCount( ) throw(RuntimeException)
{
    if ( !m_xUnoControl.is() )
        return 0;
    else if ( !isAliveMode( m_xUnoControl ) )
		// no special action required when in design mode
		return AccessibleShape::getAccessibleChildCount( );
	else
	{
		// in alive mode, we have the full control over our children - they are determined by the children
		// of the context of our UNO control
		Reference< XAccessibleContext > xControlContext( m_aControlContext );
		OSL_ENSURE( xControlContext.is(), "AccessibleControlShape::getAccessibleChildCount: control context already dead! How this!" );
		return xControlContext.is() ? xControlContext->getAccessibleChildCount() : 0;
	}
}

//--------------------------------------------------------------------
Reference< XAccessible > SAL_CALL AccessibleControlShape::getAccessibleChild( sal_Int32 i ) throw(IndexOutOfBoundsException, RuntimeException)
{
	Reference< XAccessible > xChild;
    if ( !m_xUnoControl.is() )
    {
        throw IndexOutOfBoundsException();
    }
	if ( !isAliveMode( m_xUnoControl ) )
	{
		// no special action required when in design mode - let the base class handle this
		xChild = AccessibleShape::getAccessibleChild( i );
	}
	else
	{
		// in alive mode, we have the full control over our children - they are determined by the children
		// of the context of our UNO control

		Reference< XAccessibleContext > xControlContext( m_aControlContext );
		OSL_ENSURE( xControlContext.is(), "AccessibleControlShape::getAccessibleChildCount: control context already dead! How this!" );
		if ( xControlContext.is() )
		{
			Reference< XAccessible > xInnerChild( xControlContext->getAccessibleChild( i ) );
			OSL_ENSURE( xInnerChild.is(), "AccessibleControlShape::getAccessibleChild: control context returned nonsense!" );
			if ( xInnerChild.is() )
			{
				// we need to wrap this inner child into an own implementation
				xChild = m_pChildManager->getAccessibleWrapperFor( xInnerChild );
			}
		}
	}

#if OSL_DEBUG_LEVEL > 0
    sal_Int32 nChildIndex = -1;
    Reference< XAccessibleContext > xContext;
    if ( xChild.is() )
        xContext = xChild->getAccessibleContext( );
    if ( xContext.is() )
        nChildIndex = xContext->getAccessibleIndexInParent( );
    OSL_ENSURE( nChildIndex == i, "AccessibleControlShape::getAccessibleChild: index mismatch!" );
#endif
	return xChild;
}

//--------------------------------------------------------------------
Reference< XAccessibleRelationSet > SAL_CALL AccessibleControlShape::getAccessibleRelationSet(  ) throw (RuntimeException)
{
	// TODO
	// return AccessibleShape::getAccessibleRelationSet( );
    utl::AccessibleRelationSetHelper* pRelationSetHelper = new utl::AccessibleRelationSetHelper;
	ensureControlModelAccess();
	AccessibleControlShape* pCtlAccShape = GetLabeledByControlShape();
	if(pCtlAccShape)
	{
		Reference < XAccessible > xAcc (pCtlAccShape->getAccessibleContext(), UNO_QUERY);

		::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > aSequence(1);
		aSequence[0] = xAcc;
		if( getAccessibleRole() == AccessibleRole::RADIO_BUTTON )
		{
			pRelationSetHelper->AddRelation( AccessibleRelation( AccessibleRelationType::MEMBER_OF, aSequence ) );
		}
		else
		{
			pRelationSetHelper->AddRelation( AccessibleRelation( AccessibleRelationType::LABELED_BY, aSequence ) );
		}
	}
	Reference< XAccessibleRelationSet > xSet = pRelationSetHelper;
	return xSet;
}

//--------------------------------------------------------------------
::rtl::OUString AccessibleControlShape::CreateAccessibleName (void) throw (RuntimeException)
{
	ensureControlModelAccess();
	::rtl::OUString sName;
	if ( getAccessibleRole() != AccessibleRole::SHAPE	
		&& getAccessibleRole() != AccessibleRole::RADIO_BUTTON  )
	{
		AccessibleControlShape* pCtlAccShape = GetLabeledByControlShape();
		if(pCtlAccShape)
		{
			sName = pCtlAccShape->CreateAccessibleName();
		}
	}
	if(sName.getLength() == 0)
	{
		// check if we can obtain the "Name" resp. "Label" property from the model
		const ::rtl::OUString& rAccNameProperty = lcl_getPreferredAccNameProperty( m_xModelPropsMeta );
		sName = getControlModelStringProperty( rAccNameProperty );
		if ( !sName.getLength() )
		{	// no -> use the default
			sName = AccessibleShape::CreateAccessibleName();
		}
	}
	// now that somebody first asked us for our name, ensure that we are listening to name changes on the model
	m_bListeningForName = ensureListeningState( m_bListeningForName, sal_True, lcl_getPreferredAccNameProperty( m_xModelPropsMeta ) );

	return sName;
}

//--------------------------------------------------------------------
void SAL_CALL AccessibleControlShape::disposing (void)
{
	// ensure we're not listening
	m_bListeningForName = ensureListeningState( m_bListeningForName, sal_False, lcl_getPreferredAccNameProperty( m_xModelPropsMeta ) );
	m_bListeningForDesc = ensureListeningState( m_bListeningForDesc, sal_False, lcl_getDescPropertyName() );

	if ( m_bMultiplexingStates )
		stopStateMultiplexing( );

	// dispose the child cache/map
	m_pChildManager->dispose();

	// release the model
	m_xControlModel.clear();
	m_xModelPropsMeta.clear();
	m_aControlContext = WeakReference< XAccessibleContext >();

    // stop listening at the control container (should never be necessary here, but who knows ....)
    if ( m_bWaitingForControl )
    {
        OSL_ENSURE( sal_False, "AccessibleControlShape::disposing: this should never happen!" );
        Reference< XContainer > xContainer = lcl_getControlContainer( maShapeTreeInfo.GetWindow(), maShapeTreeInfo.GetSdrView() );
        if ( xContainer.is() )
        {
            m_bWaitingForControl = sal_False;
            xContainer->removeContainerListener( this );
        }
    }

	// forward the disposel to our inner context
	if ( m_bDisposeNativeContext )
	{
		// don't listen for mode changes anymore
		Reference< XModeChangeBroadcaster > xControlModes( m_xUnoControl, UNO_QUERY );
		OSL_ENSURE( xControlModes.is(), "AccessibleControlShape::disposing: don't have an mode broadcaster anymore!" );
		if ( xControlModes.is() )
			xControlModes->removeModeChangeListener( this );

        if ( m_xControlContextComponent.is() )
			m_xControlContextComponent->dispose();
		// do _not_ clear m_xControlContextProxy! This has to be done in the dtor for correct ref-count handling

		// no need to dispose the proxy/inner context anymore
		m_bDisposeNativeContext = sal_False;
	}

	m_xUnoControl.clear();

	// let the base do it's stuff
	AccessibleShape::disposing();
}

//--------------------------------------------------------------------
sal_Bool AccessibleControlShape::ensureControlModelAccess() SAL_THROW(())
{
	if ( m_xControlModel.is() )
		return sal_True;

	try
	{
		Reference< XControlShape > xShape( mxShape, UNO_QUERY );
		if ( xShape.is() )
			m_xControlModel = m_xControlModel.query( xShape->getControl() );

		if ( m_xControlModel.is() )
			m_xModelPropsMeta = m_xControlModel->getPropertySetInfo();
	}
	catch( const Exception& e )
	{
		(void)e;    // make compiler happy
		OSL_ENSURE( sal_False, "AccessibleControlShape::ensureControlModelAccess: caught an exception!" );
	}

	return m_xControlModel.is();
}

//--------------------------------------------------------------------
void AccessibleControlShape::startStateMultiplexing()
{
	OSL_PRECOND( !m_bMultiplexingStates, "AccessibleControlShape::startStateMultiplexing: already multiplexing!" );

#if OSL_DEBUG_LEVEL > 0
	// we should have a control, and it should be in alive mode
	OSL_PRECOND( isAliveMode( m_xUnoControl ),
		"AccessibleControlShape::startStateMultiplexing: should be done in alive mode only!" );
#endif
	// we should have the native context of the control
	Reference< XAccessibleEventBroadcaster > xBroadcaster( m_aControlContext.get(), UNO_QUERY );
	OSL_ENSURE( xBroadcaster.is(), "AccessibleControlShape::startStateMultiplexing: no AccessibleEventBroadcaster on the native context!" );

	if ( xBroadcaster.is() )
	{
		xBroadcaster->addEventListener( this );
		m_bMultiplexingStates = sal_True;
	}
}

//--------------------------------------------------------------------
void AccessibleControlShape::stopStateMultiplexing()
{
	OSL_PRECOND( m_bMultiplexingStates, "AccessibleControlShape::stopStateMultiplexing: not multiplexing!" );

	// we should have the native context of the control
	Reference< XAccessibleEventBroadcaster > xBroadcaster( m_aControlContext.get(), UNO_QUERY );
	OSL_ENSURE( xBroadcaster.is(), "AccessibleControlShape::stopStateMultiplexing: no AccessibleEventBroadcaster on the native context!" );

	if ( xBroadcaster.is() )
	{
		xBroadcaster->removeEventListener( this );
		m_bMultiplexingStates = sal_False;
	}
}

//--------------------------------------------------------------------
::rtl::OUString	AccessibleControlShape::getControlModelStringProperty( const ::rtl::OUString& _rPropertyName ) const SAL_THROW(())
{
	::rtl::OUString sReturn;
	try
	{
		if ( const_cast< AccessibleControlShape* >( this )->ensureControlModelAccess() )
		{
			if ( !m_xModelPropsMeta.is() ||	m_xModelPropsMeta->hasPropertyByName( _rPropertyName ) )
				// ask only if a) the control does not have a PropertySetInfo object or b) it has, and the
				// property in question is available
				m_xControlModel->getPropertyValue( _rPropertyName ) >>= sReturn;
		}
	}
	catch( const Exception& )
	{
		OSL_ENSURE( sal_False, "OAccessibleControlContext::getModelStringProperty: caught an exception!" );
	}
	return sReturn;
}

//--------------------------------------------------------------------
void AccessibleControlShape::adjustAccessibleRole( )
{
	// if we're in design mode, we are a simple SHAPE, in alive mode, we use the role of our inner context
	if ( !isAliveMode( m_xUnoControl ) )
		return;

	// we're in alive mode -> determine the role of the inner context
	Reference< XAccessibleContext > xNativeContext( m_aControlContext );
	OSL_PRECOND( xNativeContext.is(), "AccessibleControlShape::adjustAccessibleRole: no inner context!" );
	if ( xNativeContext.is() )
		SetAccessibleRole( xNativeContext->getAccessibleRole( ) );
}

#ifdef DBG_UTIL
//--------------------------------------------------------------------
sal_Bool AccessibleControlShape::SetState( sal_Int16 _nState )
{
	OSL_ENSURE( !isAliveMode( m_xUnoControl ) || !isComposedState( _nState ),
		"AccessibleControlShape::SetState: a state which should be determined by the control context is set from outside!" );
	return AccessibleShape::SetState( _nState );
}
#endif // DBG_UTIL

//--------------------------------------------------------------------
void AccessibleControlShape::initializeComposedState()
{
	if ( !isAliveMode( m_xUnoControl ) )
		// no action necessary for design mode
		return;

	// get our own state set implementation
	::utl::AccessibleStateSetHelper* pComposedStates =
		static_cast< ::utl::AccessibleStateSetHelper* >( mxStateSet.get() );
	OSL_PRECOND( pComposedStates,
		"AccessibleControlShape::initializeComposedState: no composed set!" );

	// we need to reset some states of the composed set, because they either do not apply
	// for controls in alive mode, or are in the responsibility of the UNO-control, anyway
	pComposedStates->RemoveState( AccessibleStateType::ENABLED );		// this is controlled by the UNO-control
    pComposedStates->RemoveState( AccessibleStateType::SENSITIVE );		// this is controlled by the UNO-control
	pComposedStates->RemoveState( AccessibleStateType::FOCUSABLE );		// this is controlled by the UNO-control
	pComposedStates->RemoveState( AccessibleStateType::SELECTABLE );	// this does not hold for an alive UNO-control
#if OSL_DEBUG_LEVEL > 0
	// now, only states which are not in the responsibility of the UNO control should be part of this state set
	{
		Sequence< sal_Int16 > aInitStates = pComposedStates->getStates();
		for ( sal_Int32 i=0; i<aInitStates.getLength(); ++i )
			OSL_ENSURE( !isComposedState( aInitStates.getConstArray()[i] ),
				"AccessibleControlShape::initializeComposedState: invalid initial composed state (should be controlled by the UNO-control)!" );
	}
#endif

	// get my inner context
	Reference< XAccessibleContext > xInnerContext( m_aControlContext );
	OSL_PRECOND( xInnerContext.is(), "AccessibleControlShape::initializeComposedState: no inner context!" );
	if ( xInnerContext.is() )
	{
		// get all states of the inner context
		Reference< XAccessibleStateSet > xInnerStates( xInnerContext->getAccessibleStateSet() );
		OSL_ENSURE( xInnerStates.is(), "AccessibleControlShape::initializeComposedState: no inner states!" );
		Sequence< sal_Int16 > aInnerStates;
		if ( xInnerStates.is() )
			aInnerStates = xInnerStates->getStates();

		// look which one are to be propagated to the composed context
		const sal_Int16* pStates = aInnerStates.getConstArray();
		const sal_Int16* pStatesEnd = pStates + aInnerStates.getLength();
		for ( ; pStates != pStatesEnd; ++pStates )
		{
			if ( isComposedState( *pStates ) && !pComposedStates->contains( *pStates ) )
			{
				pComposedStates->AddState( *pStates );
			}
		}
	}
}

void SAL_CALL AccessibleControlShape::elementInserted( const ::com::sun::star::container::ContainerEvent& _rEvent ) throw (::com::sun::star::uno::RuntimeException)
{
    Reference< XContainer > xContainer( _rEvent.Source, UNO_QUERY );
    Reference< XControl > xControl( _rEvent.Element, UNO_QUERY );

    OSL_ENSURE( xContainer.is() && xControl.is(),
        "AccessibleControlShape::elementInserted: invalid event description!" );

    if ( !xControl.is() )
        return;

    ensureControlModelAccess();

    Reference< XInterface > xNewNormalized( xControl->getModel(), UNO_QUERY );
    Reference< XInterface > xMyModelNormalized( m_xControlModel, UNO_QUERY );
    if ( xNewNormalized.get() && xMyModelNormalized.get() )
    {
        // now finally the control for the model we're responsible for has been inserted into the container
        Reference< XInterface > xKeepAlive( *this );

        // first, we're not interested in any more container events
        if ( xContainer.is() )
        {
            xContainer->removeContainerListener( this );
            m_bWaitingForControl = sal_False;
        }

        // second, we need to replace ourself with a new version, which now can be based on the
        // control
		OSL_VERIFY( mpParent->ReplaceChild ( this, mxShape, mnIndex, maShapeTreeInfo ) );
    }
}

void SAL_CALL AccessibleControlShape::elementRemoved( const ::com::sun::star::container::ContainerEvent& ) throw (::com::sun::star::uno::RuntimeException)
{
    // not interested in
}

void SAL_CALL AccessibleControlShape::elementReplaced( const ::com::sun::star::container::ContainerEvent& ) throw (::com::sun::star::uno::RuntimeException)
{
    // not interested in
}
AccessibleControlShape* SAL_CALL AccessibleControlShape::GetLabeledByControlShape( )
{
	if(m_xControlModel.is())
	{
		const ::rtl::OUString& rAccLabelControlProperty = lcl_getLabelControlPropertyName();
		Any sCtlLabelBy;
		// get the "label by" property value of the control
		if (::comphelper::hasProperty(rAccLabelControlProperty, m_xControlModel))
		{
			m_xControlModel->getPropertyValue( rAccLabelControlProperty ) >>= sCtlLabelBy;
			if( sCtlLabelBy.hasValue() )
			{
				Reference< XPropertySet >  xAsSet (sCtlLabelBy, UNO_QUERY);
				AccessibleControlShape* pCtlAccShape = mpParent->GetAccControlShapeFromModel(xAsSet.get());
				return pCtlAccShape;
			}
		}
	}
	return NULL;
}
