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

#include <dragmt3d.hxx>
#include <tools/shl.hxx>
#include <svx/svdpagv.hxx>
#include <svx/dialmgr.hxx>
#include <svx/svddrgmt.hxx>
#include <svx/svdtrans.hxx>
#include <svx/obj3d.hxx>
#include <svx/polysc3d.hxx>
#include <svx/e3dundo.hxx>
#include <svx/dialogs.hrc>
#include <svx/sdr/overlay/overlaypolypolygon.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <svx/sdr/contact/viewcontactofe3dscene.hxx>
#include <drawinglayer/geometry/viewinformation3d.hxx>
#include <svx/e3dsceneupdater.hxx>

TYPEINIT1(E3dDragMethod, SdrDragMethod);

/*************************************************************************
|*
|* Konstruktor aller 3D-DragMethoden
|*
\************************************************************************/

E3dDragMethod::E3dDragMethod (
	SdrDragView &_rView,
	const SdrMarkList& rMark,
	E3dDragConstraint eConstr,
	sal_Bool bFull)
:	SdrDragMethod(_rView),
	meConstraint(eConstr),
	mbMoveFull(bFull),
	mbMovedAtAll(sal_False)
{
	// Fuer alle in der selektion befindlichen 3D-Objekte
	// eine Unit anlegen
	const long nCnt(rMark.GetMarkCount());
	static bool bDoInvalidate(false);
	long nObjs(0);

	if(mbMoveFull)
	{
		// for non-visible 3D objects fallback to wireframe interaction
		bool bInvisibleObjects(false);

		for(nObjs = 0;!bInvisibleObjects && nObjs < nCnt;nObjs++)
		{
			E3dObject* pE3dObj = dynamic_cast< E3dObject* >(rMark.GetMark(nObjs)->GetMarkedSdrObj());

			if(pE3dObj)
			{
				if(!pE3dObj->HasFillStyle() && !pE3dObj->HasLineStyle())
				{
					bInvisibleObjects = true;
				}
			}
		}

		if(bInvisibleObjects)
		{
			mbMoveFull = false;
		}
	}

	for(nObjs = 0;nObjs < nCnt;nObjs++)
	{
		E3dObject* pE3dObj = dynamic_cast< E3dObject* >(rMark.GetMark(nObjs)->GetMarkedSdrObj());

		if(pE3dObj)
		{
			// fill new interaction unit
			E3dDragMethodUnit aNewUnit;
			aNewUnit.mp3DObj = pE3dObj;

			// get transformations
			aNewUnit.maInitTransform = aNewUnit.maTransform = pE3dObj->GetTransform();

			if(pE3dObj->GetParentObj())
			{
				// get transform between object and world, normally scene transform
				aNewUnit.maInvDisplayTransform = aNewUnit.maDisplayTransform = pE3dObj->GetParentObj()->GetFullTransform();
				aNewUnit.maInvDisplayTransform.invert();
			}

			// SnapRects der beteiligten Objekte invalidieren, um eine
			// Neuberechnung beim Setzen der Marker zu erzwingen
			if(bDoInvalidate)
			{
				pE3dObj->SetRectsDirty();
			}

			if(!mbMoveFull)
			{
				// create wireframe visualisation for parent coordinate system
				aNewUnit.maWireframePoly.clear();
				aNewUnit.maWireframePoly = pE3dObj->CreateWireframe();
				aNewUnit.maWireframePoly.transform(aNewUnit.maTransform);
			}

			// FullBound ermitteln
			maFullBound.Union(pE3dObj->GetSnapRect());

			// Unit einfuegen
			maGrp.push_back(aNewUnit);
		}
	}
}

/*************************************************************************
|*
\************************************************************************/

void E3dDragMethod::TakeSdrDragComment(XubString& /*rStr*/) const
{
}

/*************************************************************************
|*
|* Erstelle das Drahtgittermodel fuer alle Aktionen
|*
\************************************************************************/

bool E3dDragMethod::BeginSdrDrag()
{
	if(E3DDRAG_CONSTR_Z == meConstraint)
	{
		const sal_uInt32 nCnt(maGrp.size());
		DragStat().Ref1() = maFullBound.Center();

		for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
		{
			E3dDragMethodUnit& rCandidate = maGrp[nOb];
			rCandidate.mnStartAngle = GetAngle(DragStat().GetStart() - DragStat().GetRef1());
			rCandidate.mnLastAngle = 0;
		}
	}
	else
	{
		maLastPos = DragStat().GetStart();
	}

	if(!mbMoveFull)
	{
		Show();
	}

	return sal_True;
}

