/**************************************************************
 * 
 * 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_accessibility.hxx"

// includes --------------------------------------------------------------
#include <accessibility/standard/vclxaccessibletoolbox.hxx>
#include <accessibility/standard/vclxaccessibletoolboxitem.hxx>
#include <toolkit/helper/convert.hxx>

#include <unotools/accessiblestatesethelper.hxx>
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <tools/debug.hxx>
#include <vcl/toolbox.hxx>
#include <comphelper/accessiblewrapper.hxx>
#include <comphelper/processfactory.hxx>

using namespace ::comphelper;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::accessibility;

namespace
{
	// =========================================================================
	// = OToolBoxWindowItemContext
	// =========================================================================
	/** XAccessibleContext implementation for a toolbox item which is represented by a VCL Window
	*/
	class OToolBoxWindowItemContext : public OAccessibleContextWrapper
	{
		sal_Int32 m_nIndexInParent;
	public:
		OToolBoxWindowItemContext(sal_Int32 _nIndexInParent,
			const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
			const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerAccessibleContext,
			const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxOwningAccessible,
			const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible
			) : OAccessibleContextWrapper(
			_rxORB,
			_rxInnerAccessibleContext,
			_rxOwningAccessible,
			_rxParentAccessible		)
			,m_nIndexInParent(_nIndexInParent)
		{
		}
		virtual sal_Int32 SAL_CALL getAccessibleIndexInParent(  ) throw (::com::sun::star::uno::RuntimeException);
	};

	// -------------------------------------------------------------------------
	sal_Int32 SAL_CALL OToolBoxWindowItemContext::getAccessibleIndexInParent(  ) throw (::com::sun::star::uno::RuntimeException)
	{
		::osl::MutexGuard aGuard( m_aMutex );
		return m_nIndexInParent;
	}

	// =========================================================================
	// = OToolBoxWindowItem
	// =========================================================================
	typedef ::cppu::ImplHelper1	<	XUnoTunnel
								>	OToolBoxWindowItem_Base;

	/** XAccessible implementation for a toolbox item which is represented by a VCL Window
	*/
	class OToolBoxWindowItem
			:public OAccessibleWrapper
			,public OToolBoxWindowItem_Base
	{
	private:
		sal_Int32 m_nIndexInParent;

	public:
		inline sal_Int32	getIndexInParent() const					{ return m_nIndexInParent; }
		inline void			setIndexInParent( sal_Int32 _nNewIndex )	{ m_nIndexInParent = _nNewIndex; }

        static	sal_Bool	isWindowItem( const Reference< XAccessible >& _rxAcc, OToolBoxWindowItem** /* [out] */ _ppImplementation = NULL );

	public:
		OToolBoxWindowItem(sal_Int32 _nIndexInParent,
			const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB,
			const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxInnerAccessible,
			const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxParentAccessible
			) : OAccessibleWrapper(
			_rxORB,
			_rxInnerAccessible,
			_rxParentAccessible)
			,m_nIndexInParent(_nIndexInParent)
		{
		}

	protected:
		// XInterface
		DECLARE_XINTERFACE( )
		DECLARE_XTYPEPROVIDER( )

		// OAccessibleWrapper
		virtual OAccessibleContextWrapper* createAccessibleContext(
				const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& _rxInnerContext
			);

		// XUnoTunnel
		virtual sal_Int64 SAL_CALL getSomething( const Sequence< sal_Int8 >& aIdentifier ) throw (RuntimeException);
		static Sequence< sal_Int8 > getUnoTunnelImplementationId();
	};

	// -------------------------------------------------------------------------
	IMPLEMENT_FORWARD_XINTERFACE2( OToolBoxWindowItem, OAccessibleWrapper, OToolBoxWindowItem_Base )
	IMPLEMENT_FORWARD_XTYPEPROVIDER2( OToolBoxWindowItem, OAccessibleWrapper, OToolBoxWindowItem_Base )

	// -------------------------------------------------------------------------
	OAccessibleContextWrapper* OToolBoxWindowItem::createAccessibleContext(
			const Reference< XAccessibleContext >& _rxInnerContext )
	{
		return new OToolBoxWindowItemContext( m_nIndexInParent,getORB(), _rxInnerContext, this, getParent() );
	}

	//--------------------------------------------------------------------
	sal_Bool OToolBoxWindowItem::isWindowItem( const Reference< XAccessible >& _rxAcc, OToolBoxWindowItem** /* [out] */ _ppImplementation )
	{
		OToolBoxWindowItem* pImplementation = NULL;

		Reference< XUnoTunnel > xTunnel( _rxAcc, UNO_QUERY );
		if ( xTunnel.is() )
			pImplementation = reinterpret_cast< OToolBoxWindowItem* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) );

		if ( _ppImplementation )
			*_ppImplementation = pImplementation;

		return NULL != pImplementation;
	}

	//--------------------------------------------------------------------
	Sequence< sal_Int8 > OToolBoxWindowItem::getUnoTunnelImplementationId()
	{
		static ::cppu::OImplementationId * pId = 0;
		if (! pId)
		{
			::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
			if (! pId)
			{
				static ::cppu::OImplementationId aId;
				pId = &aId;
			}
		}
		return pId->getImplementationId();
	}

	//--------------------------------------------------------------------
	sal_Int64 SAL_CALL OToolBoxWindowItem::getSomething( const Sequence< sal_Int8 >& _rId ) throw (RuntimeException)
	{
		if	(	( 16 == _rId.getLength() )
			&&	( 0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(),  _rId.getConstArray(), 16 ) )
			)
			return reinterpret_cast< sal_Int64>( this );

		return 0;
	}
}

