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

#include "ViewShellManager.hxx"
#include "ViewShell.hxx"
#include "ViewShellBase.hxx"
#include "Window.hxx"
#include "DrawDocShell.hxx"
#include "FormShellManager.hxx"

#include <sfx2/dispatch.hxx>
#include <svx/svxids.hrc>
#include <svx/fmshell.hxx>

#include <hash_map>

#undef VERBOSE
//#define VERBOSE 2

namespace sd {

namespace {

/** The ShellDescriptor class is used to shells together with their ids and
	the factory that was used to create the shell.

	The shell pointer may be NULL. In that case the shell is created on
	demand by a factory.

	The factory pointer may be NULL. In that case the shell pointer is
	given to the ViewShellManager.

	Shell pointer and factory pointer can but should not be NULL at the same
	time.
*/
class ShellDescriptor {
public:
	SfxShell* mpShell;
	ShellId mnId;
	ViewShellManager::SharedShellFactory mpFactory;
	bool mbIsListenerAddedToWindow;

	ShellDescriptor ();
	ShellDescriptor (SfxShell* pShell, ShellId nId);
	ShellDescriptor (const ShellDescriptor& rDescriptor);
	ShellDescriptor& operator= (const ShellDescriptor& rDescriptor);
	bool IsMainViewShell (void) const;
	::Window* GetWindow (void) const;
};




/** This functor can be used to search for a shell in an STL container when the
	shell pointer is given.
*/
class IsShell : public ::std::unary_function<ShellDescriptor,bool>
{
public:
	IsShell (const SfxShell* pShell) : mpShell(pShell) {}
	bool operator() (const ShellDescriptor& rDescriptor)
	{ return rDescriptor.mpShell == mpShell; }
private:
	const SfxShell* mpShell;
};




/** This functor can be used to search for a shell in an STL container when the
	id of the shell is given.
*/
class IsId : public ::std::unary_function<ShellDescriptor,bool>
{
public:
	IsId (ShellId nId) : mnId(nId) {}
	bool operator() (const ShellDescriptor& rDescriptor)
	{ return rDescriptor.mnId == mnId; }
private:
	ShellId mnId;
};

} // end of anonymous namespace




class ViewShellManager::Implementation
{
public:
	Implementation (
		ViewShellManager& rManager,
		ViewShellBase& rBase);
	~Implementation (void);

	void AddShellFactory (
		const SfxShell* pViewShell,
		const SharedShellFactory& rpFactory);
	void RemoveShellFactory (
		const SfxShell* pViewShell,
		const SharedShellFactory& rpFactory);
	void ActivateViewShell (
		ViewShell* pViewShell);
	void DeactivateViewShell (const ViewShell& rShell);
	void ActivateShell (SfxShell& rShell);
	void DeactivateShell (const SfxShell& rShell);
	void ActivateShell (const ShellDescriptor& rDescriptor);
	void SetFormShell (const ViewShell* pViewShell, FmFormShell* pFormShell, bool bAbove);
	void ActivateSubShell (const SfxShell& rParentShell, ShellId nId);
	void DeactivateSubShell (const SfxShell& rParentShell, ShellId nId);
	void MoveSubShellToTop (const SfxShell& rParentShell, ShellId nId);
	void MoveToTop (const SfxShell& rParentShell);
	SfxShell* GetShell (ShellId nId) const;
	SfxShell* GetTopShell (void) const;
	void Shutdown (void);
	void InvalidateAllSubShells (const SfxShell* pParentShell);

	/** Remove all shells from the SFX stack above and including the given
		shell.
	*/
	void TakeShellsFromStack (const SfxShell* pShell);

	class UpdateLock
	{
	public:
		UpdateLock (Implementation& rImpl) : mrImpl(rImpl) {mrImpl.LockUpdate();}
		~UpdateLock (void) {mrImpl.UnlockUpdate();};
	private:
		Implementation& mrImpl;
	};



	/** Prevent updates of the shell stack. While the sub shell manager is
		locked it will update its internal data structures but not alter the
		shell stack. Use this method when there are several modifications
		to the shell stack to prevent multiple rebuilds of the shell stack
		and resulting broadcasts.
	*/
	void LockUpdate (void);

	/** Allow updates of the shell stack. This method has to be called the
		same number of times as LockUpdate() to really allow a rebuild of
		the shell stack.
	*/
	void UnlockUpdate (void);

private:
	ViewShellBase& mrBase;
	mutable ::osl::Mutex maMutex;

	class ShellHash{public: size_t operator()(const SfxShell* p) const { return (size_t)p;} };
	typedef ::std::hash_multimap<const SfxShell*,SharedShellFactory,ShellHash>
		FactoryList;
	FactoryList maShellFactories;

	/** List of the active view shells. In order to create gather all shells
		to put on the shell stack each view shell in this list is asked for
		its sub-shells (typically toolbars).
	*/
	typedef ::std::list<ShellDescriptor> ActiveShellList;
	ActiveShellList maActiveViewShells;

	typedef ::std::list<ShellDescriptor> SubShellSubList;
	typedef ::std::hash_map<const SfxShell*,SubShellSubList,ShellHash> SubShellList;
	SubShellList maActiveSubShells;

