/**************************************************************
 * 
 * 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_comphelper.hxx"
#include <comphelper/accessiblecontexthelper.hxx>
#include <comphelper/accessibleeventbuffer.hxx>
#include <osl/diagnose.h>
#include <cppuhelper/weakref.hxx>
#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <comphelper/accessibleeventnotifier.hxx>

//.........................................................................
namespace comphelper
{
//.........................................................................

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

	//=====================================================================
	//= OContextHelper_Impl
	//=====================================================================
	/** implementation class for OAccessibleContextHelper. No own thread safety!
	*/
	class OContextHelper_Impl
	{
	private:
		OAccessibleContextHelper*			m_pAntiImpl;		// the owning instance
		IMutex*								m_pExternalLock;	// the optional additional external lock

	    ::cppu::OInterfaceContainerHelper*	m_pEventListeners;
		WeakReference< XAccessible >		m_aCreator;			// the XAccessible which created our XAccessibleContext

		AccessibleEventNotifier::TClientId	m_nClientId;

	public:
		inline	Reference< XAccessible >	getCreator( ) const					{ return m_aCreator; }
		inline	void						setCreator( const Reference< XAccessible >& _rAcc );

		inline	IMutex*						getExternalLock( )					{ return m_pExternalLock; }
		inline	void						setExternalLock( IMutex* _pLock )	{ m_pExternalLock = _pLock; }

		inline	AccessibleEventNotifier::TClientId
											getClientId() const					{ return m_nClientId; }
		inline	void						setClientId( const AccessibleEventNotifier::TClientId _nId )
																				{ m_nClientId = _nId; }

	public:
		OContextHelper_Impl( OAccessibleContextHelper* _pAntiImpl )
			:m_pAntiImpl( _pAntiImpl )
			,m_pExternalLock( NULL )
			,m_pEventListeners( NULL )
			,m_nClientId( 0 )
		{
		}
	};

	//---------------------------------------------------------------------
	inline	void OContextHelper_Impl::setCreator( const Reference< XAccessible >& _rAcc )
	{
		m_aCreator = _rAcc;
	}

	//=====================================================================
	//= OAccessibleContextHelper
	//=====================================================================
	//---------------------------------------------------------------------
	OAccessibleContextHelper::OAccessibleContextHelper( )
		:OAccessibleContextHelper_Base( GetMutex() )
		,m_pImpl( NULL )
	{
		m_pImpl = new OContextHelper_Impl( this );
	}

	//---------------------------------------------------------------------
	OAccessibleContextHelper::OAccessibleContextHelper( IMutex* _pExternalLock )
		:OAccessibleContextHelper_Base( GetMutex() )
		,m_pImpl( NULL )
	{
		m_pImpl = new OContextHelper_Impl( this );
		m_pImpl->setExternalLock( _pExternalLock );
	}

	//---------------------------------------------------------------------
	void OAccessibleContextHelper::forgetExternalLock()
	{
		m_pImpl->setExternalLock( NULL );
	}

	//---------------------------------------------------------------------
	OAccessibleContextHelper::~OAccessibleContextHelper( )
	{
		forgetExternalLock();
			// this ensures that the lock, which may be already destroyed as part of the derivee,
			// is not used anymore

		ensureDisposed();

		delete m_pImpl;
		m_pImpl = NULL;
	}

	//---------------------------------------------------------------------
	IMutex* OAccessibleContextHelper::getExternalLock( )
	{
		return m_pImpl->getExternalLock();
	}

	//---------------------------------------------------------------------
	void SAL_CALL OAccessibleContextHelper::disposing()
	{
		::osl::ClearableMutexGuard aGuard( GetMutex() );

		if ( m_pImpl->getClientId( ) )
		{
			AccessibleEventNotifier::revokeClientNotifyDisposing( m_pImpl->getClientId( ), *this );
			m_pImpl->setClientId( 0 );
		}
	}

	//---------------------------------------------------------------------
	void SAL_CALL OAccessibleContextHelper::addEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException)
	{
		OMutexGuard aGuard( getExternalLock() );
			// don't use the OContextEntryGuard - it will throw an exception if we're not alive
			// anymore, while the most recent specification for XComponent states that we should
			// silently ignore the call in such a situation
		if ( !isAlive() )
		{
			if ( _rxListener.is() )
				_rxListener->disposing( EventObject( *this ) );
			return;
		}

		if ( _rxListener.is() )
		{
			if ( !m_pImpl->getClientId( ) )
				m_pImpl->setClientId( AccessibleEventNotifier::registerClient( ) );

			AccessibleEventNotifier::addEventListener( m_pImpl->getClientId( ), _rxListener );
		}
	}

	//---------------------------------------------------------------------
	void SAL_CALL OAccessibleContextHelper::removeEventListener( const Reference< XAccessibleEventListener >& _rxListener ) throw (RuntimeException)
	{
		OMutexGuard aGuard( getExternalLock() );
			// don't use the OContextEntryGuard - it will throw an exception if we're not alive
			// anymore, while the most recent specification for XComponent states that we should
			// silently ignore the call in such a situation
		if ( !isAlive() )
			return;

		if ( _rxListener.is() )
		{
			sal_Int32 nListenerCount = AccessibleEventNotifier::removeEventListener( m_pImpl->getClientId( ), _rxListener );
			if ( !nListenerCount )
			{
				// no listeners anymore
				// -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
				// and at least to us not firing any events anymore, in case somebody calls
				// NotifyAccessibleEvent, again
				AccessibleEventNotifier::revokeClient( m_pImpl->getClientId( ) );
				m_pImpl->setClientId( 0 );
			}
		}
	}

	//---------------------------------------------------------------------
	void SAL_CALL OAccessibleContextHelper::NotifyAccessibleEvent( const sal_Int16 _nEventId,
		const Any& _rOldValue, const Any& _rNewValue )
	{
		if ( !m_pImpl->getClientId( ) )
			// if we don't have a client id for the notifier, then we don't have listeners, then
			// we don't need to notify anything
			return;

		// build an event object
		AccessibleEventObject aEvent;
		aEvent.Source = *this;
		aEvent.EventId = _nEventId;
		aEvent.OldValue = _rOldValue;
		aEvent.NewValue = _rNewValue;

		// let the notifier handle this event
		AccessibleEventNotifier::addEvent( m_pImpl->getClientId( ), aEvent );
	}

	//---------------------------------------------------------------------
	void SAL_CALL OAccessibleContextHelper::BufferAccessibleEvent( const sal_Int16 _nEventId,
		const Any& _rOldValue, const Any& _rNewValue,
        AccessibleEventBuffer & _rBuffer )
	{
		// TODO: this whole method (as well as the class AccessibleEventBuffer) should be removed
		// The reasons why they have been introduces id that we needed to collect a set of events
		// before notifying them alltogether (after releasing our mutex). With the other
		// NotifyAccessibleEvent being asynchronous now, this should not be necessary anymore
		// - clients could use the other version now.

		// copy our current listeners
		Sequence< Reference< XInterface > > aListeners;
		if ( m_pImpl->getClientId( ) )
			aListeners = AccessibleEventNotifier::getEventListeners( m_pImpl->getClientId( ) );

		if ( aListeners.getLength() )
		{
			AccessibleEventObject aEvent;
			aEvent.Source = *this;
			OSL_ENSURE( aEvent.Source.is(), "OAccessibleContextHelper::BufferAccessibleEvent: invalid creator!" );
			aEvent.EventId = _nEventId;
			aEvent.OldValue = _rOldValue;
			aEvent.NewValue = _rNewValue;

            _rBuffer.addEvent( aEvent, aListeners );
		}
	}

	//---------------------------------------------------------------------
	sal_Bool OAccessibleContextHelper::isAlive() const
	{
		return !GetBroadcastHelper().bDisposed && !GetBroadcastHelper().bInDispose;
	}

	//---------------------------------------------------------------------
	void OAccessibleContextHelper::ensureAlive() const SAL_THROW( ( DisposedException ) )
	{
		if( !isAlive() )
			throw DisposedException();
	}

	//---------------------------------------------------------------------
	void OAccessibleContextHelper::ensureDisposed( )
	{
		if ( !GetBroadcastHelper().bDisposed )
		{
			OSL_ENSURE( 0 == m_refCount, "OAccessibleContextHelper::ensureDisposed: this method _has_ to be called from without your dtor only!" );
			acquire();
			dispose();
		}
	}

	//---------------------------------------------------------------------
	void OAccessibleContextHelper::lateInit( const Reference< XAccessible >& _rxAccessible )
	{
		m_pImpl->setCreator( _rxAccessible );
	}

	//---------------------------------------------------------------------
	Reference< XAccessible > OAccessibleContextHelper::getAccessibleCreator( ) const
	{
		return m_pImpl->getCreator();
	}

	//---------------------------------------------------------------------
	sal_Int32 SAL_CALL OAccessibleContextHelper::getAccessibleIndexInParent(  ) throw (RuntimeException)
	{
		OExternalLockGuard aGuard( this );

		// -1 for child not found/no parent (according to specification)
		sal_Int32 nRet = -1;

		try
		{
			
			Reference< XAccessibleContext > xParentContext( implGetParentContext() );

			//  iterate over parent's children and search for this object
			if ( xParentContext.is() )
			{
				// our own XAccessible for comparing with the children of our parent
				Reference< XAccessible > xCreator( m_pImpl->getCreator() );

				OSL_ENSURE( xCreator.is(), "OAccessibleContextHelper::getAccessibleIndexInParent: invalid creator!" );
					// two ideas why this could be NULL:
					// * nobody called our late ctor (init), so we never had a creator at all -> bad
					// * the creator is already dead. In this case, we should have been disposed, and
					//	 never survived the above OContextEntryGuard.
					// in all other situations the creator should be non-NULL

				if ( xCreator.is() )
				{
					sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
					for ( sal_Int32 nChild = 0; ( nChild < nChildCount ) && ( -1 == nRet ); ++nChild )
					{
						Reference< XAccessible > xChild( xParentContext->getAccessibleChild( nChild ) );
						if ( xChild.get() == xCreator.get() )
							nRet = nChild;
					}
				}
			}
		}
		catch( const Exception& )
		{
			OSL_ENSURE( sal_False, "OAccessibleContextHelper::getAccessibleIndexInParent: caught an exception!" );
		}

		return nRet;
	}

	//---------------------------------------------------------------------
	Locale SAL_CALL OAccessibleContextHelper::getLocale(  ) throw (IllegalAccessibleComponentStateException, RuntimeException)
	{
		// simply ask the parent
		Reference< XAccessible > xParent = getAccessibleParent();
		Reference< XAccessibleContext > xParentContext;
		if ( xParent.is() )
			xParentContext = xParent->getAccessibleContext();

		if ( !xParentContext.is() )
			throw IllegalAccessibleComponentStateException( ::rtl::OUString(), *this );

		return xParentContext->getLocale();
	}

	//---------------------------------------------------------------------
	Reference< XAccessibleContext > OAccessibleContextHelper::implGetParentContext() SAL_THROW( ( RuntimeException ) )
	{
		Reference< XAccessible > xParent = getAccessibleParent();
		Reference< XAccessibleContext > xParentContext;
		if ( xParent.is() )
			xParentContext = xParent->getAccessibleContext();
		return xParentContext;
	}

//.........................................................................
}	// namespace comphelper
//.........................................................................