/*************************************************************************
|*
|* Schluss
|*
\************************************************************************/

bool E3dDragMethod::EndSdrDrag(bool /*bCopy*/)
{
	const sal_uInt32 nCnt(maGrp.size());

	if(!mbMoveFull)
	{
		// WireFrame ausblenden
		Hide();
	}

	// Alle Transformationen anwenden und UnDo's anlegen
	if(mbMovedAtAll)
	{
		const bool bUndo = getSdrDragView().IsUndoEnabled();
		if( bUndo )
			getSdrDragView().BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_ROTATE));
		sal_uInt32 nOb(0);

		for(nOb=0;nOb<nCnt;nOb++)
		{
			E3dDragMethodUnit& rCandidate = maGrp[nOb];
			E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
			rCandidate.mp3DObj->SetTransform(rCandidate.maTransform);
			if( bUndo )
			{
				getSdrDragView().AddUndo(new E3dRotateUndoAction(rCandidate.mp3DObj->GetModel(),
					rCandidate.mp3DObj, rCandidate.maInitTransform,
					rCandidate.maTransform));
			}
		}
		if( bUndo )
			getSdrDragView().EndUndo();
	}

	return sal_True;
}

/*************************************************************************
|*
|* Abbruch
|*
\************************************************************************/

void E3dDragMethod::CancelSdrDrag()
{
	if(mbMoveFull)
	{
		if(mbMovedAtAll)
		{
			const sal_uInt32 nCnt(maGrp.size());

			for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
			{
				// Transformation restaurieren
				E3dDragMethodUnit& rCandidate = maGrp[nOb];
    			E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
				rCandidate.mp3DObj->SetTransform(rCandidate.maInitTransform);
			}
		}
	}
	else
	{
		// WireFrame ausblenden
		Hide();
	}
}

/*************************************************************************
|*
|* Gemeinsames MoveSdrDrag()
|*
\************************************************************************/

void E3dDragMethod::MoveSdrDrag(const Point& /*rPnt*/)
{
	mbMovedAtAll = true;
}

/*************************************************************************
|*
|* Zeichne das Drahtgittermodel
|*
\************************************************************************/

// for migration from XOR to overlay
void E3dDragMethod::CreateOverlayGeometry(::sdr::overlay::OverlayManager& rOverlayManager)
{
	const sal_uInt32 nCnt(maGrp.size());
	basegfx::B2DPolyPolygon aResult;

	for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
	{
		E3dDragMethodUnit& rCandidate = maGrp[nOb];
		SdrPageView* pPV = getSdrDragView().GetSdrPageView();

		if(pPV && pPV->HasMarkedObjPageView())
		{
			const basegfx::B3DPolyPolygon aCandidate(rCandidate.maWireframePoly);
			const sal_uInt32 nPlyCnt(aCandidate.count());

			if(nPlyCnt)
			{
				const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact());
				const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
				const basegfx::B3DHomMatrix aWorldToView(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection() * aViewInfo3D.getOrientation());
				const basegfx::B3DHomMatrix aTransform(aWorldToView * rCandidate.maDisplayTransform);

				// transform to relative scene coordinates
				basegfx::B2DPolyPolygon aPolyPolygon(basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCandidate, aTransform));

				// transform to 2D view coordinates
				aPolyPolygon.transform(rVCScene.getObjectTransformation());

				aResult.append(aPolyPolygon);
			}
		}
	}

	if(aResult.count())
	{
		::sdr::overlay::OverlayPolyPolygonStripedAndFilled* pNew = new ::sdr::overlay::OverlayPolyPolygonStripedAndFilled(
            aResult);
		rOverlayManager.add(*pNew);
		addToOverlayObjectList(*pNew);
	}
}

/*************************************************************************

								E3dDragRotate

*************************************************************************/

TYPEINIT1(E3dDragRotate, E3dDragMethod);

