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

#include <com/sun/star/util/XCloseBroadcaster.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/frame/DoubleInitializationException.hpp>
#include <com/sun/star/frame/DoubleInitializationException.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>

#include "instancelocker.hxx"

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


// ====================================================================
// OInstanceLocker
// ====================================================================

// --------------------------------------------------------
OInstanceLocker::OInstanceLocker( const uno::Reference< uno::XComponentContext >& xContext )
: m_xContext( xContext )
, m_pLockListener( NULL )
, m_pListenersContainer( NULL )
, m_bDisposed( sal_False )
, m_bInitialized( sal_False )
{
}

// --------------------------------------------------------
OInstanceLocker::~OInstanceLocker()
{
	if ( !m_bDisposed )
	{
		m_refCount++; // to call dispose
		try {
			dispose();
		}
		catch ( uno::RuntimeException& )
		{}
	}

	if ( m_pListenersContainer )
	{
		delete m_pListenersContainer;
		m_pListenersContainer = NULL;
	}
}

// XComponent
// --------------------------------------------------------
void SAL_CALL OInstanceLocker::dispose()
	throw (uno::RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );

	if ( m_bDisposed )
		throw lang::DisposedException();

   	lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
	if ( m_pListenersContainer )
		m_pListenersContainer->disposeAndClear( aSource );

	if ( m_xLockListener.is() )
	{
		if ( m_pLockListener )
		{
			m_pLockListener->Dispose();
			m_pLockListener = NULL;
		}
		m_xLockListener = uno::Reference< uno::XInterface >();
	}

	m_bDisposed = sal_True;
}

// --------------------------------------------------------
void SAL_CALL OInstanceLocker::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
	throw (uno::RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO

	if ( !m_pListenersContainer )
		m_pListenersContainer = new ::cppu::OInterfaceContainerHelper( m_aMutex );

	m_pListenersContainer->addInterface( xListener );
}

// --------------------------------------------------------
void SAL_CALL OInstanceLocker::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
	throw (uno::RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	if ( m_pListenersContainer )
		m_pListenersContainer->removeInterface( xListener );
}

// XInitialization
// --------------------------------------------------------
void SAL_CALL OInstanceLocker::initialize( const uno::Sequence< uno::Any >& aArguments )
	throw (uno::Exception, uno::RuntimeException)
{
	::osl::MutexGuard aGuard( m_aMutex );
	if ( m_bInitialized )
		throw frame::DoubleInitializationException();

	if ( m_bDisposed )
		throw lang::DisposedException(); // TODO
	
	if ( !m_refCount )
		throw uno::RuntimeException(); // the object must be refcounted already!

	uno::Reference< uno::XInterface > xInstance;
	uno::Reference< embed::XActionsApproval > xApproval;
	sal_Int32 nModes = 0;

	try
	{
		sal_Int32 nLen = aArguments.getLength();
		if ( nLen < 2 || nLen > 3 )
			throw lang::IllegalArgumentException(
							::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Wrong count of parameters!" ) ),
							uno::Reference< uno::XInterface >(),
							0 );

		if ( !( aArguments[0] >>= xInstance ) || !xInstance.is() )
			throw lang::IllegalArgumentException(
					::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Nonempty reference is expected as the first argument!" ) ),
					uno::Reference< uno::XInterface >(),
					0 );

		if (
            !( aArguments[1] >>= nModes ) ||
            (
              !( nModes & embed::Actions::PREVENT_CLOSE ) &&
              !( nModes & embed::Actions::PREVENT_TERMINATION ) 
            )
           )
        {
			throw lang::IllegalArgumentException(
					::rtl::OUString(
							RTL_CONSTASCII_USTRINGPARAM("The correct modes set is expected as the second argument!" ) ),
					uno::Reference< uno::XInterface >(),
					0 );
        }

		if ( nLen == 3 && !( aArguments[2] >>= xApproval ) )
			throw lang::IllegalArgumentException(
					::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("If the third argument is provided, it must be XActionsApproval implementation!" ) ),
					uno::Reference< uno::XInterface >(),
					0 );
	
		m_pLockListener = new OLockListener( uno::Reference< lang::XComponent > ( static_cast< lang::XComponent* >( this ) ),
											xInstance,
											nModes,
											xApproval );
		m_xLockListener = uno::Reference< uno::XInterface >( static_cast< OWeakObject* >( m_pLockListener ) );
		m_pLockListener->Init();
	}
	catch( uno::Exception& )
	{
		dispose();
		throw;
	}

	m_bInitialized = sal_True;
}


// XServiceInfo
// --------------------------------------------------------
::rtl::OUString SAL_CALL OInstanceLocker::getImplementationName(  )
	throw (uno::RuntimeException)
{
	return getImplementationName_static();
}