	/** In this member we remember what shells we have pushed on the shell
		stack.
	*/
	typedef ::std::vector<SfxShell*> ShellStack;

	int mnUpdateLockCount;

	/** When this flag is set then the main view shell is always kept at the
		top of the shell stack.
	*/
	bool mbKeepMainViewShellOnTop;

	/** The UpdateShellStack() method can be called recursively. This flag
		is used to communicate between different levels of invocation: if
		the stack has been updated in an inner call the outer call can (has
		to) stop and return immediately.
	*/
	bool mbShellStackIsUpToDate;

	SfxShell* mpFormShell;
	const ViewShell* mpFormShellParent;
	bool mbFormShellAboveParent;

	SfxShell* mpTopShell;

	void GatherActiveShells (ShellStack& rShellList);

	void UpdateShellStack (void);

	void CreateShells (void);

	/** This method rebuilds the stack of shells that are stacked upon the
		view shell base.
	*/
	void CreateTargetStack (ShellStack& rStack) const;

	DECL_LINK(WindowEventHandler, VclWindowEvent*);

#ifdef VERBOSE
	void DumpShellStack (const ShellStack& rStack);
	void DumpSfxShellStack (void);
#endif

	/** To be called before a shell is taken from the SFX shell stack. This
		method deactivates an active text editing to avoid problems with
		undo managers.
		Afterwards the Deactivate() of the shell is called.
	*/
	void Deactivate (SfxShell* pShell);

	ShellDescriptor CreateSubShell (
		SfxShell* pShell,
		ShellId nShellId,
		::Window* pParentWindow,
		FrameView* pFrameView);
	void DestroyViewShell (ShellDescriptor& rDescriptor);
	void DestroySubShell (
		const SfxShell& rViewShell,
		const ShellDescriptor& rDescriptor);
};




//===== ViewShellManager ======================================================

ViewShellManager::ViewShellManager (ViewShellBase& rBase)
	: mpImpl(new Implementation(*this,rBase)),
	  mbValid(true)
{
}




ViewShellManager::~ViewShellManager (void)
{
}




void ViewShellManager::AddSubShellFactory (
	ViewShell* pViewShell,
	const SharedShellFactory& rpFactory)
{
	if (mbValid)
		mpImpl->AddShellFactory(pViewShell, rpFactory);
}




void ViewShellManager::RemoveSubShellFactory (
	ViewShell* pViewShell,
	const SharedShellFactory& rpFactory)
{
	if (mbValid)
		mpImpl->RemoveShellFactory(pViewShell, rpFactory);
}




void ViewShellManager::ActivateViewShell (ViewShell* pViewShell)
{
	if (mbValid)
		return mpImpl->ActivateViewShell(pViewShell);
}




void ViewShellManager::DeactivateViewShell (const ViewShell* pShell)
{
	if (mbValid && pShell!=NULL)
		mpImpl->DeactivateViewShell(*pShell);
}




void ViewShellManager::MoveSubShellToTop (
	const ViewShell& rParentShell,
	ShellId nId)
{
	if (mbValid)
		mpImpl->MoveSubShellToTop(rParentShell, nId);
}




void ViewShellManager::SetFormShell (
	const ViewShell* pParentShell,
	FmFormShell* pFormShell,
	bool bAbove)
{
	if (mbValid)
		mpImpl->SetFormShell(pParentShell,pFormShell,bAbove);
}




void ViewShellManager::ActivateSubShell (const ViewShell& rViewShell, ShellId nId)
{
	if (mbValid)
		mpImpl->ActivateSubShell(rViewShell,nId);
}




void ViewShellManager::DeactivateSubShell (const ViewShell& rViewShell, ShellId nId)
{
	if (mbValid)
		mpImpl->DeactivateSubShell(rViewShell,nId);
}




void ViewShellManager::InvalidateAllSubShells (ViewShell* pViewShell)
{
	if (mbValid)
		mpImpl->InvalidateAllSubShells(pViewShell);
}




void ViewShellManager::ActivateShell (SfxShell* pShell)
{
	if (mbValid && pShell!=NULL)
		mpImpl->ActivateShell(*pShell);
}




void ViewShellManager::DeactivateShell (const SfxShell* pShell)
{
	if (mbValid && pShell!=NULL)
		mpImpl->DeactivateShell(*pShell);
}




void ViewShellManager::MoveToTop (const ViewShell& rParentShell)
{
	if (mbValid)
		mpImpl->MoveToTop(rParentShell);
}




SfxShell* ViewShellManager::GetShell (ShellId nId) const
{
	if (mbValid)
		return mpImpl->GetShell(nId);
	else
		return NULL;
}




SfxShell* ViewShellManager::GetTopShell (void) const
{
	if (mbValid)
		return mpImpl->GetTopShell();
	else
		return NULL;
}




void ViewShellManager::Shutdown (void)
{
	if (mbValid)
	{
		mpImpl->Shutdown();
		mbValid = false;
	}
}



void ViewShellManager::LockUpdate (void)
{
	mpImpl->LockUpdate();
}




void ViewShellManager::UnlockUpdate (void)
{
	mpImpl->UnlockUpdate();
}




//===== ViewShellManager::Implementation ======================================

ViewShellManager::Implementation::Implementation (
	ViewShellManager& rManager,
	ViewShellBase& rBase)
	: mrBase(rBase),
	  maMutex(),
	  maShellFactories(),
	  maActiveViewShells(),
	  mnUpdateLockCount(0),
	  mbKeepMainViewShellOnTop(false),
	  mbShellStackIsUpToDate(true),
	  mpFormShell(NULL),
	  mpFormShellParent(NULL),
	  mbFormShellAboveParent(true),
	  mpTopShell(NULL)
{
	(void)rManager;
}




ViewShellManager::Implementation::~Implementation (void)
{
	Shutdown();
}




void ViewShellManager::Implementation::AddShellFactory (
	const SfxShell* pViewShell,
	const SharedShellFactory& rpFactory)
{
	bool bAlreadyAdded (false);

	// Check that the given factory has not already been added.
	::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
		maShellFactories.equal_range(pViewShell));
	for (FactoryList::const_iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory)
		if (iFactory->second == rpFactory)
		{
			bAlreadyAdded = true;
			break;
		}