E3dDragRotate::E3dDragRotate(SdrDragView &_rView,
	const SdrMarkList& rMark,
	E3dDragConstraint eConstr,
	sal_Bool bFull)
:	E3dDragMethod(_rView, rMark, eConstr, bFull)
{
	// Zentrum aller selektierten Objekte in Augkoordinaten holen
	const sal_uInt32 nCnt(maGrp.size());

	if(nCnt)
	{
		const E3dScene *pScene = maGrp[0].mp3DObj->GetScene();

		if(pScene)
		{
			const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
			const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());

			for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
			{
				E3dDragMethodUnit& rCandidate = maGrp[nOb];
				basegfx::B3DPoint aObjCenter = rCandidate.mp3DObj->GetBoundVolume().getCenter();
				const basegfx::B3DHomMatrix aTransform(aViewInfo3D.getOrientation() * rCandidate.maDisplayTransform * rCandidate.maInitTransform);

				aObjCenter = aTransform * aObjCenter;
				maGlobalCenter += aObjCenter;
			}

			// Teilen durch Anzahl
			if(nCnt > 1)
			{
				maGlobalCenter /= (double)nCnt;
			}

			// get rotate center and transform to 3D eye coordinates
			basegfx::B2DPoint aRotCenter2D(Ref1().X(), Ref1().Y());

			// from world to relative scene using inverse getObjectTransformation()
			basegfx::B2DHomMatrix aInverseObjectTransform(rVCScene.getObjectTransformation());
			aInverseObjectTransform.invert();
			aRotCenter2D = aInverseObjectTransform * aRotCenter2D;

			// from 3D view to 3D eye
			basegfx::B3DPoint aRotCenter3D(aRotCenter2D.getX(), aRotCenter2D.getY(), 0.0);
			basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());
			aInverseViewToEye.invert();
			aRotCenter3D = aInverseViewToEye * aRotCenter3D;

		// X,Y des RotCenter und Tiefe der gemeinsamen Objektmitte aus
		// Rotationspunkt im Raum benutzen
			maGlobalCenter.setX(aRotCenter3D.getX());
			maGlobalCenter.setY(aRotCenter3D.getY());
		}
	}
}

/*************************************************************************
|*
|* Das Objekt wird bewegt, bestimme die Winkel
|*
\************************************************************************/

void E3dDragRotate::MoveSdrDrag(const Point& rPnt)
{
	// call parent
	E3dDragMethod::MoveSdrDrag(rPnt);

	if(DragStat().CheckMinMoved(rPnt))
	{
		// Modifier holen
		sal_uInt16 nModifier = 0;
		if(getSdrDragView().ISA(E3dView))
		{
			const MouseEvent& rLastMouse = ((E3dView&)getSdrDragView()).GetMouseEvent();
			nModifier = rLastMouse.GetModifier();
		}

		// Alle Objekte rotieren
		const sal_uInt32 nCnt(maGrp.size());

		for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
		{
			// Rotationswinkel bestimmen
			double fWAngle, fHAngle;
			E3dDragMethodUnit& rCandidate = maGrp[nOb];

			if(E3DDRAG_CONSTR_Z == meConstraint)
			{
				fWAngle = NormAngle360(GetAngle(rPnt - DragStat().GetRef1()) -
					rCandidate.mnStartAngle) - rCandidate.mnLastAngle;
				rCandidate.mnLastAngle = (long)fWAngle + rCandidate.mnLastAngle;
				fWAngle /= 100.0;
				fHAngle = 0.0;
			}
			else
			{
				fWAngle = 90.0 * (double)(rPnt.X() - maLastPos.X())
					/ (double)maFullBound.GetWidth();
				fHAngle = 90.0 * (double)(rPnt.Y() - maLastPos.Y())
					/ (double)maFullBound.GetHeight();
			}
			long nSnap = 0;

			if(!getSdrDragView().IsRotateAllowed(sal_False))
				nSnap = 90;

			if(nSnap != 0)
			{
				fWAngle = (double)(((long) fWAngle + nSnap/2) / nSnap * nSnap);
				fHAngle = (double)(((long) fHAngle + nSnap/2) / nSnap * nSnap);
			}

			// nach radiant
			fWAngle *= F_PI180;
			fHAngle *= F_PI180;

			// Transformation bestimmen
			basegfx::B3DHomMatrix aRotMat;
			if(E3DDRAG_CONSTR_Y & meConstraint)
			{
				if(nModifier & KEY_MOD2)
					aRotMat.rotate(0.0, 0.0, fWAngle);
				else
					aRotMat.rotate(0.0, fWAngle, 0.0);
			}
			else if(E3DDRAG_CONSTR_Z & meConstraint)
			{
				if(nModifier & KEY_MOD2)
					aRotMat.rotate(0.0, fWAngle, 0.0);
				else
					aRotMat.rotate(0.0, 0.0, fWAngle);
			}
			if(E3DDRAG_CONSTR_X & meConstraint)
			{
				aRotMat.rotate(fHAngle, 0.0, 0.0);
			}

			// Transformation in Eye-Koordinaten, dort rotieren
			// und zurueck
			const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact());
			const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
			basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
			aInverseOrientation.invert();

			basegfx::B3DHomMatrix aTransMat(rCandidate.maDisplayTransform);
			aTransMat *= aViewInfo3D.getOrientation();
			aTransMat.translate(-maGlobalCenter.getX(), -maGlobalCenter.getY(), -maGlobalCenter.getZ());
			aTransMat *= aRotMat;
			aTransMat.translate(maGlobalCenter.getX(), maGlobalCenter.getY(), maGlobalCenter.getZ());
			aTransMat *= aInverseOrientation;
			aTransMat *= rCandidate.maInvDisplayTransform;

			// ...und anwenden
			rCandidate.maTransform *= aTransMat;
			
			if(mbMoveFull)
			{
        		E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
				rCandidate.mp3DObj->SetTransform(rCandidate.maTransform);
			}
			else
			{
				Hide();
				rCandidate.maWireframePoly.transform(aTransMat);
				Show();
			}
		}
		maLastPos = rPnt;
		DragStat().NextMove(rPnt);
	}
}

