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

#include "sdpage.hxx"
#include "drawdoc.hxx"
#include "sdresid.hxx"
#include "glob.hrc"
#include "app.hrc"
#include "strings.hrc"
#include "strings.hrc"
#include "helpids.h"
#include "sdattr.hxx"
#include "sdabstdlg.hxx"
#include "unmodpg.hxx"
#include "Window.hxx"
#include "optsitem.hxx"
#include "DrawDocShell.hxx"
#include "DrawController.hxx"
#include "FactoryIds.hxx"
#include "slideshow.hxx"
#include "ViewShellBase.hxx"
#include "FrameView.hxx"
#include "DrawViewShell.hxx"
#include "ViewShellHint.hxx"
#include "SidebarPanelId.hxx"
#include "framework/FrameworkHelper.hxx"

#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/request.hxx>
#include <sfx2/sidebar/Sidebar.hxx>
#include <svl/aeitem.hxx>
#include <svx/imapdlg.hxx>
#include <vcl/msgbox.hxx>
#include <basic/sbstar.hxx>
#include "undo/undoobjects.hxx"

#include <com/sun/star/drawing/framework/XControllerManager.hpp>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::drawing::framework;
using ::sd::framework::FrameworkHelper;

namespace sd {

ViewShell::Implementation::Implementation (ViewShell& rViewShell)
	: mbIsShowingUIControls(false),
	  mbIsMainViewShell(false),
	  mbIsInitialized(false),
	  mbArrangeActive(false),
	  mpSubShellFactory(),
	  mpUpdateLockForMouse(),
	  mrViewShell(rViewShell)
{
}




ViewShell::Implementation::~Implementation (void)
{
	if ( ! mpUpdateLockForMouse.expired())
	{
		::boost::shared_ptr<ToolBarManagerLock> pLock(mpUpdateLockForMouse);
		if (pLock.get() != NULL)
		{
			// Force the ToolBarManagerLock to be released even when the
			// IsUICaptured() returns <TRUE/>.
			pLock->Release(true);
		}
	}
}




void ViewShell::Implementation::ProcessModifyPageSlot (
	SfxRequest& rRequest,
	SdPage* pCurrentPage,
	PageKind ePageKind)
{
	SdDrawDocument* pDocument = mrViewShell.GetDoc();
	SdrLayerAdmin& rLayerAdmin = pDocument->GetLayerAdmin();
	sal_uInt8 aBckgrnd = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False);
	sal_uInt8 aBckgrndObj = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False);
	SetOfByte aVisibleLayers;
	sal_Bool bHandoutMode = sal_False;
	SdPage* pHandoutMPage = NULL;
	String aNewName;

	// #95981#
	String aOldName;

	AutoLayout aNewAutoLayout;

	sal_Bool bBVisible;
	sal_Bool bBObjsVisible;
	const SfxItemSet* pArgs = rRequest.GetArgs();

	if (pCurrentPage != NULL && pCurrentPage->TRG_HasMasterPage())
		aVisibleLayers = pCurrentPage->TRG_GetMasterPageVisibleLayers();
	else
		aVisibleLayers.SetAll();

	do
	{
		if (pCurrentPage == NULL)
			break;

		if (!pArgs || pArgs->Count() == 1 || pArgs->Count() == 2 )
		{
			if (pArgs && pArgs->Count() == 2)
			{
				// We have been called with a request that contains two
				// arguments. One was used as preselected layout in a
				// dialog. We could select that layout in the
				// layout panel instead.
				/*
					SFX_REQUEST_ARG (rRequest, pNewAutoLayout, SfxUInt32Item, ID_VAL_WHATLAYOUT, sal_False);
					eNewAutoLayout = (AutoLayout) pNewAutoLayout->GetValue
					();
				*/
			}

			// Make the layout menu visible in the tool pane.
			sfx2::sidebar::Sidebar::ShowPanel(
				rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ImpressLayoutsPanel")),
				mrViewShell.GetViewFrame()->GetFrame().GetFrameInterface());
			break;
		}
		else if (pArgs->Count() == 4)
		{
			SFX_REQUEST_ARG (rRequest, pNewName, SfxStringItem, ID_VAL_PAGENAME, sal_False);
			SFX_REQUEST_ARG (rRequest, pNewAutoLayout, SfxUInt32Item, ID_VAL_WHATLAYOUT, sal_False);
			SFX_REQUEST_ARG (rRequest, pBVisible, SfxBoolItem, ID_VAL_ISPAGEBACK, sal_False);
			SFX_REQUEST_ARG (rRequest, pBObjsVisible, SfxBoolItem, ID_VAL_ISPAGEOBJ, sal_False);
			AutoLayout aLayout ((AutoLayout)pNewAutoLayout->GetValue ());
			if (aLayout >= AUTOLAYOUT__START
				&& aLayout < AUTOLAYOUT__END)
			{
				aNewName		= pNewName->GetValue ();
				aNewAutoLayout	= (AutoLayout) pNewAutoLayout->GetValue ();
				bBVisible		= pBVisible->GetValue ();
				bBObjsVisible	= pBObjsVisible->GetValue ();
			}
			else
			{
				StarBASIC::FatalError (SbERR_BAD_PROP_VALUE);
				rRequest.Ignore ();
				break;
			}
			if (ePageKind == PK_HANDOUT)
			{
				bHandoutMode = sal_True;
				pHandoutMPage = pDocument->GetMasterSdPage(0, PK_HANDOUT);
			}
		}
		else
		{
			StarBASIC::FatalError (SbERR_WRONG_ARGS);
			rRequest.Ignore ();
			break;
		}

		SdPage* pUndoPage =
			bHandoutMode ? pHandoutMPage : pCurrentPage;

		::svl::IUndoManager* pUndoManager = mrViewShell.GetDocSh()->GetUndoManager();
		DBG_ASSERT(pUndoManager, "No UNDO MANAGER ?!?");

		if( pUndoManager )
		{
			String aComment( SdResId(STR_UNDO_MODIFY_PAGE) );
			pUndoManager->EnterListAction(aComment, aComment);
			ModifyPageUndoAction* pAction = new ModifyPageUndoAction(
				pDocument, pUndoPage, aNewName, aNewAutoLayout, bBVisible, bBObjsVisible);
			pUndoManager->AddUndoAction(pAction);

			// Clear the selection because the selected object may be removed as
			// a result of the assignment of the layout.
			mrViewShell.GetDrawView()->UnmarkAll();

			if (!bHandoutMode)
			{
				if (pCurrentPage->GetName() != aNewName)
				{
					pCurrentPage->SetName(aNewName);

					if (ePageKind == PK_STANDARD)
					{
						sal_uInt16 nPage = (pCurrentPage->GetPageNum()-1) / 2;
						SdPage* pNotesPage = pDocument->GetSdPage(nPage, PK_NOTES);
						if (pNotesPage != NULL)
							pNotesPage->SetName(aNewName);
					}
				}

				pCurrentPage->SetAutoLayout(aNewAutoLayout, sal_True);

				aBckgrnd = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False);
				aBckgrndObj = rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False);
				aVisibleLayers.Set(aBckgrnd, bBVisible);
				aVisibleLayers.Set(aBckgrndObj, bBObjsVisible);
				pCurrentPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers);
			}
			else
			{
				pHandoutMPage->SetAutoLayout(aNewAutoLayout, sal_True);
			}

			mrViewShell.GetViewFrame()->GetDispatcher()->Execute(SID_SWITCHPAGE,
				SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD);

			sal_Bool bSetModified = sal_True;

			if (pArgs && pArgs->Count() == 1)
			{
				bSetModified = (sal_Bool) ((SfxBoolItem&) pArgs->Get(SID_MODIFYPAGE)).GetValue();
			}

			pUndoManager->AddUndoAction( new UndoAutoLayoutPosAndSize( *pUndoPage ) );
			pUndoManager->LeaveListAction();

			pDocument->SetChanged(bSetModified);
		}
	}
	while (false);

	mrViewShell.Cancel();
	rRequest.Done ();
}

