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



// INCLUDE ---------------------------------------------------------------

#include <svx/svdmark.hxx>
#include <svx/svdoole2.hxx>
#include <svx/svdview.hxx>
#include <sfx2/app.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/request.hxx>
#include <basic/sbxcore.hxx>
#include <svl/whiter.hxx>
#include <vcl/msgbox.hxx>

#include "tabvwsh.hxx"
#include "client.hxx"
#include "document.hxx"
#include "docsh.hxx"
#include "sc.hrc"
#include "drwlayer.hxx"		// GetVisibleName
#include "retypepassdlg.hxx"
#include "tabprotection.hxx"

#include <memory>

using namespace com::sun::star;

//------------------------------------------------------------------

void ScTabViewShell::ExecuteSbx( SfxRequest& /* rReq */ )
{
	//	SID_RANGE_OFFSET (Offset),
	//	SID_PIVOT_CREATE (DataPilotCreate) - removed (old Basic)
}

void ScTabViewShell::GetSbxState( SfxItemSet& /* rSet */ )
{
	//	SID_RANGE_REGION (CurrentRegion) - removed (old Basic)
}

//------------------------------------------------------------------

void ScTabViewShell::ExecuteObject( SfxRequest& rReq )
{
	sal_uInt16 nSlotId = rReq.GetSlot();
	const SfxItemSet* pReqArgs = rReq.GetArgs();

		//	Objekte aktivieren/deaktivieren immer auf der sichtbaren View

	ScTabViewShell* pVisibleSh = this;
	if ( nSlotId == SID_OLE_SELECT || nSlotId == SID_OLE_ACTIVATE || nSlotId == SID_OLE_DEACTIVATE )
	{
		DBG_ERROR("old slot SID_OLE...");
	}

	switch (nSlotId)
	{
		case SID_OLE_SELECT:
		case SID_OLE_ACTIVATE:
			{
				//	in beiden Faellen erstmal auf der sichtbaren View selektieren

				String aName;
				SdrView* pDrView = GetSdrView();
				if (pDrView)
				{
					const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
					if (rMarkList.GetMarkCount() == 1)
						aName = ScDrawLayer::GetVisibleName( rMarkList.GetMark(0)->GetMarkedSdrObj() );
				}
				pVisibleSh->SelectObject( aName );

				//	aktivieren

				if ( nSlotId == SID_OLE_ACTIVATE )
					pVisibleSh->DoVerb( 0 );
			}
			break;
		case SID_OLE_DEACTIVATE:
            pVisibleSh->DeactivateOle();
			break;

		case SID_OBJECT_LEFT:
		case SID_OBJECT_TOP:
		case SID_OBJECT_WIDTH:
		case SID_OBJECT_HEIGHT:
			{
				sal_Bool bDone = sal_False;
				const SfxPoolItem* pItem;
				if ( pReqArgs && pReqArgs->GetItemState( nSlotId, sal_True, &pItem ) == SFX_ITEM_SET )
				{
					long nNewVal = ((const SfxInt32Item*)pItem)->GetValue();
					if ( nNewVal < 0 )
						nNewVal = 0;

					//!	von irgendwas in 1/100mm umrechnen ??????

					SdrView* pDrView = GetSdrView();
					if ( pDrView )
					{
						const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
						if (rMarkList.GetMarkCount() == 1)
						{
							SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
							Rectangle aRect = pObj->GetLogicRect();

							if ( nSlotId == SID_OBJECT_LEFT )
								pDrView->MoveMarkedObj( Size( nNewVal - aRect.Left(), 0 ) );
							else if ( nSlotId == SID_OBJECT_TOP )
								pDrView->MoveMarkedObj( Size( 0, nNewVal - aRect.Top() ) );
							else if ( nSlotId == SID_OBJECT_WIDTH )
								pDrView->ResizeMarkedObj( aRect.TopLeft(),
												Fraction( nNewVal, aRect.GetWidth() ),
												Fraction( 1, 1 ) );
							else // if ( nSlotId == SID_OBJECT_HEIGHT )
								pDrView->ResizeMarkedObj( aRect.TopLeft(),
												Fraction( 1, 1 ),
												Fraction( nNewVal, aRect.GetHeight() ) );
							bDone = sal_True;
						}
					}
				}
				if (!bDone)
					SbxBase::SetError( SbxERR_BAD_PARAMETER );	// Basic-Fehler
			}
			break;

	}
}