	// Add the factory if it is not already present.
	if ( ! bAlreadyAdded)
		maShellFactories.insert(FactoryList::value_type(pViewShell, rpFactory));
}




void ViewShellManager::Implementation::RemoveShellFactory (
	const SfxShell* pViewShell,
	const SharedShellFactory& rpFactory)
{
	::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
		maShellFactories.equal_range(pViewShell));
	for (FactoryList::iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory)
		if (iFactory->second == rpFactory)
		{
			maShellFactories.erase(iFactory);
			break;
		}
}




void ViewShellManager::Implementation::ActivateViewShell (ViewShell* pViewShell)
{
	::osl::MutexGuard aGuard (maMutex);

	ShellDescriptor aResult;
	aResult.mpShell = pViewShell;

	// Register as window listener so that the shells of the current
	// window can be moved to the top of the shell stack.
	if (aResult.mpShell != NULL)
	{
		::Window* pWindow = aResult.GetWindow();
		if (pWindow != NULL)
		{
			pWindow->AddEventListener(
				LINK(this, ViewShellManager::Implementation, WindowEventHandler));
			aResult.mbIsListenerAddedToWindow = true;
		}
		else
		{
			DBG_ASSERT(false,
				"ViewShellManager::ActivateViewShell: "
				"new view shell has no active window");
		}
	}

	ActivateShell(aResult);
}




void ViewShellManager::Implementation::DeactivateViewShell (const ViewShell& rShell)
{
	::osl::MutexGuard aGuard (maMutex);

	ActiveShellList::iterator iShell (::std::find_if (
		maActiveViewShells.begin(),
		maActiveViewShells.end(),
		IsShell(&rShell)));
	if (iShell != maActiveViewShells.end())
	{
		UpdateLock aLocker (*this);

		ShellDescriptor aDescriptor(*iShell);
		mrBase.GetDocShell()->Disconnect(dynamic_cast<ViewShell*>(aDescriptor.mpShell));
		maActiveViewShells.erase(iShell);
		TakeShellsFromStack(aDescriptor.mpShell);

		// Deactivate sub shells.
		SubShellList::iterator iList (maActiveSubShells.find(&rShell));
		if (iList != maActiveSubShells.end())
		{
			SubShellSubList& rList (iList->second);
			while ( ! rList.empty())
				DeactivateSubShell(rShell, rList.front().mnId);
		}

		DestroyViewShell(aDescriptor);
	}
}




void ViewShellManager::Implementation::ActivateShell (SfxShell& rShell)
{
	::osl::MutexGuard aGuard (maMutex);

	// Create a new shell or recycle on in the cache.
	ShellDescriptor aDescriptor;
	aDescriptor.mpShell = &rShell;

	ActivateShell(aDescriptor);
}




void ViewShellManager::Implementation::ActivateShell (const ShellDescriptor& rDescriptor)
{
	// Put shell on top of the active view shells.
	if (rDescriptor.mpShell != NULL)
	{
		// Determine where to put the view shell on the stack. By default
		// it is put on top of the stack. When the view shell of the center
		// pane is to be kept top most and the new view shell is not
		// displayed in the center pane then it is inserted at the position
		// one below the top.
		ActiveShellList::iterator iInsertPosition (maActiveViewShells.begin());
		if (iInsertPosition != maActiveViewShells.end()
			&& mbKeepMainViewShellOnTop
			&& ! rDescriptor.IsMainViewShell()
			&& iInsertPosition->IsMainViewShell())
		{
			++iInsertPosition;
		}
		maActiveViewShells.insert(
			iInsertPosition,
			rDescriptor);
	}
}