DBG_NAME(VCLXAccessibleToolBox)

// -----------------------------------------------------------------------------
// VCLXAccessibleToolBox
// -----------------------------------------------------------------------------
VCLXAccessibleToolBox::VCLXAccessibleToolBox( VCLXWindow* pVCLXWindow ) :

	VCLXAccessibleComponent( pVCLXWindow )

{
	DBG_CTOR(VCLXAccessibleToolBox,NULL);
}
// -----------------------------------------------------------------------------
VCLXAccessibleToolBox::~VCLXAccessibleToolBox()
{
	DBG_DTOR(VCLXAccessibleToolBox,NULL);
}
// -----------------------------------------------------------------------------
VCLXAccessibleToolBoxItem* VCLXAccessibleToolBox::GetItem_Impl( sal_Int32 _nPos, bool _bMustHaveFocus )
{
	VCLXAccessibleToolBoxItem* pItem = NULL;
    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if ( pToolBox && ( !_bMustHaveFocus || pToolBox->HasFocus() ) )
	{
		ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
		// returns only toolbox buttons, not windows
		if ( aIter != m_aAccessibleChildren.end()  && aIter->second.is())
			pItem =	static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
	}

	return pItem;
}
// -----------------------------------------------------------------------------

void VCLXAccessibleToolBox::UpdateFocus_Impl()
{
    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if( !pToolBox )
        return;

    // submit events only if toolbox has the focus to avoid sending events due to mouse move
    sal_Bool bHasFocus = sal_False;
    if ( pToolBox->HasFocus() )
        bHasFocus = sal_True;
    else
    {
        // check for subtoolbar, i.e. check if our parent is a toolbar
        ToolBox* pToolBoxParent = dynamic_cast< ToolBox* >( pToolBox->GetParent() );
        // subtoolbars never get the focus as key input is just forwarded, so check if the parent toolbar has it
        if ( pToolBoxParent && pToolBoxParent->HasFocus() )
            bHasFocus = sal_True;
    }

    if ( bHasFocus )
	{
		sal_uInt16 nHighlightItemId = pToolBox->GetHighlightItemId();
		sal_uInt16 nFocusCount = 0;
        for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
			  aIter != m_aAccessibleChildren.end(); ++aIter )
		{
            sal_uInt16 nItemId = pToolBox->GetItemId( (sal_uInt16)aIter->first );

            if ( aIter->second.is() )
            {
                VCLXAccessibleToolBoxItem* pItem =
                    static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
                if ( pItem->HasFocus() && nItemId != nHighlightItemId )
                {
                    // reset the old focused item
                    pItem->SetFocus( sal_False );
                    nFocusCount++;
                }
                if ( nItemId == nHighlightItemId )
                {
                    // set the new focused item
                    pItem->SetFocus( sal_True );
                    nFocusCount++;
                }
            }
        // both items changed?
        if ( nFocusCount > 1 )
            break;
        }
	}
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::ReleaseFocus_Impl( sal_Int32 _nPos )
{
    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if ( pToolBox ) // #107124#, do not check for focus because this message is also handled in losefocus
	{
        ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
        if ( aIter != m_aAccessibleChildren.end() && aIter->second.is() )
        {
            VCLXAccessibleToolBoxItem* pItem =
                static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
            if ( pItem->HasFocus() )
                pItem->SetFocus( sal_False );
        }
	}
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::UpdateChecked_Impl( sal_Int32 _nPos )
{
    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if ( pToolBox )
	{
		sal_uInt16 nFocusId = pToolBox->GetItemId( (sal_uInt16)_nPos );
		VCLXAccessibleToolBoxItem* pFocusItem = NULL;

	    for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
			  aIter != m_aAccessibleChildren.end(); ++aIter )
		{
				sal_uInt16 nItemId = pToolBox->GetItemId( (sal_uInt16)aIter->first );

                VCLXAccessibleToolBoxItem* pItem =
                    static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
                pItem->SetChecked( pToolBox->IsItemChecked( nItemId ) );
                if ( nItemId == nFocusId )
                    pFocusItem = pItem;
        }
		//Solution:If the position is not a child item,the focus should not be called
		if ( pFocusItem && (sal_uInt16)_nPos != TOOLBOX_ITEM_NOTFOUND )
			pFocusItem->SetFocus( sal_True );
	}
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::UpdateIndeterminate_Impl( sal_Int32 _nPos )
{
    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if ( pToolBox )
	{
		sal_uInt16 nItemId = pToolBox->GetItemId( (sal_uInt16)_nPos );

        ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find( _nPos );
        if ( aIter != m_aAccessibleChildren.end() && aIter->second.is() )
        {
            VCLXAccessibleToolBoxItem* pItem =
                static_cast< VCLXAccessibleToolBoxItem* >( aIter->second.get() );
            if ( pItem )
                pItem->SetIndeterminate( pToolBox->GetItemState( nItemId ) == STATE_DONTKNOW );
        }
	}
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::implReleaseToolboxItem( ToolBoxItemsMap::iterator& _rMapPos,
		bool _bNotifyRemoval, bool _bDispose )
{
	Reference< XAccessible > xItemAcc( _rMapPos->second );
	if ( !xItemAcc.is() )
		return;

	if ( _bNotifyRemoval )
	{
		NotifyAccessibleEvent( AccessibleEventId::CHILD, makeAny( xItemAcc ), Any() );
	}

    OToolBoxWindowItem* pWindowItem = NULL;
    if ( !OToolBoxWindowItem::isWindowItem( xItemAcc, &pWindowItem ) )
	{
		static_cast< VCLXAccessibleToolBoxItem* >( xItemAcc.get() )->ReleaseToolBox();
		if ( _bDispose )
			::comphelper::disposeComponent( xItemAcc );
	}
	else
	{
		if ( _bDispose )
		{
			if ( pWindowItem )
			{
				Reference< XAccessibleContext > xContext( pWindowItem->getContextNoCreate() );
				::comphelper::disposeComponent( xContext );
			}
		}
	}
}

// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::UpdateItem_Impl( sal_Int32 _nPos, sal_Bool _bItemAdded )
{
    if ( _nPos < sal_Int32( m_aAccessibleChildren.size() ) )
    {
        UpdateAllItems_Impl();
        return;
    }

    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if ( pToolBox )
	{
		if ( !_bItemAdded )
		{	// the item was removed
			// -> destroy the old item
			ToolBoxItemsMap::iterator aItemPos = m_aAccessibleChildren.find( _nPos );
			if ( m_aAccessibleChildren.end() != aItemPos )
			{
				implReleaseToolboxItem( aItemPos, true, true );
				m_aAccessibleChildren.erase( aItemPos );
			}
		}

		// adjust the "index-in-parent"s
		ToolBoxItemsMap::iterator aIndexAdjust = m_aAccessibleChildren.upper_bound( _nPos );
		while ( m_aAccessibleChildren.end() != aIndexAdjust )
		{
			Reference< XAccessible > xItemAcc( aIndexAdjust->second );

            OToolBoxWindowItem* pWindowItem = NULL;
            if ( !OToolBoxWindowItem::isWindowItem( xItemAcc, &pWindowItem ) )
			{
				VCLXAccessibleToolBoxItem* pItem = static_cast< VCLXAccessibleToolBoxItem* >( xItemAcc.get() );
				if ( pItem )
				{
					sal_Int32 nIndex = pItem->getIndexInParent( );
					nIndex += _bItemAdded ? +1 : -1;
					pItem->setIndexInParent( nIndex );
				}
			}
			else
			{
				if ( pWindowItem )
				{
					sal_Int32 nIndex = pWindowItem->getIndexInParent( );
					nIndex += _bItemAdded ? +1 : -1;
					pWindowItem->setIndexInParent( nIndex );
				}
			}

			++aIndexAdjust;
		}

        if ( _bItemAdded )
		{
			// TODO: we should make this dependent on the existence of event listeners
			// with the current implementation, we always create accessible object
			Any aNewChild = makeAny( getAccessibleChild( (sal_Int32)_nPos ) );
			NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewChild );
		}
	}
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::UpdateAllItems_Impl()
{
    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if ( pToolBox )
	{
		// deregister the old items
    	for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
		  	  aIter != m_aAccessibleChildren.end(); ++aIter )
		{
			implReleaseToolboxItem( aIter, true, true );
		}
		m_aAccessibleChildren.clear();

		// register the new items
	    sal_uInt16 i, nCount = pToolBox->GetItemCount();
		for ( i = 0; i < nCount; ++i )
		{
			Any aNewValue;
			aNewValue <<= getAccessibleChild( (sal_Int32)i );;
			NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewValue );
		}
	}
}