/*************************************************************************
|*
\************************************************************************/

Pointer E3dDragRotate::GetSdrDragPointer() const
{
	return Pointer(POINTER_ROTATE);
}

/*************************************************************************
|*
|* E3dDragMove
|* Diese DragMethod wird nur bei Translationen innerhalb von 3D-Scenen
|* benoetigt. Wird eine 3D-Scene selbst verschoben, so wird diese DragMethod
|* nicht verwendet.
|*
\************************************************************************/

TYPEINIT1(E3dDragMove, E3dDragMethod);

E3dDragMove::E3dDragMove(SdrDragView &_rView,
	const SdrMarkList& rMark,
	SdrHdlKind eDrgHdl,
	E3dDragConstraint eConstr,
	sal_Bool bFull)
:	E3dDragMethod(_rView, rMark, eConstr, bFull),
	meWhatDragHdl(eDrgHdl)
{
	switch(meWhatDragHdl)
	{
		case HDL_LEFT:
			maScaleFixPos = maFullBound.RightCenter();
			break;
		case HDL_RIGHT:
			maScaleFixPos = maFullBound.LeftCenter();
			break;
		case HDL_UPPER:
			maScaleFixPos = maFullBound.BottomCenter();
			break;
		case HDL_LOWER:
			maScaleFixPos = maFullBound.TopCenter();
			break;
		case HDL_UPLFT:
			maScaleFixPos = maFullBound.BottomRight();
			break;
		case HDL_UPRGT:
			maScaleFixPos = maFullBound.BottomLeft();
			break;
		case HDL_LWLFT:
			maScaleFixPos = maFullBound.TopRight();
			break;
		case HDL_LWRGT:
			maScaleFixPos = maFullBound.TopLeft();
			break;
		default:
			// Bewegen des Objektes, HDL_MOVE
			break;
	}

	// Override wenn IsResizeAtCenter()
	if(getSdrDragView().IsResizeAtCenter())
	{
		meWhatDragHdl = HDL_USER;
		maScaleFixPos = maFullBound.Center();
	}
}

/*************************************************************************
|*
|* Das Objekt wird bewegt, bestimme die Translation
|*
\************************************************************************/