void ViewShellManager::Implementation::DeactivateShell (const SfxShell& rShell)
{
	::osl::MutexGuard aGuard (maMutex);

	ActiveShellList::iterator iShell (::std::find_if (
		maActiveViewShells.begin(),
		maActiveViewShells.end(),
		IsShell(&rShell)));
	if (iShell != maActiveViewShells.end())
	{
		UpdateLock aLocker (*this);

		ShellDescriptor aDescriptor(*iShell);
		mrBase.GetDocShell()->Disconnect(dynamic_cast<ViewShell*>(aDescriptor.mpShell));
		maActiveViewShells.erase(iShell);
		TakeShellsFromStack(aDescriptor.mpShell);

		// Deactivate sub shells.
		SubShellList::iterator iList (maActiveSubShells.find(&rShell));
		if (iList != maActiveSubShells.end())
		{
			SubShellSubList& rList (iList->second);
			while ( ! rList.empty())
				DeactivateSubShell(rShell, rList.front().mnId);
		}

		DestroyViewShell(aDescriptor);
	}
}




void ViewShellManager::Implementation::ActivateSubShell (
	const SfxShell& rParentShell,
	ShellId nId)
{
	::osl::MutexGuard aGuard (maMutex);

	do
	{
		// Check that the given view shell is active.
		ActiveShellList::iterator iShell (::std::find_if (
			maActiveViewShells.begin(),
			maActiveViewShells.end(),
			IsShell(&rParentShell)));
		if (iShell == maActiveViewShells.end())
			break;

		// Create the sub shell list if it does not yet exist.
		SubShellList::iterator iList (maActiveSubShells.find(&rParentShell));
		if (iList == maActiveSubShells.end())
			iList = maActiveSubShells.insert(
				SubShellList::value_type(&rParentShell,SubShellSubList())).first;

		// Do not activate an object bar that is already active. Requesting
		// this is not exactly an error but may be an indication of one.
		SubShellSubList& rList (iList->second);
		if (::std::find_if(rList.begin(),rList.end(), IsId(nId)) != rList.end())
			break;

		// Add just the id of the sub shell. The actual shell is created
		// later in CreateShells().
		UpdateLock aLock (*this);
		rList.push_back(ShellDescriptor(NULL, nId));
	}
	while (false);
}




void ViewShellManager::Implementation::DeactivateSubShell (
	const SfxShell& rParentShell,
	ShellId nId)
{
	::osl::MutexGuard aGuard (maMutex);

	do
	{
		// Check that the given view shell is active.
		SubShellList::iterator iList (maActiveSubShells.find(&rParentShell));
		if (iList == maActiveSubShells.end())
			break;

		// Look up the sub shell.
		SubShellSubList& rList (iList->second);
		SubShellSubList::iterator iShell (
			::std::find_if(rList.begin(),rList.end(), IsId(nId)));
		if (iShell == rList.end())
			break;
		SfxShell* pShell = iShell->mpShell;
		if (pShell == NULL)
			break;

		UpdateLock aLock (*this);

		ShellDescriptor aDescriptor(*iShell);
		// Remove the sub shell from both the internal structure as well as the
		// SFX shell stack above and including the sub shell.
		rList.erase(iShell);
		TakeShellsFromStack(pShell);

		DestroySubShell(rParentShell, aDescriptor);
	}
	while (false);
}




void ViewShellManager::Implementation::MoveSubShellToTop (
	const SfxShell& rParentShell,
	ShellId nId)
{
	SubShellList::iterator iList (maActiveSubShells.find(&rParentShell));
	if (iList != maActiveSubShells.end())
	{
		// Look up the sub shell.
		SubShellSubList& rList (iList->second);
		SubShellSubList::iterator iShell (
			::std::find_if(rList.begin(),rList.end(), IsId(nId)));
		if (iShell!=rList.end() && iShell!=rList.begin())
		{
			SubShellSubList::value_type aEntry (*iShell);
			rList.erase(iShell);
			rList.push_front(aEntry);
		}
	}
	else
	{
		// Ignore this call when there are no sub shells for the given
		// parent shell. We could remember the sub shell to move to the top
		// but we do not. Do call this method at a later time instead.
	}
}



void ViewShellManager::Implementation::MoveToTop (const SfxShell& rShell)
{
	::osl::MutexGuard aGuard (maMutex);

	// Check that we have access to a dispatcher. If not, then we are
	// (probably) called while the view shell is still being created or
	// initialized. Without dispatcher we can not rebuild the shell stack
	// to move the requested shell to the top. So return right away instead
	// of making a mess without being able to clean up afterwards.
	if (mrBase.GetDispatcher() == NULL)
		return;

	ActiveShellList::iterator iShell (::std::find_if (
		maActiveViewShells.begin(),
		maActiveViewShells.end(),
		IsShell(&rShell)));
	bool bMove = true;
	if (iShell != maActiveViewShells.end())
	{
		// Is the shell already at the top of the stack? We have to keep
		// the case in mind that mbKeepMainViewShellOnTop is true. Shells
		// that are not the main view shell are placed on the second-to-top
		// position in this case.
			if (iShell == maActiveViewShells.begin()
			&& (iShell->IsMainViewShell() || ! mbKeepMainViewShellOnTop))
		{
			// The shell is at the top position and is either a) the main
			// view shell or b) another shell but the main view shell is not
			// kept at the top position. We do not have to move the shell.
			bMove = false;
		}
		else if (iShell == ++maActiveViewShells.begin()
			&& ! iShell->IsMainViewShell()
			&& mbKeepMainViewShellOnTop)
		{
			// The shell is a the second-to-top position, not the main view
			// shell and the main view shell is kept at the top position.
			// Therefore we do not have to move the shell.
			bMove = false;
		}
	}
	else
	{
		// The shell is not on the stack. Therefore it can not be moved.
		// We could insert it but we don't. Use ActivateViewShell() for
		// that.
		bMove = false;
	}

	// When the shell is not at the right position it is removed from the
	// internal list of shells and inserted at the correct position.
	if (bMove)
	{
		UpdateLock aLock (*this);

		ShellDescriptor aDescriptor(*iShell);

		TakeShellsFromStack(&rShell);
		maActiveViewShells.erase(iShell);

		// Find out whether to insert at the top or one below.
		ActiveShellList::iterator aInsertPosition (maActiveViewShells.begin());
		if (mbKeepMainViewShellOnTop && ! aDescriptor.IsMainViewShell())
		{
			if (maActiveViewShells.back().IsMainViewShell())
				aInsertPosition++;
		}

		maActiveViewShells.insert(aInsertPosition, aDescriptor);
	}
}