// --------------------------------------------------------
::sal_Bool SAL_CALL OInstanceLocker::supportsService( const ::rtl::OUString& ServiceName )
	throw (uno::RuntimeException)
{
	uno::Sequence< ::rtl::OUString > aSeq = getSupportedServiceNames();

	for ( sal_Int32 nInd = 0; nInd < aSeq.getLength(); nInd++ )
    	if ( ServiceName.compareTo( aSeq[nInd] ) == 0 )
        	return sal_True;

	return sal_False;
}

// --------------------------------------------------------
uno::Sequence< ::rtl::OUString > SAL_CALL OInstanceLocker::getSupportedServiceNames()
	throw (uno::RuntimeException)
{
	return getSupportedServiceNames_static();
}

// Static methods
// --------------------------------------------------------
uno::Sequence< ::rtl::OUString > SAL_CALL OInstanceLocker::getSupportedServiceNames_static()
{
    const rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.InstanceLocker" ) );
    return uno::Sequence< rtl::OUString >( &aServiceName, 1 );
}

// --------------------------------------------------------
::rtl::OUString SAL_CALL OInstanceLocker::getImplementationName_static()
{
    return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.embed.InstanceLocker" ) );
}

// --------------------------------------------------------
uno::Reference< uno::XInterface > SAL_CALL OInstanceLocker::Create(
								const uno::Reference< uno::XComponentContext >& rxContext )
{
    return static_cast< cppu::OWeakObject * >( new OInstanceLocker( rxContext ) );
}



// ====================================================================
// OLockListener
// ====================================================================

// --------------------------------------------------------
OLockListener::OLockListener( const uno::WeakReference< lang::XComponent >& xWrapper,
					const uno::Reference< uno::XInterface >& xInstance,
					sal_Int32 nMode,
					const uno::Reference< embed::XActionsApproval > xApproval )
: m_xInstance( xInstance )
, m_xApproval( xApproval )
, m_xWrapper( xWrapper )
, m_bDisposed( sal_False )
, m_bInitialized( sal_False )
, m_nMode( nMode )
{
}

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

// --------------------------------------------------------
void OLockListener::Dispose()
{
	::osl::ResettableMutexGuard aGuard( m_aMutex );

	if ( m_bDisposed )
		return;

	if ( m_nMode & embed::Actions::PREVENT_CLOSE )
	{
		try
		{
			uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xInstance, uno::UNO_QUERY );
			if ( xCloseBroadcaster.is() )
				xCloseBroadcaster->removeCloseListener( static_cast< util::XCloseListener* >( this ) );

			uno::Reference< util::XCloseable > xCloseable( m_xInstance, uno::UNO_QUERY );
			if ( xCloseable.is() )
				xCloseable->close( sal_True );
		}
		catch( uno::Exception& )
		{}
	}

	if ( m_nMode & embed::Actions::PREVENT_TERMINATION )
	{
		try
		{
			uno::Reference< frame::XDesktop > xDesktop( m_xInstance, uno::UNO_QUERY_THROW );
			xDesktop->removeTerminateListener( static_cast< frame::XTerminateListener* >( this ) );
		}
		catch( uno::Exception& )
		{}
	}
	
	m_xInstance = uno::Reference< uno::XInterface >();
	m_bDisposed = sal_True;
}

// XEventListener
// --------------------------------------------------------
void SAL_CALL OLockListener::disposing( const lang::EventObject& aEvent )
	throw (uno::RuntimeException)
{
	::osl::ResettableMutexGuard aGuard( m_aMutex );

	// object is disposed
	if ( aEvent.Source == m_xInstance )
	{
		// the object does not listen for anything any more
		m_nMode = 0;

		// dispose the wrapper;
		uno::Reference< lang::XComponent > xComponent( m_xWrapper.get(), uno::UNO_QUERY );
		aGuard.clear();
		if ( xComponent.is() )
		{
			try { xComponent->dispose(); }
			catch( uno::Exception& ){}
		}
	}
}


// XCloseListener
// --------------------------------------------------------
void SAL_CALL OLockListener::queryClosing( const lang::EventObject& aEvent, sal_Bool )
	throw (util::CloseVetoException, uno::RuntimeException)
{
	// GetsOwnership parameter is always ignored, the user of the service must close the object always
	::osl::ResettableMutexGuard aGuard( m_aMutex );
	if ( !m_bDisposed && aEvent.Source == m_xInstance && ( m_nMode & embed::Actions::PREVENT_CLOSE ) )
	{
		try
		{
			uno::Reference< embed::XActionsApproval > xApprove = m_xApproval;

			// unlock the mutex here
			aGuard.clear();

			if ( xApprove.is() && xApprove->approveAction( embed::Actions::PREVENT_CLOSE ) )
				throw util::CloseVetoException();
		}
		catch( util::CloseVetoException& )
		{
			// rethrow this exception
			throw;
		}
		catch( uno::Exception& )
		{
			// no action should be done
		}
	}
}