void E3dDragMove::MoveSdrDrag(const Point& rPnt)
{
	// call parent
	E3dDragMethod::MoveSdrDrag(rPnt);

	if(DragStat().CheckMinMoved(rPnt))
	{
		if(HDL_MOVE == meWhatDragHdl)
		{
			// Translation
			// Bewegungsvektor bestimmen
			basegfx::B3DPoint aGlobalMoveHead((double)(rPnt.X() - maLastPos.X()), (double)(rPnt.Y() - maLastPos.Y()), 32768.0);
			basegfx::B3DPoint aGlobalMoveTail(0.0, 0.0, 32768.0);
			const sal_uInt32 nCnt(maGrp.size());

			// Modifier holen
			sal_uInt16 nModifier(0);

			if(getSdrDragView().ISA(E3dView))
			{
				const MouseEvent& rLastMouse = ((E3dView&)getSdrDragView()).GetMouseEvent();
				nModifier = rLastMouse.GetModifier();
			}

			for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
			{
				E3dDragMethodUnit& rCandidate = maGrp[nOb];
				const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact());
				const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());

				// move coor from 2d world to 3d Eye
				basegfx::B2DPoint aGlobalMoveHead2D((double)(rPnt.X() - maLastPos.X()), (double)(rPnt.Y() - maLastPos.Y()));
				basegfx::B2DPoint aGlobalMoveTail2D(0.0, 0.0);
				basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation());
				
				aInverseSceneTransform.invert();
				aGlobalMoveHead2D = aInverseSceneTransform * aGlobalMoveHead2D;
				aGlobalMoveTail2D = aInverseSceneTransform * aGlobalMoveTail2D;

				basegfx::B3DPoint aMoveHead3D(aGlobalMoveHead2D.getX(), aGlobalMoveHead2D.getY(), 0.5);
				basegfx::B3DPoint aMoveTail3D(aGlobalMoveTail2D.getX(), aGlobalMoveTail2D.getY(), 0.5);
				basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());
				aInverseViewToEye.invert();

				aMoveHead3D = aInverseViewToEye * aMoveHead3D;
				aMoveTail3D = aInverseViewToEye * aMoveTail3D;

				// eventually switch movement from XY to XZ plane
				if(nModifier & KEY_MOD2)
				{
					double fZwi = aMoveHead3D.getY();
					aMoveHead3D.setY(aMoveHead3D.getZ());
					aMoveHead3D.setZ(fZwi);

					fZwi = aMoveTail3D.getY();
					aMoveTail3D.setY(aMoveTail3D.getZ());
					aMoveTail3D.setZ(fZwi);
				}

				// Bewegungsvektor von Aug-Koordinaten nach Parent-Koordinaten
				basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
				aInverseOrientation.invert();
				basegfx::B3DHomMatrix aCompleteTrans(rCandidate.maInvDisplayTransform * aInverseOrientation);

				aMoveHead3D = aCompleteTrans * aMoveHead3D;
				aMoveTail3D = aCompleteTrans* aMoveTail3D;

				// build transformation
				basegfx::B3DHomMatrix aTransMat;
				basegfx::B3DPoint aTranslate(aMoveHead3D - aMoveTail3D);
				aTransMat.translate(aTranslate.getX(), aTranslate.getY(), aTranslate.getZ());

				// ...and apply
				rCandidate.maTransform *= aTransMat;

				if(mbMoveFull)
				{
        			E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
					rCandidate.mp3DObj->SetTransform(rCandidate.maTransform);
				}
				else
				{
					Hide();
					rCandidate.maWireframePoly.transform(aTransMat);
					Show();
				}
			}
		}
		else
		{
			// Skalierung
			// Skalierungsvektor bestimmen
			Point aStartPos = DragStat().GetStart();
			const sal_uInt32 nCnt(maGrp.size());

			for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
			{
				E3dDragMethodUnit& rCandidate = maGrp[nOb];
				const basegfx::B3DPoint aObjectCenter(rCandidate.mp3DObj->GetBoundVolume().getCenter());

				// transform from 2D world view to 3D eye
				const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact());
				const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
				
				basegfx::B2DPoint aGlobalScaleStart2D((double)(aStartPos.X()), (double)(aStartPos.Y()));
				basegfx::B2DPoint aGlobalScaleNext2D((double)(rPnt.X()), (double)(rPnt.Y()));
				basegfx::B2DPoint aGlobalScaleFixPos2D((double)(maScaleFixPos.X()), (double)(maScaleFixPos.Y()));
				basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation());

				aInverseSceneTransform.invert();
				aGlobalScaleStart2D = aInverseSceneTransform * aGlobalScaleStart2D;
				aGlobalScaleNext2D = aInverseSceneTransform * aGlobalScaleNext2D;
				aGlobalScaleFixPos2D = aInverseSceneTransform * aGlobalScaleFixPos2D;

				basegfx::B3DPoint aGlobalScaleStart3D(aGlobalScaleStart2D.getX(), aGlobalScaleStart2D.getY(), aObjectCenter.getZ());
				basegfx::B3DPoint aGlobalScaleNext3D(aGlobalScaleNext2D.getX(), aGlobalScaleNext2D.getY(), aObjectCenter.getZ());
				basegfx::B3DPoint aGlobalScaleFixPos3D(aGlobalScaleFixPos2D.getX(), aGlobalScaleFixPos2D.getY(), aObjectCenter.getZ());
				basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());

				aInverseViewToEye.invert();
				basegfx::B3DPoint aScStart(aInverseViewToEye * aGlobalScaleStart3D);
				basegfx::B3DPoint aScNext(aInverseViewToEye * aGlobalScaleNext3D);
				basegfx::B3DPoint aScFixPos(aInverseViewToEye * aGlobalScaleFixPos3D);

				// constraints?
				switch(meWhatDragHdl)
				{
					case HDL_LEFT:
					case HDL_RIGHT:
						// constrain to auf X -> Y equal
						aScNext.setY(aScFixPos.getY());
						break;
					case HDL_UPPER:
					case HDL_LOWER:
						// constrain to auf Y -> X equal
						aScNext.setX(aScFixPos.getX());
						break;
					default:
						break;
				}

				// get scale vector in eye coordinates
				basegfx::B3DPoint aScaleVec(aScStart - aScFixPos);
				aScaleVec.setZ(1.0);

				if(aScaleVec.getX() != 0.0)
				{
					aScaleVec.setX((aScNext.getX() - aScFixPos.getX()) / aScaleVec.getX());
				}
				else
				{
					aScaleVec.setX(1.0);
				}

				if(aScaleVec.getY() != 0.0)
				{
					aScaleVec.setY((aScNext.getY() - aScFixPos.getY()) / aScaleVec.getY());
				}
				else
				{
					aScaleVec.setY(1.0);
				}

				// SHIFT-key used?
				if(getSdrDragView().IsOrtho())
				{
					if(fabs(aScaleVec.getX()) > fabs(aScaleVec.getY()))
					{
						// X is biggest
						aScaleVec.setY(aScaleVec.getX());
					}
					else
					{
						// Y is biggest
						aScaleVec.setX(aScaleVec.getY());
					}
				}

				// build transformation
				basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
				aInverseOrientation.invert();

				basegfx::B3DHomMatrix aNewTrans = rCandidate.maInitTransform;
				aNewTrans *= rCandidate.maDisplayTransform;
				aNewTrans *= aViewInfo3D.getOrientation();
				aNewTrans.translate(-aScFixPos.getX(), -aScFixPos.getY(), -aScFixPos.getZ());
				aNewTrans.scale(aScaleVec.getX(), aScaleVec.getY(), aScaleVec.getZ());
				aNewTrans.translate(aScFixPos.getX(), aScFixPos.getY(), aScFixPos.getZ());
				aNewTrans *= aInverseOrientation;
				aNewTrans *= rCandidate.maInvDisplayTransform;

				// ...und anwenden
				rCandidate.maTransform = aNewTrans;
				
				if(mbMoveFull)
				{
        			E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
					rCandidate.mp3DObj->SetTransform(rCandidate.maTransform);
				}
				else
				{
					Hide();
					rCandidate.maWireframePoly.clear();
					rCandidate.maWireframePoly = rCandidate.mp3DObj->CreateWireframe();
					rCandidate.maWireframePoly.transform(rCandidate.maTransform);
					Show();
				}
			}
		}
		maLastPos = rPnt;
		DragStat().NextMove(rPnt);
	}
}

/*************************************************************************
|*
\************************************************************************/

Pointer E3dDragMove::GetSdrDragPointer() const
{
	return Pointer(POINTER_MOVE);
}

// eof