SfxShell* ViewShellManager::Implementation::GetShell (ShellId nId) const
{
	::osl::MutexGuard aGuard (maMutex);

	SfxShell* pShell = NULL;

	// First search the active view shells.
	ActiveShellList::const_iterator iShell (
		::std::find_if (
		maActiveViewShells.begin(),
		maActiveViewShells.end(),
		IsId(nId)));
	if (iShell != maActiveViewShells.end())
		pShell = iShell->mpShell;
	else
	{
		// Now search the active sub shells of every active view shell.
		SubShellList::const_iterator iList;
		for (iList=maActiveSubShells.begin(); iList!=maActiveSubShells.end(); ++iList)
		{
			const SubShellSubList& rList (iList->second);
			SubShellSubList::const_iterator iSubShell(
				::std::find_if(rList.begin(),rList.end(), IsId(nId)));
			if (iSubShell != rList.end())
			{
				pShell = iSubShell->mpShell;
				break;
			}
		}
	}

	return pShell;
}




SfxShell* ViewShellManager::Implementation::GetTopShell (void) const
{
	OSL_ASSERT(mpTopShell == mrBase.GetSubShell(0));
	return mpTopShell;
}




void ViewShellManager::Implementation::LockUpdate (void)
{
	mnUpdateLockCount++;
}




void ViewShellManager::Implementation::UnlockUpdate (void)
{
	::osl::MutexGuard aGuard (maMutex);

	mnUpdateLockCount--;
	if (mnUpdateLockCount < 0)
	{
		// This should not happen.
		OSL_ASSERT (mnUpdateLockCount>=0);
		mnUpdateLockCount = 0;
	}
	if (mnUpdateLockCount == 0)
		UpdateShellStack();
}




/** Update the SFX shell stack (the portion that is visible to us) so that
	it matches the internal shell stack. This is done in six steps:
	1. Create the missing view shells and sub shells.
	2. Set up the internal shell stack.
	3. Get the SFX shell stack.
	4. Find the lowest shell in which the two stacks differ.
	5. Remove all shells above and including that shell from the SFX stack.
	6. Push all shells of the internal stack on the SFX shell stack that are
	not already present on the later.
*/
void ViewShellManager::Implementation::UpdateShellStack (void)
{
	::osl::MutexGuard aGuard (maMutex);

	// Remember the undo manager from the top-most shell on the stack.
	SfxShell* pTopMostShell = mrBase.GetSubShell(0);
	::svl::IUndoManager* pUndoManager = (pTopMostShell!=NULL)
		? pTopMostShell->GetUndoManager()
		: NULL;

	// 1. Create the missing shells.
	CreateShells();


	// 2. Create the internal target stack.
	ShellStack aTargetStack;
	CreateTargetStack(aTargetStack);


	// 3. Get SFX shell stack.
	ShellStack aSfxShellStack;
	sal_uInt16 nIndex (0);
	while (mrBase.GetSubShell(nIndex)!=NULL)
		++nIndex;
	aSfxShellStack.reserve(nIndex);
	while (nIndex-- > 0)
		aSfxShellStack.push_back(mrBase.GetSubShell(nIndex));


#ifdef VERBOSE
	OSL_TRACE("Current SFX Stack\r");
	DumpShellStack(aSfxShellStack);
	OSL_TRACE("Target Stack\r");
	DumpShellStack(aTargetStack);
#endif


	// 4. Find the lowest shell in which the two stacks differ.
	ShellStack::const_iterator iSfxShell (aSfxShellStack.begin());
	ShellStack::iterator iTargetShell (aTargetStack.begin());
	while (iSfxShell != aSfxShellStack.end()
		&& iTargetShell!=aTargetStack.end()
		&& (*iSfxShell)==(*iTargetShell))
	{
		++iSfxShell;
		++iTargetShell;
	}


	// 5. Remove all shells above and including the differing shell from the
	// SFX stack starting with the shell on top of the stack.
	while (iSfxShell != aSfxShellStack.end())
	{
		SfxShell* pShell = aSfxShellStack.back();
		aSfxShellStack.pop_back();
#ifdef VERBOSE
		OSL_TRACE("removing shell %p from stack\r", pShell);
#endif
		mrBase.RemoveSubShell(pShell);
	}


	// 6. Push shells from the given stack onto the SFX stack.
	mbShellStackIsUpToDate = false;
	while (iTargetShell != aTargetStack.end())
	{
#ifdef VERBOSE
		OSL_TRACE("pushing shell %p on stack\r", *iTargetShell);
#endif
		mrBase.AddSubShell(**iTargetShell);
		++iTargetShell;

		// The pushing of the shell on to the shell stack may have lead to
		// another invocation of this method. In this case we have to abort
		// pushing shells on the stack and return immediately.
		if (mbShellStackIsUpToDate)
			break;
	}
	if (mrBase.GetDispatcher() != NULL)
		mrBase.GetDispatcher()->Flush();

	// Update the pointer to the top-most shell and set its undo manager
	// to the one of the previous top-most shell.
	mpTopShell = mrBase.GetSubShell(0);
	if (mpTopShell!=NULL && pUndoManager!=NULL && mpTopShell->GetUndoManager()==NULL)
		mpTopShell->SetUndoManager(pUndoManager);

	// Finally tell an invocation of this method on a higher level that it can (has
	// to) abort and return immediately.
	mbShellStackIsUpToDate = true;

#ifdef VERBOSE
	OSL_TRACE("New current stack\r");
	DumpSfxShellStack();
#endif
}




