/**************************************************************
 * 
 * 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_forms.hxx"
#include "EventThread.hxx"
#include <comphelper/guarding.hxx>
#include <tools/debug.hxx>

//.........................................................................
namespace frm
{
//.........................................................................
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::lang;

DBG_NAME( OComponentEventThread )
OComponentEventThread::OComponentEventThread( ::cppu::OComponentHelper* pCompImpl ) :
	m_pCompImpl( pCompImpl )
{
	DBG_CTOR( OComponentEventThread, NULL );

	increment(m_refCount);

	// Eine Referenz des Controls halten
	{
		InterfaceRef xIFace(static_cast<XWeak*>(pCompImpl));
		query_interface(xIFace, m_xComp);
	}

	// und uns an dem Control anmelden
	{
		Reference<XEventListener> xEvtLstnr = static_cast<XEventListener*>(this);
		m_xComp->addEventListener( xEvtLstnr );
	}

	decrement(m_refCount);
}

OComponentEventThread::~OComponentEventThread()
{
	DBG_DTOR( OComponentEventThread, NULL );

	DBG_ASSERT( m_aEvents.size() == 0,
		"OComponentEventThread::~OComponentEventThread: Kein dispose gerufen?" );

    impl_clearEventQueue();
}

Any SAL_CALL OComponentEventThread::queryInterface(const Type& _rType) throw (RuntimeException)
{
	Any aReturn;

	aReturn = OWeakObject::queryInterface(_rType);

	if (!aReturn.hasValue())
		aReturn = ::cppu::queryInterface(_rType,
			static_cast<XEventListener*>(this)
		);

	return aReturn;
}

void OComponentEventThread::impl_clearEventQueue()
{
	while ( m_aEvents.size() )
    {
		delete *m_aEvents.begin();
        m_aEvents.erase( m_aEvents.begin() );
    }
	m_aControls.erase( m_aControls.begin(), m_aControls.end() );
	m_aFlags.erase( m_aFlags.begin(), m_aFlags.end() );
}

void OComponentEventThread::disposing( const EventObject& evt ) throw ( ::com::sun::star::uno::RuntimeException)
{
	if( evt.Source == m_xComp )
	{
		::osl::MutexGuard aGuard( m_aMutex );

		// Event-Listener abmelden
		Reference<XEventListener>  xEvtLstnr = static_cast<XEventListener*>(this);
		m_xComp->removeEventListener( xEvtLstnr );

		// Event-Queue loeschen
        impl_clearEventQueue();

		// Das Control loslassen und pCompImpl auf 0 setzen, damit der
		// Thread weiss, dass er sich beenden soll.
		m_xComp = 0;
		m_pCompImpl = 0;

		// Den Thread aufwecken und beenden.
		m_aCond.set();
		terminate();
	}
}

void OComponentEventThread::addEvent( const EventObject* _pEvt, sal_Bool bFlag )
{
	Reference<XControl>  xTmp;
	addEvent( _pEvt, xTmp, bFlag );
}

void OComponentEventThread::addEvent( const EventObject* _pEvt,
								   const Reference<XControl>& rControl,
								   sal_Bool bFlag )
{
	::osl::MutexGuard aGuard( m_aMutex );

	// Daten in die Queue stellen
	m_aEvents.push_back( cloneEvent( _pEvt ) );

	Reference<XWeak>		xWeakControl(rControl, UNO_QUERY);
	Reference<XAdapter>	xControlAdapter = xWeakControl.is() ? xWeakControl->queryAdapter() : Reference<XAdapter>();
	m_aControls.push_back( xControlAdapter );

	m_aFlags.push_back( bFlag );

	// Thread aufwecken
	m_aCond.set();
}

//---------------------------------------------------------------------
//--- 22.08.01 15:48:15 -----------------------------------------------

void OComponentEventThread::implStarted( )
{
	acquire( );
}

//---------------------------------------------------------------------
//--- 22.08.01 15:48:16 -----------------------------------------------

void OComponentEventThread::implTerminated( )
{
	release( );
}

//---------------------------------------------------------------------
//--- 22.08.01 15:47:31 -----------------------------------------------

void SAL_CALL OComponentEventThread::kill()
{
	OComponentEventThread_TBASE::kill();

	implTerminated( );
}

//---------------------------------------------------------------------
//--- 22.08.01 15:47:33 -----------------------------------------------

void SAL_CALL OComponentEventThread::onTerminated()
{
	OComponentEventThread_TBASE::onTerminated();

	implTerminated( );
}

void OComponentEventThread::run()
{
	implStarted( );

	// uns selbst festhalten, damit wir nicht geloescht werden,
	// wenn zwischendrinne mal ein dispose gerufen wird.
	InterfaceRef xThis(static_cast<XWeak*>(this));

	do
	{
		::osl::MutexGuard aGuard(m_aMutex);

		while( m_aEvents.size() > 0 )
		{
			// Das Control holen und festhalten, damit es waehrend des
			// actionPerformed nicht geloescht werden kann.
			Reference<XComponent>  xComp = m_xComp;
			::cppu::OComponentHelper *pCompImpl = m_pCompImpl;

            ThreadEvents::iterator firstEvent( m_aEvents.begin() );
			EventObject* pEvt = *firstEvent;
            m_aEvents.erase( firstEvent );

            ThreadObjects::iterator firstControl( m_aControls.begin() );
			Reference<XAdapter> xControlAdapter = *firstControl;
            m_aControls.erase( firstControl );

            ThreadBools::iterator firstFlag( m_aFlags.begin() );
			sal_Bool bFlag = *firstFlag;
            m_aFlags.erase( firstFlag );

			{
				MutexRelease aReleaseOnce(m_aMutex);
				// Weil ein queryHardRef eine Exception schmeissen kann sollte
				// es nicht bei gelocktem Mutex aufgerufen werden.
				Reference<XControl>  xControl;
				if ( xControlAdapter.is() )
					query_interface(xControlAdapter->queryAdapted(), xControl);

				if( xComp.is() )
					processEvent( pCompImpl, pEvt, xControl, bFlag );
			}

			delete pEvt;
		};

		// Nach einem dispose kennen wir das Control nicht mehr. Dann darf
		// auch nicht gewartet werden.
		if( !m_xComp.is() )
			return;

		// Warte-Bedingung zuruecksetzen
		m_aCond.reset();
		{
			MutexRelease aReleaseOnce(m_aMutex);
			// und warten ... falls nicht zwischenzeitlich doch noch ein
			// Event eingetroffen ist.
			m_aCond.wait();
		}
	}
	while( sal_True );
}

//.........................................................................
}	// namespace frm
//.........................................................................