uno::Reference < embed::XEmbeddedObject > lcl_GetSelectedObj( SdrView* pDrView )       //! Member von ScDrawView?
{
    uno::Reference < embed::XEmbeddedObject > xRet;
	if (pDrView)
	{
		const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
		if (rMarkList.GetMarkCount() == 1)
		{
			SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
			if (pObj->GetObjIdentifier() == OBJ_OLE2)
			{
				SdrOle2Obj* pOle2Obj = (SdrOle2Obj*) pObj;
				xRet = pOle2Obj->GetObjRef();
			}
		}
	}

	return xRet;
}

void ScTabViewShell::GetObjectState( SfxItemSet& rSet )
{
	//	SID_OLE_OBJECT - removed (old Basic)

	SfxWhichIter aIter(rSet);
	sal_uInt16 nWhich = aIter.FirstWhich();
	while ( nWhich )
	{
		switch (nWhich)
		{
			case SID_ACTIVE_OBJ_NAME:
				{
					String aName;
                    uno::Reference < embed::XEmbeddedObject > xOLE = lcl_GetSelectedObj( GetSdrView() );
                    if (xOLE.is())
					{
                        aName = GetViewData()->GetSfxDocShell()->GetEmbeddedObjectContainer().GetEmbeddedObjectName( xOLE );
					}
					rSet.Put( SfxStringItem( nWhich, aName ) );
				}
				break;
			case SID_OBJECT_LEFT:
			case SID_OBJECT_TOP:
			case SID_OBJECT_WIDTH:
			case SID_OBJECT_HEIGHT:
				{
					SdrView* pDrView = GetSdrView();
					if ( pDrView )
					{
						const SdrMarkList& rMarkList = pDrView->GetMarkedObjectList();
						if (rMarkList.GetMarkCount() == 1)
						{
							SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
							Rectangle aRect = pObj->GetLogicRect();

							long nVal;
							if ( nWhich == SID_OBJECT_LEFT )
								nVal = aRect.Left();
							else if ( nWhich == SID_OBJECT_TOP )
								nVal = aRect.Top();
							else if ( nWhich == SID_OBJECT_WIDTH )
								nVal = aRect.GetWidth();
							else // if ( nWhich == SID_OBJECT_HEIGHT )
								nVal = aRect.GetHeight();

							//!	von 1/100mm in irgendwas umrechnen ??????

							rSet.Put( SfxInt32Item( nWhich, nVal ) );
						}
					}
				}
				break;
		}
		nWhich = aIter.NextWhich();
	}
}

void ScTabViewShell::AddAccessibilityObject( SfxListener& rObject )
{
	if (!pAccessibilityBroadcaster)
		pAccessibilityBroadcaster = new SfxBroadcaster;

	rObject.StartListening( *pAccessibilityBroadcaster );
	ScDocument* pDoc = GetViewData()->GetDocument();
	if (pDoc)
		pDoc->AddUnoObject(rObject);
}

void ScTabViewShell::RemoveAccessibilityObject( SfxListener& rObject )
{
	if (pAccessibilityBroadcaster)
	{
		rObject.EndListening( *pAccessibilityBroadcaster );
		ScDocument* pDoc = GetViewData()->GetDocument();
		if (pDoc)
			pDoc->RemoveUnoObject(rObject);
	}
	else
	{
		DBG_ERROR("kein Accessibility-Broadcaster?");
	}
}

void ScTabViewShell::BroadcastAccessibility( const SfxHint &rHint )
{
	if (pAccessibilityBroadcaster)
		pAccessibilityBroadcaster->Broadcast( rHint );
}

sal_Bool ScTabViewShell::HasAccessibilityObjects()
{
	return pAccessibilityBroadcaster != NULL;
}

bool ScTabViewShell::ExecuteRetypePassDlg(ScPasswordHash eDesiredHash)
{
    using ::std::auto_ptr;

    ScDocument* pDoc = GetViewData()->GetDocument();

    auto_ptr<ScRetypePassDlg> pDlg(new ScRetypePassDlg(GetDialogParent()));
    pDlg->SetDataFromDocument(*pDoc);
    pDlg->SetDesiredHash(eDesiredHash);
    if (pDlg->Execute() != RET_OK)
        return false;

    pDlg->WriteNewDataToDocument(*pDoc);
    return true;
}