void ViewShellManager::Implementation::TakeShellsFromStack (const SfxShell* pShell)
{
	::osl::MutexGuard aGuard (maMutex);

	// Remember the undo manager from the top-most shell on the stack.
	SfxShell* pTopMostShell = mrBase.GetSubShell(0);
	::svl::IUndoManager* pUndoManager = (pTopMostShell!=NULL)
		? pTopMostShell->GetUndoManager()
		: NULL;

#ifdef VERBOSE
	OSL_TRACE("TakeShellsFromStack(%p)\r", pShell);
	DumpSfxShellStack();
#endif

	// 0.Make sure that the given shell is on the stack. This is a
	// preparation for the following assertion.
	for (sal_uInt16 nIndex=0; true; nIndex++)
	{
		SfxShell* pShellOnStack = mrBase.GetSubShell(nIndex);
		if (pShellOnStack == NULL)
		{
			// Set pShell to NULL to indicate the following code that the
			// shell is not on the stack.
			pShell = NULL;
			break;
		}
		else if (pShellOnStack == pShell)
			break;
	}

	if (pShell != NULL)
	{
		// 1. Deactivate our shells on the stack before they are removed so
		// that during the Deactivation() calls the stack is still intact.
		for (sal_uInt16 nIndex=0; true; nIndex++)
		{
			SfxShell* pShellOnStack = mrBase.GetSubShell(nIndex);
			Deactivate(pShellOnStack);
			if (pShellOnStack == pShell)
				break;
		}

		// 2. Remove the shells from the stack.
		while (true)
		{
			SfxShell* pShellOnStack = mrBase.GetSubShell(0);
#ifdef VERBOSE
			OSL_TRACE("removing shell %p from stack\r", pShellOnStack);
#endif
			mrBase.RemoveSubShell(pShellOnStack);
			if (pShellOnStack == pShell)
				break;
		}

		// 3. Update the stack.
		if (mrBase.GetDispatcher() != NULL)
			mrBase.GetDispatcher()->Flush();

		// Update the pointer to the top-most shell and set its undo manager
		// to the one of the previous top-most shell.
		mpTopShell = mrBase.GetSubShell(0);
		if (mpTopShell!=NULL && pUndoManager!=NULL && mpTopShell->GetUndoManager()==NULL)
			mpTopShell->SetUndoManager(pUndoManager);
	}

#ifdef VERBOSE
	OSL_TRACE("Sfx shell stack is:\r");
	DumpSfxShellStack();
#endif
}




void ViewShellManager::Implementation::CreateShells (void)
{
	::osl::MutexGuard aGuard (maMutex);

	// Iterate over all view shells.
	ShellStack aShellStack;
	ActiveShellList::reverse_iterator iShell;
	for (iShell=maActiveViewShells.rbegin(); iShell!=maActiveViewShells.rend(); ++iShell)
	{
		// Get the list of associated sub shells.
		SubShellList::iterator iList (maActiveSubShells.find(iShell->mpShell));
		if (iList != maActiveSubShells.end())
		{
			SubShellSubList& rList (iList->second);

			// Iterate over all sub shells of the current view shell.
			SubShellSubList::iterator iSubShell;
			for (iSubShell=rList.begin(); iSubShell!=rList.end(); ++iSubShell)
			{
				if (iSubShell->mpShell == NULL)
				{
					*iSubShell = CreateSubShell(iShell->mpShell,iSubShell->mnId,NULL,NULL);
				}
			}
		}
	}
}