void ViewShell::Implementation::AssignLayout ( SfxRequest& rRequest, PageKind ePageKind )
{
	const SfxUInt32Item* pWhatPage = static_cast< const SfxUInt32Item* > ( rRequest.GetArg( ID_VAL_WHATPAGE, sal_False, TYPE(SfxUInt32Item) ) );
	const SfxUInt32Item* pWhatLayout = static_cast< const SfxUInt32Item* > ( rRequest.GetArg( ID_VAL_WHATLAYOUT, sal_False, TYPE(SfxUInt32Item) ) );

	SdDrawDocument* pDocument = mrViewShell.GetDoc();
	if( !pDocument )
		return;

	SdPage* pPage = 0;
	if( pWhatPage )
	{
		pPage = pDocument->GetSdPage(static_cast<sal_uInt16>(pWhatPage->GetValue()), ePageKind);
	}

	if( pPage == 0 )
		pPage = mrViewShell.getCurrentPage();

	if( pPage )
	{
		AutoLayout eLayout = pPage->GetAutoLayout();

		if( pWhatLayout )
			eLayout = static_cast< AutoLayout >( pWhatLayout->GetValue() );

		// Transform the given request into the four argument form that is
		// understood by ProcessModifyPageSlot().
		SdrLayerAdmin& rLayerAdmin (mrViewShell.GetViewShellBase().GetDocument()->GetLayerAdmin());
		sal_uInt8 aBackground (rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRND)), sal_False));
		sal_uInt8 aBackgroundObject (rLayerAdmin.GetLayerID(String(SdResId(STR_LAYER_BCKGRNDOBJ)), sal_False));

		SetOfByte aVisibleLayers;

		if( pPage->GetPageKind() == PK_HANDOUT )
			aVisibleLayers.SetAll();
		else
			aVisibleLayers = pPage->TRG_GetMasterPageVisibleLayers();

		SfxRequest aRequest (mrViewShell.GetViewShellBase().GetViewFrame(), SID_MODIFYPAGE);
		aRequest.AppendItem(SfxStringItem (ID_VAL_PAGENAME, pPage->GetName()));
		aRequest.AppendItem(SfxUInt32Item (ID_VAL_WHATLAYOUT, eLayout));
		aRequest.AppendItem(SfxBoolItem(ID_VAL_ISPAGEBACK, aVisibleLayers.IsSet(aBackground)));
		aRequest.AppendItem(SfxBoolItem(ID_VAL_ISPAGEOBJ, aVisibleLayers.IsSet(aBackgroundObject)));

		// Forward the call with the new arguments.
		ProcessModifyPageSlot( aRequest, pPage, pPage->GetPageKind());
	}
}