// -----------------------------------------------------------------------------

void VCLXAccessibleToolBox::UpdateCustomPopupItemp_Impl( Window* pWindow, bool bOpen )
{
    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
	if( pWindow && pToolBox )
	{
		Reference< XAccessible > xChild( pWindow->GetAccessible() );
        if( xChild.is() )
		{
			Reference< XAccessible > xChildItem( getAccessibleChild( static_cast< sal_Int32 >( pToolBox->GetItemPos( pToolBox->GetDownItemId() ) ) ) );
            VCLXAccessibleToolBoxItem* pItem = static_cast< VCLXAccessibleToolBoxItem* >( xChildItem.get() );

            pItem->SetChild( xChild );
            pItem->NotifyChildEvent( xChild, bOpen );
		}
	}
}

// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::UpdateItemName_Impl( sal_Int32 _nPos )
{
	VCLXAccessibleToolBoxItem* pItem = GetItem_Impl( _nPos, false );
	if ( pItem )
		pItem->NameChanged();
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::UpdateItemEnabled_Impl( sal_Int32 _nPos )
{
	VCLXAccessibleToolBoxItem* pItem = GetItem_Impl( _nPos, false );
	if ( pItem )
		pItem->ToggleEnableState();
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::HandleSubToolBarEvent( const VclWindowEvent& rVclWindowEvent, bool _bShow )
{
    Window* pChildWindow = (Window *) rVclWindowEvent.GetData();
    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if ( pChildWindow
        && pToolBox
        && pToolBox == pChildWindow->GetParent()
        && pChildWindow->GetType() == WINDOW_TOOLBOX )
    {
        sal_Int32 nIndex = pToolBox->GetItemPos( pToolBox->GetCurItemId() );
        Reference< XAccessible > xItem = getAccessibleChild( nIndex );
        if ( xItem.is() )
        {
            Reference< XAccessible > xChild = pChildWindow->GetAccessible();
            VCLXAccessibleToolBoxItem* pItem =
                static_cast< VCLXAccessibleToolBoxItem* >( xItem.get() );
            pItem->SetChild( xChild );
            pItem->NotifyChildEvent( xChild, _bShow );
        }
    }
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::ReleaseSubToolBox( ToolBox* _pSubToolBox )
{
    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if ( pToolBox )
    {
        sal_Int32 nIndex = pToolBox->GetItemPos( pToolBox->GetCurItemId() );
        Reference< XAccessible > xItem = getAccessibleChild( nIndex );
        if ( xItem.is() )
        {
            Reference< XAccessible > xChild = _pSubToolBox->GetAccessible();
            VCLXAccessibleToolBoxItem* pItem =
                static_cast< VCLXAccessibleToolBoxItem* >( xItem.get() );
            if ( pItem->GetChild() == xChild )
            {
                pItem->SetChild( Reference< XAccessible >() );
                pItem->NotifyChildEvent( xChild, false );
            }
        }
    }
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::FillAccessibleStateSet( utl::AccessibleStateSetHelper& rStateSet )
{
	VCLXAccessibleComponent::FillAccessibleStateSet( rStateSet );

    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if ( pToolBox )
	{
        rStateSet.AddState( AccessibleStateType::FOCUSABLE );
		if ( pToolBox->IsHorizontal() )
	        rStateSet.AddState( AccessibleStateType::HORIZONTAL );
		else
	        rStateSet.AddState( AccessibleStateType::VERTICAL );
	}
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
{
	// to prevent an early release of the toolbox (VCLEVENT_OBJECT_DYING)
	Reference< XAccessibleContext > xTemp = this;

	ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() ); 
	switch ( rVclWindowEvent.GetId() )
	{
		case VCLEVENT_TOOLBOX_CLICK:
		case VCLEVENT_TOOLBOX_SELECT: 
        {
			if ( rVclWindowEvent.GetData() )
            {
                UpdateChecked_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
                UpdateIndeterminate_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
            }
			else if( pToolBox->GetItemPos(pToolBox->GetCurItemId()) != TOOLBOX_ITEM_NOTFOUND )
			{
				UpdateChecked_Impl( pToolBox->GetItemPos(pToolBox->GetCurItemId()) );
		                UpdateIndeterminate_Impl( pToolBox->GetItemPos(pToolBox->GetCurItemId()) );
			}
			break;
        }
		case VCLEVENT_TOOLBOX_DOUBLECLICK:
		case VCLEVENT_TOOLBOX_ACTIVATE:
		case VCLEVENT_TOOLBOX_DEACTIVATE:
    	//case VCLEVENT_TOOLBOX_SELECT:
			break;
		// IA2 CWS. MT: Still using VCLEVENT_TOOLBOX_CLICK, see comment in vcl/source/window/toolbox2.cxx
		/*
		case VCLEVENT_TOOLBOX_ITEMUPDATED:
		{
	    	if ( rVclWindowEvent.GetData() )
	        {
				UpdateChecked_Impl( TOOLBOX_ITEM_NOTFOUND );
	            UpdateIndeterminate_Impl( (sal_Int32)rVclWindowEvent.GetData() );
	        }	
		break;
		}
		*/
		case VCLEVENT_TOOLBOX_HIGHLIGHT:
			UpdateFocus_Impl();
			break;

		case VCLEVENT_TOOLBOX_HIGHLIGHTOFF:
            ReleaseFocus_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
			break;

		case VCLEVENT_TOOLBOX_ITEMADDED :
//            UpdateItem_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData(), VCLEVENT_TOOLBOX_ITEMADDED == rVclWindowEvent.GetId() );
            UpdateItem_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData(), sal_True );
			break;

        case VCLEVENT_TOOLBOX_ITEMREMOVED :
		case VCLEVENT_TOOLBOX_ALLITEMSCHANGED :
		{
			UpdateAllItems_Impl();
			break;
		}

        case VCLEVENT_TOOLBOX_ITEMWINDOWCHANGED:
		{
            sal_Int32 nPos = (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData();
			ToolBoxItemsMap::iterator aAccessiblePos( m_aAccessibleChildren.find( nPos ) );
			if ( m_aAccessibleChildren.end() != aAccessiblePos )
            {
				implReleaseToolboxItem( aAccessiblePos, false, true );
                m_aAccessibleChildren.erase (aAccessiblePos);
            }

			Any aNewValue;
			aNewValue <<= getAccessibleChild(nPos);
			NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), aNewValue );
			break;
		}
		case VCLEVENT_TOOLBOX_ITEMTEXTCHANGED :
            UpdateItemName_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
			break;

		case VCLEVENT_TOOLBOX_ITEMENABLED :
		case VCLEVENT_TOOLBOX_ITEMDISABLED :
		{
            UpdateItemEnabled_Impl( (sal_Int32)(sal_IntPtr)rVclWindowEvent.GetData() );
			break;
		}

		case VCLEVENT_DROPDOWN_OPEN:
		case VCLEVENT_DROPDOWN_CLOSE:
		{
			UpdateCustomPopupItemp_Impl( static_cast< Window* >( rVclWindowEvent.GetData() ), rVclWindowEvent.GetId() == VCLEVENT_DROPDOWN_OPEN );
			break;
		}

		case VCLEVENT_OBJECT_DYING :
		{
            // if this toolbox is a subtoolbox, we have to relese it from its parent
            ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
            if ( pToolBox && pToolBox->GetParent() &&
                 pToolBox->GetParent()->GetType() == WINDOW_TOOLBOX )
            {
                VCLXAccessibleToolBox* pParent = static_cast< VCLXAccessibleToolBox* >(
                    pToolBox->GetParent()->GetAccessible()->getAccessibleContext().get() );
                if ( pParent )
                    pParent->ReleaseSubToolBox( pToolBox );
            }

            // dispose all items
    		for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
				  aIter != m_aAccessibleChildren.end(); ++aIter )
			{
				implReleaseToolboxItem( aIter, false, true );
			}
			m_aAccessibleChildren.clear();

			//!!! no break to call base class
		}

		default:
			VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
	}
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent )
{
	switch ( rVclWindowEvent.GetId() )
	{
        case VCLEVENT_WINDOW_SHOW:  // send create on show for direct accessible children
        {
            Reference< XAccessible > xReturn = GetItemWindowAccessible(rVclWindowEvent);
            if ( xReturn.is() )
                NotifyAccessibleEvent( AccessibleEventId::CHILD, Any(), makeAny(xReturn) );
            else
                HandleSubToolBarEvent( rVclWindowEvent, true );
        }
        break;

        default:
           VCLXAccessibleComponent::ProcessWindowChildEvent( rVclWindowEvent );

	}
}
// -----------------------------------------------------------------------------
// XInterface
// -----------------------------------------------------------------------------
IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleToolBox, VCLXAccessibleComponent, VCLXAccessibleToolBox_BASE )
// -----------------------------------------------------------------------------
// XTypeProvider
// -----------------------------------------------------------------------------
IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleToolBox, VCLXAccessibleComponent, VCLXAccessibleToolBox_BASE )
// -----------------------------------------------------------------------------
// XComponent
// -----------------------------------------------------------------------------
void SAL_CALL VCLXAccessibleToolBox::disposing()
{
	VCLXAccessibleComponent::disposing();

	// release the items
	for ( ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.begin();
		  aIter != m_aAccessibleChildren.end(); ++aIter )
	{
		implReleaseToolboxItem( aIter, false, true );
	}
	m_aAccessibleChildren.clear();
}
// -----------------------------------------------------------------------------
// XServiceInfo
// -----------------------------------------------------------------------------
::rtl::OUString VCLXAccessibleToolBox::getImplementationName() throw (RuntimeException)
{
	return ::rtl::OUString::createFromAscii( "com.sun.star.comp.toolkit.AccessibleToolBox" );
}
// -----------------------------------------------------------------------------
Sequence< ::rtl::OUString > VCLXAccessibleToolBox::getSupportedServiceNames() throw (RuntimeException)
{
	Sequence< ::rtl::OUString > aNames = VCLXAccessibleComponent::getSupportedServiceNames();
	sal_Int32 nLength = aNames.getLength();
	aNames.realloc( nLength + 1 );
	aNames[nLength] = ::rtl::OUString::createFromAscii( "com.sun.star.accessibility.AccessibleToolBox" );
	return aNames;
}
// -----------------------------------------------------------------------------
// XAccessibleContext
// -----------------------------------------------------------------------------
sal_Int32 SAL_CALL VCLXAccessibleToolBox::getAccessibleChildCount(  ) throw (RuntimeException)
{
	comphelper::OExternalLockGuard aGuard( this );

	sal_Int32 nCount = 0;
    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if ( pToolBox )
    	nCount = pToolBox->GetItemCount();

    return nCount;
}
// -----------------------------------------------------------------------------
Reference< XAccessible > SAL_CALL VCLXAccessibleToolBox::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException)
{
	if ( i < 0 || i >= getAccessibleChildCount() )
		throw IndexOutOfBoundsException();

	comphelper::OExternalLockGuard aGuard( this );

    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if ( pToolBox )
	{
		Reference< XAccessible > xChild;
		// search for the child
		ToolBoxItemsMap::iterator aIter = m_aAccessibleChildren.find(i);
		if ( m_aAccessibleChildren.end() == aIter )
        {
			sal_uInt16 nItemId = pToolBox->GetItemId( (sal_uInt16)i );
            sal_uInt16 nHighlightItemId = pToolBox->GetHighlightItemId();
			Window* pItemWindow = pToolBox->GetItemWindow( nItemId );
			// not found -> create a new child
    		VCLXAccessibleToolBoxItem* pChild = new VCLXAccessibleToolBoxItem( pToolBox, i );
			Reference< XAccessible> xParent = pChild;
			if ( pItemWindow )
			{
				xChild = new OToolBoxWindowItem(0,::comphelper::getProcessServiceFactory(),pItemWindow->GetAccessible(),xParent);
				pItemWindow->SetAccessible(xChild);
                pChild->SetChild( xChild );
			}
			xChild = pChild;
			if ( nHighlightItemId > 0 && nItemId == nHighlightItemId )
				pChild->SetFocus( sal_True );
			if ( pToolBox->IsItemChecked( nItemId ) )
				pChild->SetChecked( sal_True );
            if ( pToolBox->GetItemState( nItemId ) == STATE_DONTKNOW )
                pChild->SetIndeterminate( true );
			m_aAccessibleChildren.insert( ToolBoxItemsMap::value_type( i, xChild ) );
		}
		else
		{
			// found it
			xChild = aIter->second;
		}
		return xChild;
	}

    return NULL;
}
// -----------------------------------------------------------------------------
Reference< XAccessible > SAL_CALL VCLXAccessibleToolBox::getAccessibleAtPoint( const awt::Point& _rPoint ) throw (RuntimeException)
{
	comphelper::OExternalLockGuard aGuard( this );

	Reference< XAccessible > xAccessible;
    ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if ( pToolBox )
	{
		sal_uInt16 nItemPos = pToolBox->GetItemPos( VCLPoint( _rPoint ) );
		if ( nItemPos != TOOLBOX_ITEM_NOTFOUND )
			xAccessible = getAccessibleChild( nItemPos );
	}

	return xAccessible;
}
// -----------------------------------------------------------------------------
Reference< XAccessible > VCLXAccessibleToolBox::GetItemWindowAccessible( const VclWindowEvent& rVclWindowEvent )
{
    Reference< XAccessible > xReturn;
	Window* pChildWindow = (Window *) rVclWindowEvent.GetData();
	ToolBox* pToolBox = static_cast< ToolBox* >( GetWindow() );
    if ( pChildWindow && pToolBox )
	{
		sal_uInt16 nCount = pToolBox->GetItemCount();
		for (sal_uInt16 i = 0 ; i < nCount && !xReturn.is() ; ++i)
		{
			sal_uInt16 nItemId = pToolBox->GetItemId( i );
			Window* pItemWindow = pToolBox->GetItemWindow( nItemId );
			if ( pItemWindow == pChildWindow )
				xReturn = getAccessibleChild(i);
		}
	}
	return xReturn;
}
// -----------------------------------------------------------------------------
Reference< XAccessible > VCLXAccessibleToolBox::GetChildAccessible( const VclWindowEvent& rVclWindowEvent )
{
	Reference< XAccessible > xReturn = GetItemWindowAccessible(rVclWindowEvent);

	if ( !xReturn.is() )
		xReturn = VCLXAccessibleComponent::GetChildAccessible(rVclWindowEvent);
	return xReturn;
}
// -----------------------------------------------------------------------------
// XAccessibleSelection
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
    OExternalLockGuard aGuard( this );
    if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
        throw IndexOutOfBoundsException();
    ToolBox * pToolBox = static_cast < ToolBox * > ( GetWindow() );
    sal_uInt16 nPos = static_cast < sal_uInt16 > (nChildIndex);
    pToolBox->ChangeHighlight( nPos );
}
// -----------------------------------------------------------------------------
sal_Bool VCLXAccessibleToolBox::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
    OExternalLockGuard aGuard( this );
    if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
        throw IndexOutOfBoundsException();
    ToolBox * pToolBox = static_cast < ToolBox * > ( GetWindow() );
    sal_uInt16 nPos = static_cast < sal_uInt16 > (nChildIndex);
    if ( pToolBox != NULL && pToolBox->GetHighlightItemId() == pToolBox->GetItemId( nPos ) )
        return sal_True;
    else
        return sal_False;
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::clearAccessibleSelection(  ) throw (RuntimeException)
{
    OExternalLockGuard aGuard( this );
    ToolBox * pToolBox = static_cast < ToolBox * > ( GetWindow() );
    pToolBox -> LoseFocus();
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::selectAllAccessibleChildren(  ) throw (RuntimeException)
{
    OExternalLockGuard aGuard( this );
    // intentionally empty. makes no sense for a toolbox
}
// -----------------------------------------------------------------------------
sal_Int32 VCLXAccessibleToolBox::getSelectedAccessibleChildCount(  ) throw (RuntimeException)
{
    OExternalLockGuard aGuard( this );
    sal_Int32 nRet = 0;
    for ( sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; i++ )
    {
        if ( isAccessibleChildSelected( i ) )
        {
            nRet = 1;
            break; // a toolbox can only have (n)one selected child
        }
    }
    return nRet;
}
// -----------------------------------------------------------------------------
Reference< XAccessible > VCLXAccessibleToolBox::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
    OExternalLockGuard aGuard( this );
    if ( nSelectedChildIndex < 0 || nSelectedChildIndex >= getSelectedAccessibleChildCount() )
        throw IndexOutOfBoundsException();
    Reference< XAccessible > xChild;
    for ( sal_Int32 i = 0, j = 0, nCount = getAccessibleChildCount(); i < nCount; i++ )
    {
        if ( isAccessibleChildSelected( i ) && ( j++ == nSelectedChildIndex ) )
        {
            xChild = getAccessibleChild( i );
            break;
        }
    }
    return xChild;
}
// -----------------------------------------------------------------------------
void VCLXAccessibleToolBox::deselectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
    OExternalLockGuard aGuard( this );
    if ( nChildIndex < 0 || nChildIndex >= getAccessibleChildCount() )
        throw IndexOutOfBoundsException();
    clearAccessibleSelection(); // a toolbox can only have (n)one selected child
}
// -----------------------------------------------------------------------------