void ViewShellManager::Implementation::CreateTargetStack (ShellStack& rStack) const
{
	// Create a local stack of the shells that are to push on the shell
	// stack. We can thus safely create the required shells while still
	// having a valid shell stack.
	for (ActiveShellList::const_reverse_iterator iViewShell (maActiveViewShells.rbegin());
		 iViewShell != maActiveViewShells.rend();
		 ++iViewShell)
	{
		// Possibly place the form shell below the current view shell.
		if ( ! mbFormShellAboveParent
			&& mpFormShell!=NULL
			&& iViewShell->mpShell==mpFormShellParent)
		{
			rStack.push_back(mpFormShell);
		}

		// Put the view shell itself on the local stack.
		rStack.push_back (iViewShell->mpShell);

		// Possibly place the form shell above the current view shell.
		if (mbFormShellAboveParent
			&& mpFormShell!=NULL
			&& iViewShell->mpShell==mpFormShellParent)
		{
			rStack.push_back(mpFormShell);
		}

		// Add all other sub shells.
		SubShellList::const_iterator iList (maActiveSubShells.find(iViewShell->mpShell));
		if (iList != maActiveSubShells.end())
		{
			const SubShellSubList& rList (iList->second);
			SubShellSubList::const_reverse_iterator iSubShell;
			for (iSubShell=rList.rbegin(); iSubShell!=rList.rend(); ++iSubShell)
				if (iSubShell->mpShell != mpFormShell)
					rStack.push_back(iSubShell->mpShell);
		}
	}
}




IMPL_LINK(ViewShellManager::Implementation, WindowEventHandler, VclWindowEvent*, pEvent)
{
	if (pEvent != NULL)
	{
		::Window* pEventWindow
			= static_cast<VclWindowEvent*>(pEvent)->GetWindow();

		switch (pEvent->GetId())
		{
			case VCLEVENT_WINDOW_GETFOCUS:
			{
				for (ActiveShellList::iterator aI(maActiveViewShells.begin());
					 aI!=maActiveViewShells.end();
					 aI++)
				{
					if (pEventWindow == static_cast< ::Window*>(aI->GetWindow()))
					{
						MoveToTop(*aI->mpShell);
						break;
					}
				}
			}
			break;

			case VCLEVENT_WINDOW_LOSEFOCUS:
				break;

			case VCLEVENT_OBJECT_DYING:
				// Remember that we do not have to remove the window
				// listener for this window.
				for (ActiveShellList::iterator
						iShell(maActiveViewShells.begin()),
						iEnd(maActiveViewShells.end());
					iShell!=iEnd;
					++iShell)
				{
					if (iShell->GetWindow() == pEventWindow)
					{
						iShell->mbIsListenerAddedToWindow = false;
						break;
					}
				}
				break;
		}
	}
	return sal_True;
}




ShellDescriptor ViewShellManager::Implementation::CreateSubShell (
	SfxShell* pParentShell,
	ShellId nShellId,
	::Window* pParentWindow,
	FrameView* pFrameView)
{
	::osl::MutexGuard aGuard (maMutex);
	ShellDescriptor aResult;

	// Look up the factories for the parent shell.
	::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
		maShellFactories.equal_range(pParentShell));

	// Try all factories to create the shell.
	for (FactoryList::const_iterator iFactory=aRange.first; iFactory!=aRange.second; ++iFactory)
	{
		SharedShellFactory pFactory = iFactory->second;
		if( bool(pFactory))
			aResult.mpShell = pFactory->CreateShell(nShellId, pParentWindow, pFrameView);

		// Exit the loop when the shell has been successfully created.
		if (aResult.mpShell != NULL)
		{
			aResult.mpFactory = pFactory;
			aResult.mnId = nShellId;
			break;
		}
	}

	return aResult;
}




void ViewShellManager::Implementation::DestroyViewShell (
	ShellDescriptor& rDescriptor)
{
	OSL_ASSERT(rDescriptor.mpShell != NULL);

	if (rDescriptor.mbIsListenerAddedToWindow)
	{
		rDescriptor.mbIsListenerAddedToWindow = false;
		::Window* pWindow = rDescriptor.GetWindow();
		if (pWindow != NULL)
		{
			pWindow->RemoveEventListener(
				LINK(this, ViewShellManager::Implementation, WindowEventHandler));
		}
	}

	// Destroy the sub shell factories.
	::std::pair<FactoryList::iterator,FactoryList::iterator> aRange(
		maShellFactories.equal_range(rDescriptor.mpShell));
	if (aRange.first != maShellFactories.end())
		maShellFactories.erase(aRange.first, aRange.second);

	// Release the shell.
	if (rDescriptor.mpFactory.get() != NULL)
		rDescriptor.mpFactory->ReleaseShell(rDescriptor.mpShell);
}




void ViewShellManager::Implementation::DestroySubShell (
	const SfxShell& rParentShell,
	const ShellDescriptor& rDescriptor)
{
	(void)rParentShell;
	OSL_ASSERT(rDescriptor.mpFactory.get() != NULL);
	rDescriptor.mpFactory->ReleaseShell(rDescriptor.mpShell);
}




void ViewShellManager::Implementation::InvalidateAllSubShells (const SfxShell* pParentShell)
{
	::osl::MutexGuard aGuard (maMutex);

	SubShellList::iterator iList (maActiveSubShells.find(pParentShell));
	if (iList != maActiveSubShells.end())
	{
		SubShellSubList& rList (iList->second);
		SubShellSubList::iterator iShell;
		for (iShell=rList.begin(); iShell!=rList.end(); ++iShell)
			if (iShell->mpShell != NULL)
				iShell->mpShell->Invalidate();
	}
}




