/**************************************************************
 *
 * 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_framework.hxx"
#include <dispatch/helpagentdispatcher.hxx>
#include <threadhelp/readguard.hxx>
#include <threadhelp/writeguard.hxx>
#include <com/sun/star/awt/XWindow2.hpp>
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/awt/Size.hpp>
#include <com/sun/star/awt/Rectangle.hpp>
#include <toolkit/helper/vclunohelper.hxx>
#include <svtools/helpopt.hxx>
#include <vcl/svapp.hxx>
#include <vcl/help.hxx>

namespace css = ::com::sun::star;

//........................................................................
namespace framework
{

//-----------------------------------------------
DEFINE_XINTERFACE_4(HelpAgentDispatcher                         ,
                    OWeakObject                                 ,
                    DIRECT_INTERFACE (css::lang::XTypeProvider ),
                    DIRECT_INTERFACE (css::frame::XDispatch    ),
                    DIRECT_INTERFACE (css::awt::XWindowListener),
                    DIRECT_INTERFACE (css::lang::XEventListener))

//-----------------------------------------------
DEFINE_XTYPEPROVIDER_2(HelpAgentDispatcher     ,
                       css::lang::XTypeProvider,
                       css::frame::XDispatch   )

//--------------------------------------------------------------------
HelpAgentDispatcher::HelpAgentDispatcher( const css::uno::Reference< css::frame::XFrame >& xParentFrame)
	: ThreadHelpBase	(&Application::GetSolarMutex())
	, m_sCurrentURL		(							  )
	, m_xContainerWindow(							  )
	, m_xAgentWindow	(							  )
	, m_aTimer			(							  )
	, m_xSelfHold		(							  )
{
	// It's required that this class has to be constructed with a valid frame.
	// And "valid" means: the frame must already bound to a valid container window.
	m_xContainerWindow = xParentFrame->getContainerWindow();
}

//--------------------------------------------------------------------
HelpAgentDispatcher::~HelpAgentDispatcher()
{
	implts_stopTimer();
	implts_ignoreCurrentURL();

	// Needed ... because it was create as "new VCLWindow()" ! Such windows must be disposed explicitly.
	css::uno::Reference< css::lang::XComponent > xAgentWindow(m_xAgentWindow, css::uno::UNO_QUERY);
	if (xAgentWindow.is())
		xAgentWindow->dispose();
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::dispatch(const css::util::URL& 								   aURL ,
											const css::uno::Sequence< css::beans::PropertyValue >&)
	throw(css::uno::RuntimeException)
{
	// silently drop the request if the new URL was marked to be ignored next time.
	sal_Int32 nAllowedToIgnore = SvtHelpOptions().getAgentIgnoreURLCounter(aURL.Complete);
	if (nAllowedToIgnore < 1)
		return;

	// stop the expiration timer for the old URL
	// The timer will add the old URL to the list of ignorable URLs.
	// So m_sCurrentURL must be set AFTER the timer was stopped !!!
	implts_stopTimer();

	// SAFE ->
	WriteGuard aWriteLock(m_aLock);
	m_sCurrentURL = aURL.Complete;
	aWriteLock.unlock();
	// <- SAFE

	// start the expiration timer for the new URL
	implts_startTimer();

	// make sure the agent window is shown
	implts_showAgentWindow();
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >&,
													 const css::util::URL&)
	throw(css::uno::RuntimeException)
{
	// no status available
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >&,
														const css::util::URL&)
	throw(css::uno::RuntimeException)
{
	// no status available
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::windowResized(const css::awt::WindowEvent&)
	throw(css::uno::RuntimeException)
{
	implts_positionAgentWindow();
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::windowMoved(const css::awt::WindowEvent&)
	throw(css::uno::RuntimeException)
{
	implts_positionAgentWindow();
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::windowShown(const css::lang::EventObject&)
	throw(css::uno::RuntimeException)
{
	implts_showAgentWindow();
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::windowHidden(const css::lang::EventObject&)
	throw(css::uno::RuntimeException)
{
	implts_hideAgentWindow();
}

//--------------------------------------------------------------------
void SAL_CALL HelpAgentDispatcher::disposing(const css::lang::EventObject& aEvent)
	throw(css::uno::RuntimeException)
{
	// SAFE ->
	WriteGuard aWriteLock(m_aLock);

	// Already disposed ?!
	if (! m_xContainerWindow.is())
		return;
	// Wrong broadcaster ?!
	if (aEvent.Source != m_xContainerWindow)
		return;

    css::uno::Reference< css::uno::XInterface > xSelfHoldUntilMethodEnds(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY_THROW);
	m_xSelfHold.clear();

	aWriteLock.unlock();
	// <- SAFE

	implts_stopTimer();
	implts_hideAgentWindow();
	implts_ignoreCurrentURL();

	// SAFE ->
	aWriteLock.lock();
	m_xContainerWindow.clear();
	css::uno::Reference< css::lang::XComponent > xAgentWindow(m_xAgentWindow, css::uno::UNO_QUERY);
	m_xAgentWindow.clear();
	aWriteLock.unlock();
	// <- SAFE

	// Needed ... because it was create as "new VCLWindow()" ! Such windows must be disposed explicitly.
	if (xAgentWindow.is())
		xAgentWindow->dispose();
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::helpRequested()
{
	implts_stopTimer();
	implts_hideAgentWindow();
	implts_acceptCurrentURL();
}

//-----------------------------------------------
void HelpAgentDispatcher::closeAgent()
{
	implts_stopTimer();
	implts_hideAgentWindow();
	implts_ignoreCurrentURL();
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_acceptCurrentURL()
{
	// SAFE ->
	WriteGuard aWriteLock(m_aLock);

	::rtl::OUString sAcceptedURL  = m_sCurrentURL;
					m_sCurrentURL = ::rtl::OUString();

	aWriteLock.unlock();
	// <- SAFE

	// We must make sure that this URL isn't marked as ignored by the user.
	// Otherwise the user won't see the corresponding help content in the future.
	SvtHelpOptions().resetAgentIgnoreURLCounter(sAcceptedURL);

	// show the right help content
	// SOLAR SAFE ->
	{
		::vos::OGuard aSolarLock(Application::GetSolarMutex());
		Help* pHelp = Application::GetHelp();
		if (pHelp)
			pHelp->Start(sAcceptedURL, NULL);
	}
	// <- SOLAR SAFE
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_ignoreCurrentURL()
{
	// SAFE ->
	WriteGuard aWriteLock(m_aLock);

	::rtl::OUString sIgnoredURL   = m_sCurrentURL;
					m_sCurrentURL = ::rtl::OUString();

	aWriteLock.unlock();
	// <- SAFE

	if (sIgnoredURL.getLength())
		SvtHelpOptions().decAgentIgnoreURLCounter(sIgnoredURL);
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_stopTimer()
{
	// SAFE ->
	WriteGuard aWriteLock(m_aLock);
	m_xSelfHold.clear();
	aWriteLock.unlock();
	// <- SAFE

	// SOLAR SAFE ->
	// Timer access needs no "own lock" ! It lives if we live ...
	// But it requires locking of the solar mutex ... because it's a vcl based timer.
	{
		::vos::OGuard aSolarLock(Application::GetSolarMutex());
		if (! m_aTimer.IsActive())
			return;
		m_aTimer.Stop();
	}
	// <- SOLAR SAFE
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_startTimer()
{
	// SOLAR SAFE ->
	// Timer access needs no "own lock" ! It lives if we live ...
	// But it requires locking of the solar mutex ... because it's a vcl based timer.
	{
		::vos::OGuard aSolarLock(Application::GetSolarMutex());
		if (m_aTimer.IsActive())
			return;
	}
	// <- SOLAR SAFE

	// SAFE ->
	// Timer uses pointer to this help agent dispatcher ...
	// But normally we are ref counted. So we must make sure that this
	// dispatcher isn't killed during the timer runs .-)
	WriteGuard aWriteLock(m_aLock);
	m_xSelfHold = css::uno::Reference< css::uno::XInterface >(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY_THROW);
	aWriteLock.unlock();
	// <- SAFE

	sal_Int32 nTime = SvtHelpOptions().GetHelpAgentTimeoutPeriod();

	// SOLAR SAFE ->
	// Timer access needs no "own lock" ! It lives if we live ...
	// But it requires locking of the solar mutex ... because it's a vcl based timer.
	{
		::vos::OGuard aSolarLock(Application::GetSolarMutex());
		m_aTimer.SetTimeout(nTime*1000); // sec => ms !
		m_aTimer.Start();
	}
}

//-----------------------------------------------
IMPL_LINK(HelpAgentDispatcher, implts_timerExpired, void*,)
{
    // This method is called by using a pointer to us.
    // But we must be aware that we can be destroyed hardly
    // if our uno reference will be gone!
    // => Hold this object alive till this method finish its work.
	// SAFE ->
	WriteGuard aWriteLock(m_aLock);
    css::uno::Reference< css::uno::XInterface > xSelfHoldUntilMethodEnds(static_cast< css::frame::XDispatch* >(this), css::uno::UNO_QUERY_THROW);
	m_xSelfHold.clear();
	aWriteLock.unlock();
	// <- SAFE

	implts_hideAgentWindow();
	implts_ignoreCurrentURL();

	return 0;
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_showAgentWindow()
{
	// SAFE ->
	ReadGuard aReadLock(m_aLock);
	css::uno::Reference< css::awt::XWindow2 > xContainerWindow(m_xContainerWindow, css::uno::UNO_QUERY_THROW);
	aReadLock.unlock();
	// <- SAFE

	css::uno::Reference< css::awt::XWindow > xAgentWindow = implts_ensureAgentWindow();

	if (
		(xContainerWindow.is() 		  ) &&
		(xAgentWindow.is() 		  	  ) &&
		(xContainerWindow->isVisible())
	   )
	{
		// make sure that agent window resists at the right place .-)
		implts_positionAgentWindow();
		xAgentWindow->setVisible(sal_True);
	}
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_hideAgentWindow()
{
	css::uno::Reference< css::awt::XWindow > xAgentWindow = implts_ensureAgentWindow();
	if (xAgentWindow.is())
		xAgentWindow->setVisible(sal_False);
}

//--------------------------------------------------------------------
void HelpAgentDispatcher::implts_positionAgentWindow()
{
	// SAFE ->
	ReadGuard aReadLock(m_aLock);
	css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
	aReadLock.unlock();
	// <- SAFE

	css::uno::Reference< css::awt::XWindow > xAgentWindow = implts_ensureAgentWindow();
	if (
		(! xContainerWindow.is())  ||
		(! xAgentWindow.is()    )
	   )
		return;

		  ::svt::HelpAgentWindow* pAgentWindow   = (::svt::HelpAgentWindow*)VCLUnoHelper::GetWindow(xAgentWindow);
	const css::awt::Rectangle 	  aContainerSize = xContainerWindow->getPosSize();
	const Size                	  aAgentSize     = pAgentWindow->getPreferredSizePixel();

    sal_Int32 nW = aAgentSize.Width() ;
    sal_Int32 nH = aAgentSize.Height();

    if (nW < 1)
        nW = 100;
    if (nH < 1)
        nH = 100;

	sal_Int32 nX = aContainerSize.Width  - nW;
	sal_Int32 nY = aContainerSize.Height - nH;

	// TODO: use a surrogate if the container window is too small to contain the full-sized agent window
	xAgentWindow->setPosSize(nX, nY, nW, nH, css::awt::PosSize::POSSIZE);
}

//--------------------------------------------------------------------
css::uno::Reference< css::awt::XWindow > HelpAgentDispatcher::implts_ensureAgentWindow()
{
	// SAFE ->
	ReadGuard aReadLock(m_aLock);
	if (m_xAgentWindow.is())
		return m_xAgentWindow;
	css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
	aReadLock.unlock();
	// <- SAFE

	if (!xContainerWindow.is())
		return css::uno::Reference< css::awt::XWindow >();

	::svt::HelpAgentWindow* pAgentWindow = 0;
	// SOLAR SAFE ->
	{
		::vos::OGuard aSolarLock(Application::GetSolarMutex());
		// create the agent window
		Window*	pContainerWindow = VCLUnoHelper::GetWindow(xContainerWindow);
				pAgentWindow 	 = new ::svt::HelpAgentWindow(pContainerWindow);
		pAgentWindow->setCallback(this);
	}
	// <- SOLAR SAFE

	// SAFE ->
	WriteGuard aWriteLock(m_aLock);
	m_xAgentWindow = VCLUnoHelper::GetInterface(pAgentWindow);
	css::uno::Reference< css::awt::XWindow > xAgentWindow = m_xAgentWindow;
	aWriteLock.unlock();
	// <- SAFE

	// add as window listener to the container window so we can maintain the property position of the agent window
	xContainerWindow->addWindowListener(this);

	// SOLAR SAFE ->
	{
		::vos::OGuard aSolarLock(Application::GetSolarMutex());
		// establish callback for our internal used timer.
		// Note: Its only active, if the timer will be started ...
		m_aTimer.SetTimeoutHdl(LINK(this, HelpAgentDispatcher, implts_timerExpired));
	}
	// <- SOLAR SAFE

	return xAgentWindow;
}

} // namespace framework