// --------------------------------------------------------
void SAL_CALL OLockListener::notifyClosing( const lang::EventObject& aEvent )
	throw (uno::RuntimeException)
{
	::osl::ResettableMutexGuard aGuard( m_aMutex );

	// object is closed, no reason to listen
	if ( aEvent.Source == m_xInstance )
	{
		uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( aEvent.Source, uno::UNO_QUERY );
		if ( xCloseBroadcaster.is() )
		{
			xCloseBroadcaster->removeCloseListener( static_cast< util::XCloseListener* >( this ) );
			m_nMode &= ~embed::Actions::PREVENT_CLOSE;
			if ( !m_nMode )
			{
				// dispose the wrapper;
				uno::Reference< lang::XComponent > xComponent( m_xWrapper.get(), uno::UNO_QUERY );
				aGuard.clear();
				if ( xComponent.is() )
				{
					try { xComponent->dispose(); }
					catch( uno::Exception& ){}
				}
			}
		}
	}
}


// XTerminateListener
// --------------------------------------------------------
void SAL_CALL OLockListener::queryTermination( const lang::EventObject& aEvent )
	throw (frame::TerminationVetoException, uno::RuntimeException)
{
	::osl::ResettableMutexGuard aGuard( m_aMutex );
	if ( aEvent.Source == m_xInstance && ( m_nMode & embed::Actions::PREVENT_TERMINATION ) )
	{
		try
		{
			uno::Reference< embed::XActionsApproval > xApprove = m_xApproval;

			// unlock the mutex here
			aGuard.clear();

			if ( xApprove.is() && xApprove->approveAction( embed::Actions::PREVENT_TERMINATION ) )
				throw frame::TerminationVetoException();
		}
		catch( frame::TerminationVetoException& )
		{
			// rethrow this exception
			throw;
		}
		catch( uno::Exception& )
		{
			// no action should be done
		}
	}
}

// --------------------------------------------------------
void SAL_CALL OLockListener::notifyTermination( const lang::EventObject& aEvent )
	throw (uno::RuntimeException)
{
	::osl::ResettableMutexGuard aGuard( m_aMutex );

	// object is terminated, no reason to listen
	if ( aEvent.Source == m_xInstance )
	{
		uno::Reference< frame::XDesktop > xDesktop( aEvent.Source, uno::UNO_QUERY );
		if ( xDesktop.is() )
		{
			try
			{
				xDesktop->removeTerminateListener( static_cast< frame::XTerminateListener* >( this ) );
				m_nMode &= ~embed::Actions::PREVENT_TERMINATION;
				if ( !m_nMode )
				{
					// dispose the wrapper;
					uno::Reference< lang::XComponent > xComponent( m_xWrapper.get(), uno::UNO_QUERY );
					aGuard.clear();
					if ( xComponent.is() )
					{
						try { xComponent->dispose(); }
						catch( uno::Exception& ){}
					}
				}
			}
			catch( uno::Exception& )
			{}
		}
	}
}


// XInitialization
// --------------------------------------------------------
sal_Bool OLockListener::Init()
{
	::osl::ResettableMutexGuard aGuard( m_aMutex );

	if ( m_bDisposed || m_bInitialized )
		return sal_False;

	try
	{
		if ( m_nMode & embed::Actions::PREVENT_CLOSE )
		{
			uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( m_xInstance, uno::UNO_QUERY_THROW );
			xCloseBroadcaster->addCloseListener( static_cast< util::XCloseListener* >( this ) );
		}

		if ( m_nMode & embed::Actions::PREVENT_TERMINATION )
		{
			uno::Reference< frame::XDesktop > xDesktop( m_xInstance, uno::UNO_QUERY_THROW );
			xDesktop->addTerminateListener( static_cast< frame::XTerminateListener* >( this ) );
		}
	}
	catch( uno::Exception& )
	{
		// dispose the wrapper;
		uno::Reference< lang::XComponent > xComponent( m_xWrapper.get(), uno::UNO_QUERY );
		aGuard.clear();
		if ( xComponent.is() )
		{
			try { xComponent->dispose(); }
			catch( uno::Exception& ){}
		}

		throw;
	}

	m_bInitialized = sal_True;

	return sal_True;
}

void createRegistryInfo_OInstanceLocker()
{
    static ::comphelper::module::OAutoRegistration< OInstanceLocker > aAutoRegistration;
}