void ViewShellManager::Implementation::Shutdown (void)
{
	::osl::MutexGuard aGuard (maMutex);

	// Take stacked shells from stack.
	if ( ! maActiveViewShells.empty())
	{
		UpdateLock aLock (*this);


		while ( ! maActiveViewShells.empty())
		{
			SfxShell* pShell = maActiveViewShells.front().mpShell;
			if (pShell != NULL)
			{
				ViewShell* pViewShell = dynamic_cast<ViewShell*>(pShell);
				if (pViewShell != NULL)
					DeactivateViewShell(*pViewShell);
				else
					DeactivateShell(*pShell);
			}
			else
			{
				DBG_ASSERT(false,
					"ViewShellManager::Implementation::Shutdown(): empty active shell descriptor");
				maActiveViewShells.pop_front();
			}
		}
	}
	mrBase.RemoveSubShell (NULL);

	maShellFactories.clear();
}




#ifdef VERBOSE
void ViewShellManager::Implementation::DumpShellStack (const ShellStack& rStack)
{
	ShellStack::const_reverse_iterator iEntry;
	for (iEntry=rStack.rbegin(); iEntry!=rStack.rend(); ++iEntry)
		if (*iEntry != NULL)
			OSL_TRACE ("    %p : %s\r",
				*iEntry,
				::rtl::OUStringToOString((*iEntry)->GetName(),RTL_TEXTENCODING_UTF8).getStr());
		else
			OSL_TRACE("     null\r");
}




void ViewShellManager::Implementation::DumpSfxShellStack (void)
{
	ShellStack aSfxShellStack;
	sal_uInt16 nIndex (0);
	while (mrBase.GetSubShell(nIndex)!=NULL)
		++nIndex;
	aSfxShellStack.reserve(nIndex);
	while (nIndex-- > 0)
		aSfxShellStack.push_back(mrBase.GetSubShell(nIndex));
	DumpShellStack(aSfxShellStack);
}
#endif



void ViewShellManager::Implementation::Deactivate (SfxShell* pShell)
{
	OSL_ASSERT(pShell!=NULL);

	// We have to end a text edit for view shells that are to be taken from
	// the shell stack.
	ViewShell* pViewShell = dynamic_cast<ViewShell*>(pShell);
	if (pViewShell != NULL)
	{
		sd::View* pView = pViewShell->GetView();
		if (pView!=NULL && pView->IsTextEdit())
		{
			pView->SdrEndTextEdit();
			pView->UnmarkAll();
			pViewShell->GetViewFrame()->GetDispatcher()->Execute(
				SID_OBJECT_SELECT,
				SFX_CALLMODE_ASYNCHRON);
		}
	}

	// Now we can deactivate the shell.
	pShell->Deactivate(sal_True);
}




void ViewShellManager::Implementation::SetFormShell (
	const ViewShell* pFormShellParent,
	FmFormShell* pFormShell,
	bool bFormShellAboveParent)
{
	::osl::MutexGuard aGuard (maMutex);

	mpFormShellParent = pFormShellParent;
	mpFormShell = pFormShell;
	mbFormShellAboveParent = bFormShellAboveParent;
}




namespace {

ShellDescriptor::ShellDescriptor (void)
	: mpShell(NULL),
	  mnId(0),
	  mpFactory(),
	  mbIsListenerAddedToWindow(false)
{
}




ShellDescriptor::ShellDescriptor (
	SfxShell* pShell,
	ShellId nId)
	: mpShell(pShell),
	  mnId(nId),
	  mpFactory(),
	  mbIsListenerAddedToWindow(false)
{
}




ShellDescriptor::ShellDescriptor (const ShellDescriptor& rDescriptor)
	: mpShell(rDescriptor.mpShell),
	  mnId(rDescriptor.mnId),
	  mpFactory(rDescriptor.mpFactory),
	  mbIsListenerAddedToWindow(rDescriptor.mbIsListenerAddedToWindow)
{
}




ShellDescriptor& ShellDescriptor::operator= (const ShellDescriptor& rDescriptor)
{
	if (this != &rDescriptor)
	{
		mpShell = rDescriptor.mpShell;
		mnId = rDescriptor.mnId;
		mpFactory = rDescriptor.mpFactory;
		mbIsListenerAddedToWindow = rDescriptor.mbIsListenerAddedToWindow;
	}
	return *this;
}




bool ShellDescriptor::IsMainViewShell (void) const
{
	ViewShell* pViewShell = dynamic_cast<ViewShell*>(mpShell);
	if (pViewShell != NULL)
		return pViewShell->IsMainViewShell();
	else
		return false;
}




::Window* ShellDescriptor::GetWindow (void) const
{
	ViewShell* pViewShell = dynamic_cast<ViewShell*>(mpShell);
	if (pViewShell != NULL)
		return pViewShell->GetActiveWindow();
	else
		return NULL;
}



} // end of anonymous namespace

} // end of namespace sd