sal_uInt16 ViewShell::Implementation::GetViewId (void)
{
	switch (mrViewShell.GetShellType())
	{
		case ViewShell::ST_IMPRESS:
		case ViewShell::ST_NOTES:
		case ViewShell::ST_HANDOUT:
			return IMPRESS_FACTORY_ID;

		case ViewShell::ST_DRAW:
			return DRAW_FACTORY_ID;

		case ViewShell::ST_OUTLINE:
			return OUTLINE_FACTORY_ID;

		case ViewShell::ST_SLIDE_SORTER:
			return SLIDE_SORTER_FACTORY_ID;

		case ViewShell::ST_PRESENTATION:
			return PRESENTATION_FACTORY_ID;

		// Since we have to return a view id for every possible shell type
		// and there is not (yet) a proper ViewShellBase sub class for the
		// remaining types we chose the Impress factory as a fall back.
		case ViewShell::ST_SIDEBAR:
		case ViewShell::ST_NONE:
		default:
			return IMPRESS_FACTORY_ID;
	}
}




SvxIMapDlg* ViewShell::Implementation::GetImageMapDialog (void)
{
	SvxIMapDlg* pDialog = NULL;
	SfxChildWindow* pChildWindow = SfxViewFrame::Current()->GetChildWindow(
		SvxIMapDlgChildWindow::GetChildWindowId());
	if (pChildWindow != NULL)
		pDialog = dynamic_cast<SvxIMapDlg*>(pChildWindow->GetWindow());
	return pDialog;
}



//===== ToolBarManagerLock ====================================================

class ViewShell::Implementation::ToolBarManagerLock::Deleter { public:
	void operator() (ToolBarManagerLock* pObject) { delete pObject; }
};

::boost::shared_ptr<ViewShell::Implementation::ToolBarManagerLock>
	ViewShell::Implementation::ToolBarManagerLock::Create (
		const ::boost::shared_ptr<ToolBarManager>& rpManager)
{
	::boost::shared_ptr<ToolBarManagerLock> pLock (
		new ViewShell::Implementation::ToolBarManagerLock(rpManager),
		ViewShell::Implementation::ToolBarManagerLock::Deleter());
	pLock->mpSelf = pLock;
	return pLock;
}




ViewShell::Implementation::ToolBarManagerLock::ToolBarManagerLock (
	const ::boost::shared_ptr<ToolBarManager>& rpManager)
	: mpLock(new ToolBarManager::UpdateLock(rpManager)),
	  maTimer()
{
	// Start a timer that will unlock the ToolBarManager update lock when
	// that is not done explicitly by calling Release().
	maTimer.SetTimeoutHdl(LINK(this,ToolBarManagerLock,TimeoutCallback));
	maTimer.SetTimeout(100);
	maTimer.Start();
}




IMPL_LINK(ViewShell::Implementation::ToolBarManagerLock,TimeoutCallback,Timer*,EMPTYARG)
{
	// If possible then release the lock now. Otherwise start the timer
	// and try again later.
	if (Application::IsUICaptured())
	{
		maTimer.Start();
	}
	else
	{
		mpSelf.reset();
	}
	return 0;
}




void ViewShell::Implementation::ToolBarManagerLock::Release (bool bForce)
{
	// If possible then release the lock now. Otherwise try again when the
	// timer expires.
	if (bForce || ! Application::IsUICaptured())
	{
		mpSelf.reset();
	}
}




ViewShell::Implementation::ToolBarManagerLock::~ToolBarManagerLock (void)
{
	mpLock.reset();
}

} // end of namespace sd
