/**************************************************************
 * 
 * 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 <vcl/wrkwin.hxx>
#include <svx/svdogrp.hxx>
#include <svx/svdopath.hxx>
#include <tools/shl.hxx>
#include "svx/svditer.hxx"
#include <svx/svdpool.hxx>
#include <svx/svdorect.hxx>
#include <svx/svdmodel.hxx>
#include <svx/svdpagv.hxx>
#include <svx/svxids.hrc>
#include <editeng/colritem.hxx>
#include <svx/xtable.hxx>
#include <svx/svdview.hxx>
#include <svx/dialogs.hrc>
#include <svx/dialmgr.hxx>
#include "svx/globl3d.hxx"
#include <svx/obj3d.hxx>
#include <svx/lathe3d.hxx>
#include <svx/sphere3d.hxx>
#include <svx/extrud3d.hxx>
#include <svx/cube3d.hxx>
#include <svx/polysc3d.hxx>
#include "dragmt3d.hxx"
#include <svx/view3d.hxx>
#include <svx/svdundo.hxx>
#include <svx/xflclit.hxx>
#include <svx/xlnclit.hxx>
#include <svx/svdograf.hxx>
#include <svx/xbtmpit.hxx>
#include <svx/xflbmtit.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <svx/xlnwtit.hxx>
#include <svx/sdr/overlay/overlaypolypolygon.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <svx/sdrpaintwindow.hxx>
#include <svx/sdr/contact/viewcontactofe3dscene.hxx>
#include <drawinglayer/geometry/viewinformation3d.hxx>
#include <svx/sdrpagewindow.hxx>
#include <svx/sdr/contact/displayinfo.hxx>
#include <svx/sdr/contact/objectcontact.hxx>
#include <svx/sdr/contact/viewobjectcontact.hxx>
#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
#include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <basegfx/polygon/b2dpolypolygoncutter.hxx>

#define ITEMVALUE(ItemSet,Id,Cast)	((const Cast&)(ItemSet).Get(Id)).GetValue()

TYPEINIT1(E3dView, SdrView);

////////////////////////////////////////////////////////////////////////////////////////////////////
// Migrate Marking

class Impl3DMirrorConstructOverlay
{
	// The OverlayObjects
	::sdr::overlay::OverlayObjectList				maObjects;

	// the view
	const E3dView&									mrView;

	// the object count
	sal_uInt32										mnCount;

	// the unmirrored polygons
	basegfx::B2DPolyPolygon*						mpPolygons;

    // the overlay geometry from selected objects
    drawinglayer::primitive2d::Primitive2DSequence  maFullOverlay;

public:
	Impl3DMirrorConstructOverlay(const E3dView& rView);
	~Impl3DMirrorConstructOverlay();

	void SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB);
};

Impl3DMirrorConstructOverlay::Impl3DMirrorConstructOverlay(const E3dView& rView)
:	maObjects(),
    mrView(rView),
    mnCount(rView.GetMarkedObjectCount()),
    mpPolygons(0),
    maFullOverlay()
{
    if(mnCount)
    {
        if(mrView.IsSolidDragging())
        {
	        SdrPageView* pPV = rView.GetSdrPageView();

	        if(pPV && pPV->PageWindowCount())
	        {
		        sdr::contact::ObjectContact& rOC = pPV->GetPageWindow(0)->GetObjectContact();
    	        sdr::contact::DisplayInfo aDisplayInfo;

                // Do not use the last ViewPort set at the OC at the last ProcessDisplay()
                rOC.resetViewPort();

		        for(sal_uInt32 a(0);a < mnCount;a++)
		        {
			        SdrObject* pObject = mrView.GetMarkedObjectByIndex(a);

			        if(pObject)
			        {
				        sdr::contact::ViewContact& rVC = pObject->GetViewContact();
				        sdr::contact::ViewObjectContact& rVOC = rVC.GetViewObjectContact(rOC);
    				    
                        const drawinglayer::primitive2d::Primitive2DSequence aNewSequence(rVOC.getPrimitive2DSequenceHierarchy(aDisplayInfo));
                        drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(maFullOverlay, aNewSequence);
			        }
		        }
	        }
        }
        else
        {
	        mpPolygons = new basegfx::B2DPolyPolygon[mnCount];

	        for(sal_uInt32 a(0); a < mnCount; a++)
	        {
			    SdrObject* pObject = mrView.GetMarkedObjectByIndex(a);
		        mpPolygons[mnCount - (a + 1)] = pObject->TakeXorPoly();
	        }
        }
    }
}

Impl3DMirrorConstructOverlay::~Impl3DMirrorConstructOverlay()
{
	// The OverlayObjects are cleared using the destructor of OverlayObjectList.
	// That destructor calls clear() at the list which removes all objects from the
	// OverlayManager and deletes them.
    if(!mrView.IsSolidDragging())
    {
    	delete[] mpPolygons;
    }
}

void Impl3DMirrorConstructOverlay::SetMirrorAxis(Point aMirrorAxisA, Point aMirrorAxisB)
{
	// get rid of old overlay objects
	maObjects.clear();

	// create new ones
	for(sal_uInt32 a(0); a < mrView.PaintWindowCount(); a++)
	{
		SdrPaintWindow* pCandidate = mrView.GetPaintWindow(a);
		::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();

		if(pTargetOverlay)
		{
	        // buld transfoprmation: translate and rotate so that given edge is 
            // on x axis, them mirror in y and translate back
	        const basegfx::B2DVector aEdge(aMirrorAxisB.X() - aMirrorAxisA.X(), aMirrorAxisB.Y() - aMirrorAxisA.Y());
            basegfx::B2DHomMatrix aMatrixTransform(basegfx::tools::createTranslateB2DHomMatrix(
                -aMirrorAxisA.X(), -aMirrorAxisA.Y()));
	        aMatrixTransform.rotate(-atan2(aEdge.getY(), aEdge.getX()));
	        aMatrixTransform.scale(1.0, -1.0);
	        aMatrixTransform.rotate(atan2(aEdge.getY(), aEdge.getX()));
	        aMatrixTransform.translate(aMirrorAxisA.X(), aMirrorAxisA.Y());

            if(mrView.IsSolidDragging())
            {
                if(maFullOverlay.hasElements())
                {
					drawinglayer::primitive2d::Primitive2DSequence aContent(maFullOverlay);

					if(!aMatrixTransform.isIdentity())
					{
						// embed in transformation group
						drawinglayer::primitive2d::Primitive2DReference aTransformPrimitive2D(new drawinglayer::primitive2d::TransformPrimitive2D(aMatrixTransform, aContent));
						aContent = drawinglayer::primitive2d::Primitive2DSequence(&aTransformPrimitive2D, 1);
					}

                    // if we have full overlay from selected objects, embed with 50% transparence, the
                    // transformation is added to the OverlayPrimitive2DSequenceObject
		            drawinglayer::primitive2d::Primitive2DReference aUnifiedTransparencePrimitive2D(new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(aContent, 0.5));
                    aContent = drawinglayer::primitive2d::Primitive2DSequence(&aUnifiedTransparencePrimitive2D, 1);

					sdr::overlay::OverlayPrimitive2DSequenceObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aContent);
            		
		            pTargetOverlay->add(*pNew);
		            maObjects.append(*pNew);
                }
            }
            else
            {
		        for(sal_uInt32 b(0); b < mnCount; b++)
		        {
			        // apply to polygon
			        basegfx::B2DPolyPolygon aPolyPolygon(mpPolygons[b]);
			        aPolyPolygon.transform(aMatrixTransform);

			        ::sdr::overlay::OverlayPolyPolygonStripedAndFilled* pNew = new ::sdr::overlay::OverlayPolyPolygonStripedAndFilled(
                        aPolyPolygon);
			        pTargetOverlay->add(*pNew);
			        maObjects.append(*pNew);
                }
            }
		}
	}
}

/*************************************************************************
|*
|* Konstruktor 1
|*
\************************************************************************/

E3dView::E3dView(SdrModel* pModel, OutputDevice* pOut) :
    SdrView(pModel, pOut)
{
	InitView ();
}

/*************************************************************************
|*
|* DrawMarkedObj ueberladen, da eventuell nur einzelne 3D-Objekte
|* gezeichnet werden sollen
|*
\************************************************************************/

void E3dView::DrawMarkedObj(OutputDevice& rOut) const
{
	// Existieren 3D-Objekte, deren Szenen nicht selektiert sind?
	sal_Bool bSpecialHandling = sal_False;
	E3dScene *pScene = NULL;

	long nCnt = GetMarkedObjectCount();
	for(long nObjs = 0;nObjs < nCnt;nObjs++)
	{
		SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
		if(pObj && pObj->ISA(E3dCompoundObject))
		{
			// zugehoerige Szene
			pScene = ((E3dCompoundObject*)pObj)->GetScene();
			if(pScene && !IsObjMarked(pScene))
				bSpecialHandling = sal_True;
		}
		// Alle SelectionFlags zuruecksetzen
		if(pObj && pObj->ISA(E3dObject))
		{
			pScene = ((E3dObject*)pObj)->GetScene();
			if(pScene)
				pScene->SetSelected(sal_False);
		}
	}

	if(bSpecialHandling)
	{
		// SelectionFlag bei allen zu 3D Objekten gehoerigen
		// Szenen und deren Objekten auf nicht selektiert setzen
		long nObjs;
		for(nObjs = 0;nObjs < nCnt;nObjs++)
		{
			SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
			if(pObj && pObj->ISA(E3dCompoundObject))
			{
				// zugehoerige Szene
				pScene = ((E3dCompoundObject*)pObj)->GetScene();
				if(pScene)
					pScene->SetSelected(sal_False);
			}
		}

		// bei allen direkt selektierten Objekten auf selektiert setzen
		SdrMark* pM = NULL;

		for(nObjs = 0;nObjs < nCnt;nObjs++)
		{
			SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
			if(pObj && pObj->ISA(E3dObject))
			{
				// Objekt markieren
				E3dObject* p3DObj = (E3dObject*)pObj;
				p3DObj->SetSelected(sal_True);
				pScene = p3DObj->GetScene();
				pM = GetSdrMarkByIndex(nObjs);
			}
		}

		if(pScene)
		{
			// code from parent
			SortMarkedObjects();

			pScene->SetDrawOnlySelected(sal_True);
			pScene->SingleObjectPainter(rOut); // #110094#-17
			pScene->SetDrawOnlySelected(sal_False);
		}

		// SelectionFlag zuruecksetzen
		for(nObjs = 0;nObjs < nCnt;nObjs++)
		{
			SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
			if(pObj && pObj->ISA(E3dCompoundObject))
			{
				// zugehoerige Szene
				pScene = ((E3dCompoundObject*)pObj)->GetScene();
				if(pScene)
					pScene->SetSelected(sal_False);
			}
		}
	}
	else
	{
		// call parent
		SdrExchangeView::DrawMarkedObj(rOut);
	}
}

/*************************************************************************
|*
|* Model holen ueberladen, da bei einzelnen 3D Objekten noch eine Szene
|* untergeschoben werden muss
|*
\************************************************************************/

SdrModel* E3dView::GetMarkedObjModel() const
{
	// Existieren 3D-Objekte, deren Szenen nicht selektiert sind?
	bool bSpecialHandling(false);
	const sal_uInt32 nCount(GetMarkedObjectCount());
    sal_uInt32 nObjs(0);
	E3dScene *pScene = 0;

	for(nObjs = 0; nObjs < nCount; nObjs++)
	{
		const SdrObject* pObj = GetMarkedObjectByIndex(nObjs);

        if(!bSpecialHandling && pObj && pObj->ISA(E3dCompoundObject))
		{
			// if the object is selected, but it's scene not,
            // we need special handling
			pScene = ((E3dCompoundObject*)pObj)->GetScene();

			if(pScene && !IsObjMarked(pScene))
            {
				bSpecialHandling = true;
			}
		}

		if(pObj && pObj->ISA(E3dObject))
		{
            // reset all selection flags at 3D objects
			pScene = ((E3dObject*)pObj)->GetScene();
			
			if(pScene)
            {
				pScene->SetSelected(false);
            }
		}
	}

    if(!bSpecialHandling)
	{
		// call parent
		return SdrView::GetMarkedObjModel();
	}

	SdrModel* pNewModel = 0;
    Rectangle aSelectedSnapRect;

	// set 3d selection flags at all directly selected objects
    // and collect SnapRect of selected objects
	for(nObjs = 0; nObjs < nCount; nObjs++)
	{
		SdrObject *pObj = GetMarkedObjectByIndex(nObjs);

        if(pObj && pObj->ISA(E3dCompoundObject))
		{
			// mark object, but not scenes
			E3dCompoundObject* p3DObj = (E3dCompoundObject*)pObj;
			p3DObj->SetSelected(true);
            aSelectedSnapRect.Union(p3DObj->GetSnapRect());
		}
	}

	// create new mark list which contains all indirectly selected3d 
    // scenes as selected objects
    SdrMarkList aOldML(GetMarkedObjectList());
    SdrMarkList aNewML;
	SdrMarkList& rCurrentMarkList = ((E3dView*)this)->GetMarkedObjectListWriteAccess();
	rCurrentMarkList = aNewML;

	for(nObjs = 0; nObjs < nCount; nObjs++)
	{
		SdrObject *pObj = aOldML.GetMark(nObjs)->GetMarkedSdrObj();

		if(pObj && pObj->ISA(E3dObject))
		{
			pScene = ((E3dObject*)pObj)->GetScene();
			
            if(pScene && !IsObjMarked(pScene) && GetSdrPageView())
			{
				((E3dView*)this)->MarkObj(pScene, GetSdrPageView(), sal_False, sal_True);
			}
		}
	}

	// call parent. This will copy all scenes and the selection flags at the 3d objectss. So
    // it will be possible to delete all non-selected 3d objects from the cloned 3d scenes
	pNewModel = SdrView::GetMarkedObjModel();

	if(pNewModel)
	{
		for(sal_uInt16 nPg(0); nPg < pNewModel->GetPageCount(); nPg++)
		{
			const SdrPage* pSrcPg=pNewModel->GetPage(nPg);
			const sal_uInt32 nObAnz(pSrcPg->GetObjCount());

			for(sal_uInt32 nOb(0); nOb < nObAnz; nOb++)
			{
				const SdrObject* pSrcOb=pSrcPg->GetObj(nOb);

				if(pSrcOb->ISA(E3dScene))
				{
					pScene = (E3dScene*)pSrcOb;

                    // delete all not intentionally cloned 3d objects
                    pScene->removeAllNonSelectedObjects();

                    // reset select flags and set SnapRect of all selected objects
					pScene->SetSelected(false);
                    pScene->SetSnapRect(aSelectedSnapRect);
				}
			}
		}
	}

	// restore old selection
	rCurrentMarkList = aOldML;

	// model zurueckgeben
	return pNewModel;
}

/*************************************************************************
|*
|* Bei Paste muss - falls in eine Scene eingefuegt wird - die
|* Objekte der Szene eingefuegt werden, die Szene selbst aber nicht
|*
\************************************************************************/

sal_Bool E3dView::Paste(const SdrModel& rMod, const Point& rPos, SdrObjList* pLst, sal_uInt32 nOptions)
{
	sal_Bool bRetval = sal_False;

	// Liste holen
    Point aPos(rPos);
	SdrObjList* pDstList = pLst;
    ImpGetPasteObjList(aPos, pDstList);
    
	if(!pDstList)
		return sal_False;

	// Owner der Liste holen
	SdrObject* pOwner = pDstList->GetOwnerObj();
	if(pOwner && pOwner->ISA(E3dScene))
	{
		E3dScene* pDstScene = (E3dScene*)pOwner;
	    BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_EXCHANGE_PASTE));

		// Alle Objekte aus E3dScenes kopieren und direkt einfuegen
	    for(sal_uInt16 nPg(0); nPg < rMod.GetPageCount(); nPg++)
		{
	        const SdrPage* pSrcPg=rMod.GetPage(nPg);
	        sal_uInt32 nObAnz(pSrcPg->GetObjCount());

			// calculate offset for paste
			Rectangle aR = pSrcPg->GetAllObjBoundRect();
			Point aDist(aPos - aR.Center());

			// Unterobjekte von Szenen einfuegen
			for(sal_uInt32 nOb(0); nOb < nObAnz; nOb++)
			{
				const SdrObject* pSrcOb = pSrcPg->GetObj(nOb);
				if(pSrcOb->ISA(E3dScene))
				{
					E3dScene* pSrcScene = (E3dScene*)pSrcOb;
					ImpCloneAll3DObjectsToDestScene(pSrcScene, pDstScene, aDist);
				}
			}
		}
		EndUndo();
	}
	else
	{
		// call parent
		bRetval = SdrView::Paste(rMod, rPos, pLst, nOptions);
	}

	// und Rueckgabewert liefern
	return bRetval;
}

// #83403# Service routine used from local Clone() and from SdrCreateView::EndCreateObj(...)
sal_Bool E3dView::ImpCloneAll3DObjectsToDestScene(E3dScene* pSrcScene, E3dScene* pDstScene, Point /*aOffset*/)
{
	sal_Bool bRetval(sal_False);

	if(pSrcScene && pDstScene)
	{
		const sdr::contact::ViewContactOfE3dScene& rVCSceneDst = static_cast< sdr::contact::ViewContactOfE3dScene& >(pDstScene->GetViewContact());
		const drawinglayer::geometry::ViewInformation3D aViewInfo3DDst(rVCSceneDst.getViewInformation3D());
		const sdr::contact::ViewContactOfE3dScene& rVCSceneSrc = static_cast< sdr::contact::ViewContactOfE3dScene& >(pSrcScene->GetViewContact());
		const drawinglayer::geometry::ViewInformation3D aViewInfo3DSrc(rVCSceneSrc.getViewInformation3D());

		for(sal_uInt32 i(0); i < pSrcScene->GetSubList()->GetObjCount(); i++)
		{
			E3dCompoundObject* pCompoundObj = dynamic_cast< E3dCompoundObject* >(pSrcScene->GetSubList()->GetObj(i));

			if(pCompoundObj)
			{
				// #116235#
				E3dCompoundObject* pNewCompoundObj = dynamic_cast< E3dCompoundObject* >(pCompoundObj->Clone());
				
				if(pNewCompoundObj)
				{
                    // get dest scene's current range in 3D world coordinates
                    const basegfx::B3DHomMatrix aSceneToWorldTrans(pDstScene->GetFullTransform());
                	basegfx::B3DRange aSceneRange(pDstScene->GetBoundVolume());
                    aSceneRange.transform(aSceneToWorldTrans);

                    // get new object's implied object transformation
                    const basegfx::B3DHomMatrix aNewObjectTrans(pNewCompoundObj->GetTransform());

                    // get new object's range in 3D world coordinates in dest scene
                    // as if it were already added
                    const basegfx::B3DHomMatrix aObjectToWorldTrans(aSceneToWorldTrans * aNewObjectTrans);
                    basegfx::B3DRange aObjectRange(pNewCompoundObj->GetBoundVolume());
                    aObjectRange.transform(aObjectToWorldTrans);

                    // get scale adaption
                    const basegfx::B3DVector aSceneScale(aSceneRange.getRange());
                    const basegfx::B3DVector aObjectScale(aObjectRange.getRange());
                    double fScale(1.0);

                    // if new object's size in X,Y or Z is bigger that 80% of dest scene, adapt scale
                    // to not change the scene by the inserted object
                    const double fSizeFactor(0.5);

                    if(aObjectScale.getX() * fScale > aSceneScale.getX() * fSizeFactor)
                    {
                        const double fObjSize(aObjectScale.getX() * fScale);
                        const double fFactor((aSceneScale.getX() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize));
                        fScale *= fFactor;
                    }
                    
                    if(aObjectScale.getY() * fScale > aSceneScale.getY() * fSizeFactor)
                    {
                        const double fObjSize(aObjectScale.getY() * fScale);
                        const double fFactor((aSceneScale.getY() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize));
                        fScale *= fFactor;
					}

                    if(aObjectScale.getZ() * fScale > aSceneScale.getZ() * fSizeFactor)
                    {
                        const double fObjSize(aObjectScale.getZ() * fScale);
                        const double fFactor((aSceneScale.getZ() * fSizeFactor) / (basegfx::fTools::equalZero(fObjSize) ? 1.0 : fObjSize));
                        fScale *= fFactor;
                    }

                    // get translation adaption
                    const basegfx::B3DPoint aSceneCenter(aSceneRange.getCenter());
            		const basegfx::B3DPoint aObjectCenter(aObjectRange.getCenter());

                    // build full modification transform. The object's transformation
                    // shall be modified, so start at object coordinates; transform to 3d world coor
                    basegfx::B3DHomMatrix aModifyingTransform(aObjectToWorldTrans);

                    // translate to absolute center in 3d world coor
                    aModifyingTransform.translate(-aObjectCenter.getX(), -aObjectCenter.getY(), -aObjectCenter.getZ());

                    // scale to dest size in 3d world coor
                    aModifyingTransform.scale(fScale, fScale, fScale);

                    // translate to dest scene center in 3d world coor
                    aModifyingTransform.translate(aSceneCenter.getX(), aSceneCenter.getY(), aSceneCenter.getZ());

                    // transform from 3d world to dest object coordinates
                    basegfx::B3DHomMatrix aWorldToObject(aObjectToWorldTrans);
                    aWorldToObject.invert();
                    aModifyingTransform = aWorldToObject * aModifyingTransform;

                    // correct implied object transform by applying changing one in object coor
                    pNewCompoundObj->SetTransform(aModifyingTransform * aNewObjectTrans);

					// fill and insert new object
					pNewCompoundObj->SetModel(pDstScene->GetModel());
					pNewCompoundObj->SetPage(pDstScene->GetPage());
					pNewCompoundObj->NbcSetLayer(pCompoundObj->GetLayer());
					pNewCompoundObj->NbcSetStyleSheet(pCompoundObj->GetStyleSheet(), sal_True);
					pDstScene->Insert3DObj(pNewCompoundObj);
					bRetval = sal_True;

					// Undo anlegen
					if( GetModel()->IsUndoEnabled() )
						AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNewCompoundObj));
				}
			}
		}
	}

	return bRetval;
}

/*************************************************************************
|*
|* 3D-Konvertierung moeglich?
|*
\************************************************************************/

sal_Bool E3dView::IsConvertTo3DObjPossible() const
{
	sal_Bool bAny3D(sal_False);
	sal_Bool bGroupSelected(sal_False);
	sal_Bool bRetval(sal_True);

	for(sal_uInt32 a=0;!bAny3D && a<GetMarkedObjectCount();a++)
	{
		SdrObject *pObj = GetMarkedObjectByIndex(a);
		if(pObj)
		{
			ImpIsConvertTo3DPossible(pObj, bAny3D, bGroupSelected);
		}
	}

	bRetval = !bAny3D
		&& (
		   IsConvertToPolyObjPossible(sal_False)
		|| IsConvertToPathObjPossible(sal_False)
		|| IsImportMtfPossible());
	return bRetval;
}

void E3dView::ImpIsConvertTo3DPossible(SdrObject* pObj, sal_Bool& rAny3D,
	sal_Bool& rGroupSelected) const
{
	if(pObj)
	{
		if(pObj->ISA(E3dObject))
		{
			rAny3D = sal_True;
		}
		else
		{
			if(pObj->IsGroupObject())
			{
				SdrObjListIter aIter(*pObj, IM_DEEPNOGROUPS);
				while(aIter.IsMore())
				{
					SdrObject* pNewObj = aIter.Next();
					ImpIsConvertTo3DPossible(pNewObj, rAny3D, rGroupSelected);
				}
				rGroupSelected = sal_True;
			}
		}
	}
}

/*************************************************************************
|*
|* 3D-Konvertierung zu Extrude ausfuehren
|*
\************************************************************************/
#include <editeng/eeitem.hxx>

void E3dView::ImpChangeSomeAttributesFor3DConversion(SdrObject* pObj)
{
	if(pObj->ISA(SdrTextObj))
	{
		const SfxItemSet& rSet = pObj->GetMergedItemSet();
		const SvxColorItem& rTextColorItem = (const SvxColorItem&)rSet.Get(EE_CHAR_COLOR);
		if(rTextColorItem.GetValue() == RGB_Color(COL_BLACK))
		{
			// Bei schwarzen Textobjekten wird die Farbe auf grau gesetzt
			if(pObj->GetPage())
			{
				// #84864# if black is only default attribute from
				// pattern set it hard so that it is used in undo.
				pObj->SetMergedItem(SvxColorItem(RGB_Color(COL_BLACK), EE_CHAR_COLOR));

				// add undo now
				if( GetModel()->IsUndoEnabled() )
					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj, false, false));
			}

			pObj->SetMergedItem(SvxColorItem(RGB_Color(COL_GRAY), EE_CHAR_COLOR));
		}
	}
}

void E3dView::ImpChangeSomeAttributesFor3DConversion2(SdrObject* pObj)
{
	if(pObj->ISA(SdrPathObj))
	{
		const SfxItemSet& rSet = pObj->GetMergedItemSet();
		sal_Int32 nLineWidth = ((const XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue();
		XLineStyle eLineStyle = (XLineStyle)((const XLineStyleItem&)rSet.Get(XATTR_LINESTYLE)).GetValue();
		XFillStyle eFillStyle = ITEMVALUE(rSet, XATTR_FILLSTYLE, XFillStyleItem);

		if(((SdrPathObj*)pObj)->IsClosed() 
			&& eLineStyle == XLINE_SOLID 
			&& !nLineWidth 
			&& eFillStyle != XFILL_NONE)
		{
			if(pObj->GetPage() && GetModel()->IsUndoEnabled() )
				AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj, false, false));
			pObj->SetMergedItem(XLineStyleItem(XLINE_NONE));
			pObj->SetMergedItem(XLineWidthItem(0L));
		}
	}
}

void E3dView::ImpCreateSingle3DObjectFlat(E3dScene* pScene, SdrObject* pObj, sal_Bool bExtrude, double fDepth, basegfx::B2DHomMatrix& rLatheMat)
{
	// Einzelnes PathObject, dieses umwanden
	SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj);

	if(pPath)
	{
		E3dDefaultAttributes aDefault = Get3DDefaultAttributes();
		if(bExtrude)
			aDefault.SetDefaultExtrudeCharacterMode(sal_True);
		else
			aDefault.SetDefaultLatheCharacterMode(sal_True);

		// ItemSet des Ursprungsobjektes holen
		SfxItemSet aSet(pObj->GetMergedItemSet());

		XFillStyle eFillStyle = ITEMVALUE(aSet, XATTR_FILLSTYLE, XFillStyleItem);

		// Linienstil ausschalten
		aSet.Put(XLineStyleItem(XLINE_NONE));

		// Feststellen, ob ein FILL_Attribut gesetzt ist.
		if(!pPath->IsClosed() || eFillStyle == XFILL_NONE)
		{
			// Das SdrPathObj ist nicht gefuellt, lasse die
			// vordere und hintere Flaeche weg. Ausserdem ist
			// eine beidseitige Darstellung notwendig.
			aDefault.SetDefaultExtrudeCloseFront(sal_False);
			aDefault.SetDefaultExtrudeCloseBack(sal_False);

			aSet.Put(Svx3DDoubleSidedItem(sal_True));

			// Fuellattribut setzen
			aSet.Put(XFillStyleItem(XFILL_SOLID));

			// Fuellfarbe muss auf Linienfarbe, da das Objekt vorher
			// nur eine Linie war
			Color aColorLine = ((const XLineColorItem&)(aSet.Get(XATTR_LINECOLOR))).GetColorValue();
			aSet.Put(XFillColorItem(String(), aColorLine));
		}

		// Neues Extrude-Objekt erzeugen
		E3dObject* p3DObj = NULL;
		if(bExtrude)
		{
			p3DObj = new E3dExtrudeObj(aDefault, pPath->GetPathPoly(), fDepth);
		}
		else
		{
			basegfx::B2DPolyPolygon aPolyPoly2D(pPath->GetPathPoly());
			aPolyPoly2D.transform(rLatheMat);
			p3DObj = new E3dLatheObj(aDefault, aPolyPoly2D);
		}

		// Attribute setzen
		if(p3DObj)
		{
			p3DObj->NbcSetLayer(pObj->GetLayer());

			p3DObj->SetMergedItemSet(aSet);
			
			p3DObj->NbcSetStyleSheet(pObj->GetStyleSheet(), sal_True);

			// Neues 3D-Objekt einfuegen
			pScene->Insert3DObj(p3DObj);
		}
	}
}

void E3dView::ImpCreate3DObject(E3dScene* pScene, SdrObject* pObj, sal_Bool bExtrude, double fDepth, basegfx::B2DHomMatrix& rLatheMat)
{
	if(pObj)
	{
		// change text color attribute for not so dark colors
		if(pObj->IsGroupObject())
		{
			SdrObjListIter aIter(*pObj, IM_DEEPWITHGROUPS);
			while(aIter.IsMore())
			{
				SdrObject* pGroupMember = aIter.Next();
				ImpChangeSomeAttributesFor3DConversion(pGroupMember);
			}
		}
		else
			ImpChangeSomeAttributesFor3DConversion(pObj);
		
		// convert completely to path objects
		SdrObject* pNewObj1 = pObj->ConvertToPolyObj(sal_False, sal_False);

		if(pNewObj1)
		{
			// change text color attribute for not so dark colors
			if(pNewObj1->IsGroupObject())
			{
				SdrObjListIter aIter(*pNewObj1, IM_DEEPWITHGROUPS);
				while(aIter.IsMore())
				{
					SdrObject* pGroupMember = aIter.Next();
					ImpChangeSomeAttributesFor3DConversion2(pGroupMember);
				}
			}
			else
				ImpChangeSomeAttributesFor3DConversion2(pNewObj1);
			
			// convert completely to path objects
			SdrObject* pNewObj2 = pObj->ConvertToContourObj(pNewObj1, sal_True);

			if(pNewObj2)
			{
				// add all to flat scene
				if(pNewObj2->IsGroupObject())
				{
					SdrObjListIter aIter(*pNewObj2, IM_DEEPWITHGROUPS);
					while(aIter.IsMore())
					{
						SdrObject* pGroupMember = aIter.Next();
						ImpCreateSingle3DObjectFlat(pScene, pGroupMember, bExtrude, fDepth, rLatheMat);
					}
				}
				else
					ImpCreateSingle3DObjectFlat(pScene, pNewObj2, bExtrude, fDepth, rLatheMat);

				// delete zwi object
				if(pNewObj2 != pObj && pNewObj2 != pNewObj1 && pNewObj2)
                    SdrObject::Free( pNewObj2 );
			}

			// delete zwi object
			if(pNewObj1 != pObj && pNewObj1)
				SdrObject::Free( pNewObj1 );
		}
	}
}

/*************************************************************************
|*
|* 3D-Konvertierung zu Extrude steuern
|*
\************************************************************************/

void E3dView::ConvertMarkedObjTo3D(sal_Bool bExtrude, basegfx::B2DPoint aPnt1, basegfx::B2DPoint aPnt2)
{
	if(AreObjectsMarked())
	{
		// Undo anlegen
        if(bExtrude)
			BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_EXTRUDE));
		else
			BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_LATHE));

		// Neue Szene fuer zu erzeugende 3D-Objekte anlegen
        E3dScene* pScene = new E3dPolyScene(Get3DDefaultAttributes());

		// Rechteck bestimmen und evtl. korrigieren
		Rectangle aRect = GetAllMarkedRect();
		if(aRect.GetWidth() <= 1)
			aRect.SetSize(Size(500, aRect.GetHeight()));
		if(aRect.GetHeight() <= 1)
			aRect.SetSize(Size(aRect.GetWidth(), 500));

		// Tiefe relativ zur Groesse der Selektion bestimmen
		double fDepth = 0.0;
		double fRot3D = 0.0;
		basegfx::B2DHomMatrix aLatheMat;

		if(bExtrude)
		{
			double fW = (double)aRect.GetWidth();
			double fH = (double)aRect.GetHeight();
			fDepth = sqrt(fW*fW + fH*fH) / 6.0;
		}
		if(!bExtrude)
		{
			// Transformation fuer Polygone Rotationskoerper erstellen
			if(aPnt1 != aPnt2)
			{
				// Rotation um Kontrollpunkt1 mit eigestelltem Winkel
				// fuer 3D Koordinaten
				basegfx::B2DPoint aDiff(aPnt1 - aPnt2);
				fRot3D = atan2(aDiff.getY(), aDiff.getX()) - F_PI2;

                if(basegfx::fTools::equalZero(fabs(fRot3D)))
					fRot3D = 0.0;

				if(fRot3D != 0.0)
				{
                    aLatheMat = basegfx::tools::createRotateAroundPoint(aPnt2, -fRot3D)
                        * aLatheMat;
				}
			}

			if(aPnt2.getX() != 0.0)
			{
				// Translation auf Y=0 - Achse
				aLatheMat.translate(-aPnt2.getX(), 0.0);
			}
			else
			{
				aLatheMat.translate((double)-aRect.Left(), 0.0);
			}

			// Inverse Matrix bilden, um die Zielausdehnung zu bestimmen
			basegfx::B2DHomMatrix aInvLatheMat(aLatheMat);
			aInvLatheMat.invert();

			// SnapRect Ausdehnung mittels Spiegelung an der Rotationsachse
			// erweitern
			for(sal_uInt32 a=0;a<GetMarkedObjectCount();a++)
			{
				SdrMark* pMark = GetSdrMarkByIndex(a);
				SdrObject* pObj = pMark->GetMarkedSdrObj();
				Rectangle aTurnRect = pObj->GetSnapRect();
				basegfx::B2DPoint aRot;
				Point aRotPnt;

				aRot = basegfx::B2DPoint(aTurnRect.Left(), -aTurnRect.Top());
				aRot *= aLatheMat;
				aRot.setX(-aRot.getX());
				aRot *= aInvLatheMat;
				aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5));
				aRect.Union(Rectangle(aRotPnt, aRotPnt));

				aRot = basegfx::B2DPoint(aTurnRect.Left(), -aTurnRect.Bottom());
				aRot *= aLatheMat;
				aRot.setX(-aRot.getX());
				aRot *= aInvLatheMat;
				aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5));
				aRect.Union(Rectangle(aRotPnt, aRotPnt));

				aRot = basegfx::B2DPoint(aTurnRect.Right(), -aTurnRect.Top());
				aRot *= aLatheMat;
				aRot.setX(-aRot.getX());
				aRot *= aInvLatheMat;
				aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5));
				aRect.Union(Rectangle(aRotPnt, aRotPnt));

				aRot = basegfx::B2DPoint(aTurnRect.Right(), -aTurnRect.Bottom());
				aRot *= aLatheMat;
				aRot.setX(-aRot.getX());
				aRot *= aInvLatheMat;
				aRotPnt = Point((long)(aRot.getX() + 0.5), (long)(-aRot.getY() - 0.5));
				aRect.Union(Rectangle(aRotPnt, aRotPnt));
			}
		}

		// Ueber die Selektion gehen und in 3D wandeln, komplett mit
		// Umwandeln in SdrPathObject, auch Schriften
		for(sal_uInt32 a=0;a<GetMarkedObjectCount();a++)
		{
			SdrMark* pMark = GetSdrMarkByIndex(a);
			SdrObject* pObj = pMark->GetMarkedSdrObj();

			ImpCreate3DObject(pScene, pObj, bExtrude, fDepth, aLatheMat);
		}

		if(pScene->GetSubList() && pScene->GetSubList()->GetObjCount() != 0)
		{
			// Alle angelegten Objekte Tiefenarrangieren
			if(bExtrude)
				DoDepthArrange(pScene, fDepth);

			// 3D-Objekte auf die Mitte des Gesamtrechtecks zentrieren
			basegfx::B3DPoint aCenter(pScene->GetBoundVolume().getCenter());
			basegfx::B3DHomMatrix aMatrix;

            aMatrix.translate(-aCenter.getX(), -aCenter.getY(), -aCenter.getZ());
			pScene->SetTransform(aMatrix * pScene->GetTransform()); // #112587#

			// Szene initialisieren
			pScene->NbcSetSnapRect(aRect);
			basegfx::B3DRange aBoundVol = pScene->GetBoundVolume();
			InitScene(pScene, (double)aRect.GetWidth(), (double)aRect.GetHeight(), aBoundVol.getDepth());

			// Szene anstelle des ersten selektierten Objektes einfuegen
			// und alle alten Objekte weghauen
			SdrObject* pRepObj = GetMarkedObjectByIndex(0);
			SdrPageView* pPV = GetSdrPageViewOfMarkedByIndex(0);
			MarkObj(pRepObj, pPV, sal_True);
			ReplaceObjectAtView(pRepObj, *pPV, pScene, sal_False);
			DeleteMarked();
			MarkObj(pScene, pPV);

			// Rotationskoerper um Rotationsachse drehen
			basegfx::B3DHomMatrix aRotate;

			if(!bExtrude && fRot3D != 0.0)
			{
				aRotate.rotate(0.0, 0.0, fRot3D);
			}

			// Default-Rotation setzen
			{
	            double XRotateDefault = 20;
				aRotate.rotate(DEG2RAD(XRotateDefault), 0.0, 0.0);
			}

			if(!aRotate.isIdentity())
			{
				pScene->SetTransform(aRotate * pScene->GetTransform());
			}

			// SnapRects der Objekte ungueltig
			pScene->SetSnapRect(aRect);
		}
		else
        {
			// Es wurden keine 3D Objekte erzeugt, schmeiss alles weg
			delete pScene;
        }

		// Undo abschliessen
        EndUndo();
	}
}

/*************************************************************************
|*
|* Alle enthaltenen Extrude-Objekte Tiefenarrangieren
|*
\************************************************************************/

struct E3dDepthNeighbour
{
	E3dDepthNeighbour*	        mpNext;
	E3dExtrudeObj*		        mpObj;
    basegfx::B2DPolyPolygon     maPreparedPolyPolygon;

    E3dDepthNeighbour()
    :   mpNext(0),
        mpObj(0),
        maPreparedPolyPolygon()
    { 
    }
};

struct E3dDepthLayer
{
	E3dDepthLayer*		        mpDown;
	E3dDepthNeighbour*	        mpNext;

	E3dDepthLayer() 
    :   mpDown(0),
        mpNext(0)
    { 
    }

	~E3dDepthLayer() 
    { 
        while(mpNext) 
        { 
            E3dDepthNeighbour* pSucc = mpNext->mpNext; 
            delete mpNext; 
            mpNext = pSucc; 
        }
    }
};

void E3dView::DoDepthArrange(E3dScene* pScene, double fDepth)
{
	if(pScene && pScene->GetSubList() && pScene->GetSubList()->GetObjCount() > 1)
	{
		SdrObjList* pSubList = pScene->GetSubList();
		SdrObjListIter aIter(*pSubList, IM_FLAT);
		E3dDepthLayer* pBaseLayer = NULL;
		E3dDepthLayer* pLayer = NULL;
		sal_Int32 nNumLayers = 0;

		while(aIter.IsMore())
		{
			E3dExtrudeObj* pExtrudeObj = dynamic_cast< E3dExtrudeObj* >(aIter.Next());

			if(pExtrudeObj)
			{
                const basegfx::B2DPolyPolygon aExtrudePoly(
                    basegfx::tools::prepareForPolygonOperation(pExtrudeObj->GetExtrudePolygon()));
				const SfxItemSet& rLocalSet = pExtrudeObj->GetMergedItemSet();
				const XFillStyle eLocalFillStyle = ITEMVALUE(rLocalSet, XATTR_FILLSTYLE, XFillStyleItem);
				const Color aLocalColor = ((const XFillColorItem&)(rLocalSet.Get(XATTR_FILLCOLOR))).GetColorValue();

				// sort in ExtrudeObj
				if(pLayer)
				{
					// do we have overlap with an object of this layer?
					bool bOverlap(false);
					E3dDepthNeighbour* pAct = pLayer->mpNext;

					while(!bOverlap && pAct)
					{
						// do pAct->mpObj and pExtrudeObj overlap? Check by
                        // using logical AND clipping
                        const basegfx::B2DPolyPolygon aAndPolyPolygon(
                            basegfx::tools::solvePolygonOperationAnd(
                                aExtrudePoly, 
                                pAct->maPreparedPolyPolygon));

                        bOverlap = (0 != aAndPolyPolygon.count());
                        
						if(bOverlap)
						{
							// second ciriteria: is another fillstyle or color used?
							const SfxItemSet& rCompareSet = pAct->mpObj->GetMergedItemSet();
							
							XFillStyle eCompareFillStyle = ITEMVALUE(rCompareSet, XATTR_FILLSTYLE, XFillStyleItem);

							if(eLocalFillStyle == eCompareFillStyle)
							{				  
								if(eLocalFillStyle == XFILL_SOLID)
								{
									Color aCompareColor = ((const XFillColorItem&)(rCompareSet.Get(XATTR_FILLCOLOR))).GetColorValue();

									if(aCompareColor == aLocalColor)
									{
										bOverlap = sal_False;
									}
								}
								else if(eLocalFillStyle == XFILL_NONE)
								{
									bOverlap = sal_False;
								}
							}
						}

						pAct = pAct->mpNext;
					}

					if(bOverlap)
					{
						// yes, start a new layer
						pLayer->mpDown = new E3dDepthLayer;
						pLayer = pLayer->mpDown;
						nNumLayers++;
						pLayer->mpNext = new E3dDepthNeighbour;
						pLayer->mpNext->mpObj = pExtrudeObj;
						pLayer->mpNext->maPreparedPolyPolygon = aExtrudePoly;
					}
					else
					{
						// no, add to current layer
						E3dDepthNeighbour* pNewNext = new E3dDepthNeighbour;
						pNewNext->mpObj = pExtrudeObj;
						pNewNext->maPreparedPolyPolygon = aExtrudePoly;
						pNewNext->mpNext = pLayer->mpNext;
						pLayer->mpNext = pNewNext;
					}
				}
				else
				{
					// first layer ever
					pBaseLayer = new E3dDepthLayer;
					pLayer = pBaseLayer;
					nNumLayers++;
					pLayer->mpNext = new E3dDepthNeighbour;
					pLayer->mpNext->mpObj = pExtrudeObj;
					pLayer->mpNext->maPreparedPolyPolygon = aExtrudePoly;
				}
			}
		}

		// number of layers is done
		if(nNumLayers > 1)
		{
			// need to be arranged
			double fMinDepth = fDepth * 0.8;
			double fStep = (fDepth - fMinDepth) / (double)nNumLayers;
			pLayer = pBaseLayer;

			while(pLayer)
			{
				// move along layer
				E3dDepthNeighbour* pAct = pLayer->mpNext;

				while(pAct)
				{
					// adapt extrude value
					pAct->mpObj->SetMergedItem(SfxUInt32Item(SDRATTR_3DOBJ_DEPTH, sal_uInt32(fMinDepth + 0.5)));

					// next
					pAct = pAct->mpNext;
				}

				// next layer
				pLayer = pLayer->mpDown;
				fMinDepth += fStep;
			}
		}

		// cleanup
		while(pBaseLayer)
		{
			pLayer = pBaseLayer->mpDown;
			delete pBaseLayer;
			pBaseLayer = pLayer;
		}
	}
}

/*************************************************************************
|*
|* Drag beginnen, vorher ggf. Drag-Methode fuer 3D-Objekte erzeugen
|*
\************************************************************************/

sal_Bool E3dView::BegDragObj(const Point& rPnt, OutputDevice* pOut,
	SdrHdl* pHdl, short nMinMov,
	SdrDragMethod* pForcedMeth)
{
    if(Is3DRotationCreationActive() && GetMarkedObjectCount())
	{
		// bestimme alle selektierten Polygone und gebe die gespiegelte Hilfsfigur aus
		mpMirrorOverlay->SetMirrorAxis(aRef1, aRef2);
	}
	else
    {
        sal_Bool bOwnActionNecessary;
        if (pHdl == NULL)
        {
           bOwnActionNecessary = sal_True;
        }
        else if (pHdl->IsVertexHdl() || pHdl->IsCornerHdl())
        {
           bOwnActionNecessary = sal_True;
        }
        else
        {
           bOwnActionNecessary = sal_False;
        }

        if(bOwnActionNecessary && GetMarkedObjectCount() >= 1)
        {
            E3dDragConstraint eConstraint = E3DDRAG_CONSTR_XYZ;
			sal_Bool bThereAreRootScenes = sal_False;
			sal_Bool bThereAre3DObjects = sal_False;
			long nCnt = GetMarkedObjectCount();
			for(long nObjs = 0;nObjs < nCnt;nObjs++)
			{
				SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
				if(pObj)
				{
					if(pObj->ISA(E3dScene) && ((E3dScene*)pObj)->GetScene() == pObj)
						bThereAreRootScenes = sal_True;
					if(pObj->ISA(E3dObject))
						bThereAre3DObjects = sal_True;
				}
			}
			if( bThereAre3DObjects )
			{
                eDragHdl = ( pHdl == NULL ? HDL_MOVE : pHdl->GetKind() );
                switch ( eDragMode )
                {
                    case SDRDRAG_ROTATE:
                    case SDRDRAG_SHEAR:
                    {
                        switch ( eDragHdl )
                        {
                            case HDL_LEFT:
                            case HDL_RIGHT:
                            {
                                eConstraint = E3DDRAG_CONSTR_X;
                            }
                            break;

                            case HDL_UPPER:
                            case HDL_LOWER:
                            {
                                eConstraint = E3DDRAG_CONSTR_Y;
                            }
                            break;

                            case HDL_UPLFT:
                            case HDL_UPRGT:
                            case HDL_LWLFT:
                            case HDL_LWRGT:
                            {
                                eConstraint = E3DDRAG_CONSTR_Z;
                            }
                            break;
							default: break;
                        }

                        // die nicht erlaubten Rotationen ausmaskieren
                        eConstraint = E3dDragConstraint(eConstraint& eDragConstraint);
                        pForcedMeth = new E3dDragRotate(*this, GetMarkedObjectList(), eConstraint, IsSolidDragging());
                    }
                    break;

                    case SDRDRAG_MOVE:
                    {
                        if(!bThereAreRootScenes)
						{
							pForcedMeth = new E3dDragMove(*this, GetMarkedObjectList(), eDragHdl, eConstraint, IsSolidDragging());
						}
                    }
                    break;

                    // spaeter mal
                    case SDRDRAG_MIRROR:
                    case SDRDRAG_CROOK:
                    case SDRDRAG_DISTORT:
                    case SDRDRAG_TRANSPARENCE:
                    case SDRDRAG_GRADIENT:
                    default:
                    {
                    }
                    break;
                }
			}
        }
    }
    return SdrView::BegDragObj(rPnt, pOut, pHdl, nMinMov, pForcedMeth);
}

/*************************************************************************
|*
|* Pruefen, obj 3D-Szene markiert ist
|*
\************************************************************************/

sal_Bool E3dView::HasMarkedScene()
{
	return (GetMarkedScene() != NULL);
}

/*************************************************************************
|*
|* Pruefen, obj 3D-Szene markiert ist
|*
\************************************************************************/

E3dScene* E3dView::GetMarkedScene()
{
	sal_uIntPtr nCnt = GetMarkedObjectCount();

	for ( sal_uIntPtr i = 0; i < nCnt; i++ )
		if ( GetMarkedObjectByIndex(i)->ISA(E3dScene) )
			return (E3dScene*) GetMarkedObjectByIndex(i);

	return NULL;
}

/*************************************************************************
|*
|* aktuelles 3D-Zeichenobjekt setzen, dafuer Szene erzeugen
|*
\************************************************************************/

E3dScene* E3dView::SetCurrent3DObj(E3dObject* p3DObj)
{
	DBG_ASSERT(p3DObj != NULL, "Nana, wer steckt denn hier 'nen NULL-Zeiger rein?");
	E3dScene* pScene = NULL;

	// get transformed BoundVolume of the object
	basegfx::B3DRange aVolume(p3DObj->GetBoundVolume());
	aVolume.transform(p3DObj->GetTransform());
	double fW(aVolume.getWidth());
	double fH(aVolume.getHeight());
	
	Rectangle aRect(0,0, (long) fW, (long) fH);

	pScene = new E3dPolyScene(Get3DDefaultAttributes());

	InitScene(pScene, fW, fH, aVolume.getMaxZ() + ((fW + fH) / 4.0));

	pScene->Insert3DObj(p3DObj);
	pScene->NbcSetSnapRect(aRect);

	return pScene;
}

/*************************************************************************
|*
|* neu erzeugte Szene initialisieren
|*
\************************************************************************/

void E3dView::InitScene(E3dScene* pScene, double fW, double fH, double fCamZ)
{
	Camera3D aCam(pScene->GetCamera());

	aCam.SetAutoAdjustProjection(sal_False);
	aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
	basegfx::B3DPoint aLookAt;

	double fDefaultCamPosZ = GetDefaultCamPosZ();
	basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);

	aCam.SetPosAndLookAt(aCamPos, aLookAt);
	aCam.SetFocalLength(GetDefaultCamFocal());
	aCam.SetDefaults(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ), aLookAt, GetDefaultCamFocal());
	pScene->SetCamera(aCam);
}

/*************************************************************************
|*
|* startsequenz fuer die erstellung eines 3D-Rotationskoerpers
|*
\************************************************************************/

void E3dView::Start3DCreation()
{
	if (GetMarkedObjectCount())
	{
		// irgendwelche Markierungen ermitteln und ausschalten
		//HMHBOOL bVis = IsMarkHdlShown();

		//HMHif (bVis) HideMarkHdl();

		// bestimme die koordinaten fuer JOEs Mirrorachse
		// entgegen der normalen Achse wird diese an die linke Seite des Objektes
		// positioniert
		long		  nOutMin = 0;
		long		  nOutMax = 0;
		long		  nMinLen = 0;
		long		  nObjDst = 0;
		long		  nOutHgt = 0;
		OutputDevice* pOut	  = GetFirstOutputDevice(); //GetWin(0);

		// erstmal Darstellungsgrenzen bestimmen
		if (pOut != NULL)
		{
			nMinLen = pOut->PixelToLogic(Size(0,50)).Height();
			nObjDst = pOut->PixelToLogic(Size(0,20)).Height();

			long nDst = pOut->PixelToLogic(Size(0,10)).Height();

			nOutMin =  -pOut->GetMapMode().GetOrigin().Y();
			nOutMax =  pOut->GetOutputSize().Height() - 1 + nOutMin;
			nOutMin += nDst;
			nOutMax -= nDst;

			if (nOutMax - nOutMin < nDst)
			{
				nOutMin += nOutMax + 1;
				nOutMin /= 2;
				nOutMin -= (nDst + 1) / 2;
				nOutMax  = nOutMin + nDst;
			}

			nOutHgt = nOutMax - nOutMin;

			long nTemp = nOutHgt / 4;
			if (nTemp > nMinLen) nMinLen = nTemp;
		}

		// und dann die Markierungen oben und unten an das Objekt heften
		basegfx::B2DRange aR;
		for(sal_uInt32 nMark(0L); nMark < GetMarkedObjectCount(); nMark++)
		{
			SdrObject* pMark = GetMarkedObjectByIndex(nMark);
			basegfx::B2DPolyPolygon aXPP(pMark->TakeXorPoly());
			aR.expand(basegfx::tools::getRange(aXPP));
		}

		basegfx::B2DPoint aCenter(aR.getCenter());
        long	  nMarkHgt = basegfx::fround(aR.getHeight()) - 1;
		long	  nHgt	   = nMarkHgt + nObjDst * 2;

		if (nHgt < nMinLen) nHgt = nMinLen;

		long nY1 = basegfx::fround(aCenter.getY()) - (nHgt + 1) / 2;
		long nY2 = nY1 + nHgt;

		if (pOut && (nMinLen > nOutHgt)) nMinLen = nOutHgt;
		if (pOut)
		{
			if (nY1 < nOutMin)
			{
				nY1 = nOutMin;
				if (nY2 < nY1 + nMinLen) nY2 = nY1 + nMinLen;
			}
			if (nY2 > nOutMax)
			{
				nY2 = nOutMax;
				if (nY1 > nY2 - nMinLen) nY1 = nY2 - nMinLen;
			}
		}

        aRef1.X() = basegfx::fround(aR.getMinX());    // Initial Achse um 2/100mm nach links
		aRef1.Y() = nY1;
        aRef2.X() = aRef1.X();
		aRef2.Y() = nY2;

		// Markierungen einschalten
		SetMarkHandles();

		//HMHif (bVis) ShowMarkHdl();
		if (AreObjectsMarked()) MarkListHasChanged();

		// SpiegelPolygone SOFORT zeigen
		const SdrHdlList &aHdlList = GetHdlList();
		mpMirrorOverlay = new Impl3DMirrorConstructOverlay(*this);
		mpMirrorOverlay->SetMirrorAxis(aHdlList.GetHdl(HDL_REF1)->GetPos(), aHdlList.GetHdl(HDL_REF2)->GetPos());
		//CreateMirrorPolygons ();
		//ShowMirrorPolygons (aHdlList.GetHdl (HDL_REF1)->GetPos (),
		//					aHdlList.GetHdl (HDL_REF2)->GetPos ());
	}
}

/*************************************************************************
|*
|* was passiert bei einer Mausbewegung, wenn das Objekt erstellt wird ?
|*
\************************************************************************/

void E3dView::MovAction(const Point& rPnt)
{
    if(Is3DRotationCreationActive())
	{
		SdrHdl* pHdl = GetDragHdl();

		if (pHdl)
		{
			SdrHdlKind eHdlKind = pHdl->GetKind();

			// reagiere nur bei einer spiegelachse
			if ((eHdlKind == HDL_REF1) ||
				(eHdlKind == HDL_REF2) ||
				(eHdlKind == HDL_MIRX))
			{
				const SdrHdlList &aHdlList = GetHdlList ();

				// loesche das gespiegelte Polygon, spiegele das Original und zeichne es neu
                //ShowMirrored ();
                SdrView::MovAction (rPnt);
				mpMirrorOverlay->SetMirrorAxis(
					aHdlList.GetHdl (HDL_REF1)->GetPos(),
					aHdlList.GetHdl (HDL_REF2)->GetPos());
            }
		}
        else
        {
            SdrView::MovAction (rPnt);
        }
	}
    else
    {
        SdrView::MovAction (rPnt);
    }
}

/*************************************************************************
|*
|* Schluss. Objekt und evtl. Unterobjekte ueber ImpCreate3DLathe erstellen
|*          [FG] Mit dem Parameterwert sal_True (SDefault: sal_False) wird einfach ein
|*               Rotationskoerper erzeugt, ohne den Benutzer die Lage der
|*               Achse fetlegen zu lassen. Es reicht dieser Aufruf, falls
|*               ein Objekt selektiert ist. (keine Initialisierung noetig)
|*
\************************************************************************/

void E3dView::End3DCreation(sal_Bool bUseDefaultValuesForMirrorAxes)
{
	ResetCreationActive();

	if(AreObjectsMarked())
	{
		if(bUseDefaultValuesForMirrorAxes)
		{
			Rectangle aRect = GetAllMarkedRect();
			if(aRect.GetWidth() <= 1)
				aRect.SetSize(Size(500, aRect.GetHeight()));
			if(aRect.GetHeight() <= 1)
				aRect.SetSize(Size(aRect.GetWidth(), 500));

			basegfx::B2DPoint aPnt1(aRect.Left(), -aRect.Top());
			basegfx::B2DPoint aPnt2(aRect.Left(), -aRect.Bottom());

			ConvertMarkedObjTo3D(sal_False, aPnt1, aPnt2);
		}
		else
		{
			// Hilfsfigur ausschalten
		    // bestimme aus den Handlepositionen und den Versatz der Punkte
            const SdrHdlList &aHdlList = GetHdlList();
    		Point aMirrorRef1 = aHdlList.GetHdl(HDL_REF1)->GetPos();
	    	Point aMirrorRef2 = aHdlList.GetHdl(HDL_REF2)->GetPos();

			basegfx::B2DPoint aPnt1(aMirrorRef1.X(), -aMirrorRef1.Y());
			basegfx::B2DPoint aPnt2(aMirrorRef2.X(), -aMirrorRef2.Y());

			ConvertMarkedObjTo3D(sal_False, aPnt1, aPnt2);
		}
	}
}

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

E3dView::~E3dView ()
{
}

/*************************************************************************
|*
|* beende das erzeugen und loesche die polygone
|*
\************************************************************************/

void E3dView::ResetCreationActive ()
{
	if(mpMirrorOverlay)
	{
		delete mpMirrorOverlay;
		mpMirrorOverlay = 0L;
	}
}

/*************************************************************************
|*
|* Klasse initialisieren
|*
\************************************************************************/

void E3dView::InitView ()
{
	eDragConstraint 		 = E3DDRAG_CONSTR_XYZ;
	fDefaultScaleX			 =
	fDefaultScaleY			 =
	fDefaultScaleZ			 = 1.0;
	fDefaultRotateX 		 =
	fDefaultRotateY 		 =
	fDefaultRotateZ 		 = 0.0;
	fDefaultExtrusionDeepth  = 1000; // old: 2000;
	fDefaultLightIntensity	 = 0.8; // old: 0.6;
	fDefaultAmbientIntensity = 0.4;
    nHDefaultSegments        = 12;
    nVDefaultSegments        = 12;
    aDefaultLightColor       = RGB_Color(COL_WHITE);
    aDefaultAmbientColor     = RGB_Color(COL_BLACK);
    bDoubleSided             = sal_False;
	mpMirrorOverlay = 0L;
}

/*************************************************************************
|*
|* Koennen die selektierten Objekte aufgebrochen werden?
|*
\************************************************************************/

sal_Bool E3dView::IsBreak3DObjPossible() const
{
    sal_uIntPtr nCount = GetMarkedObjectCount();

    if (nCount > 0)
    {
        sal_uIntPtr i = 0;

        while (i < nCount)
        {
            SdrObject* pObj = GetMarkedObjectByIndex(i);

            if (pObj && pObj->ISA(E3dObject))
            {
                if(!(((E3dObject*)pObj)->IsBreakObjPossible()))
                    return sal_False;
            }
            else
            {
                return sal_False;
            }

            i++;
        }
    }
    else
    {
        return sal_False;
    }

    return sal_True;
}

/*************************************************************************
|*
|* Selektierte Lathe-Objekte aufbrechen
|*
\************************************************************************/

void E3dView::Break3DObj()
{
	if(IsBreak3DObjPossible())
	{
		// ALLE selektierten Objekte werden gewandelt
	    sal_uInt32 nCount = GetMarkedObjectCount();

		BegUndo(String(SVX_RESSTR(RID_SVX_3D_UNDO_BREAK_LATHE)));
		for(sal_uInt32 a=0;a<nCount;a++)
		{
			E3dObject* pObj = (E3dObject*)GetMarkedObjectByIndex(a);
			BreakSingle3DObj(pObj);
		}
		DeleteMarked();
		EndUndo();
	}
}

void E3dView::BreakSingle3DObj(E3dObject* pObj)
{
	if(pObj->ISA(E3dScene))
	{
		SdrObjList* pSubList = pObj->GetSubList();
		SdrObjListIter aIter(*pSubList, IM_FLAT);

		while(aIter.IsMore())
		{
			E3dObject* pSubObj = (E3dObject*)aIter.Next();
			BreakSingle3DObj(pSubObj);
		}
	}
	else
	{
		SdrAttrObj* pNewObj = pObj->GetBreakObj();
		if(pNewObj)
		{
			InsertObjectAtView(pNewObj, *GetSdrPageView(), SDRINSERT_DONTMARK);
			pNewObj->SetChanged();
			pNewObj->BroadcastObjectChange();
		}
	}
}

/*************************************************************************
|*
|* Szenen mischen
|*
\************************************************************************/

void E3dView::MergeScenes ()
{
    sal_uIntPtr nCount = GetMarkedObjectCount();

    if (nCount > 0)
    {
        sal_uIntPtr     nObj    = 0;
        SdrObject *pObj   = GetMarkedObjectByIndex(nObj);
		E3dScene  *pScene = new E3dPolyScene(Get3DDefaultAttributes());
        basegfx::B3DRange aBoundVol;
        Rectangle aAllBoundRect (GetMarkedObjBoundRect ());
		Point     aCenter (aAllBoundRect.Center());

        while (pObj)
        {
            if (pObj->ISA(E3dScene))
            {
                /**********************************************************
                * Es ist eine 3D-Scene oder 3D-PolyScene
                **********************************************************/
                SdrObjList* pSubList = ((E3dObject*) pObj)->GetSubList();

                SdrObjListIter aIter(*pSubList, IM_FLAT);

                while (aIter.IsMore())
                {
                    /******************************************************
                    * LatheObjekte suchen
                    ******************************************************/
                    SdrObject* pSubObj = aIter.Next();

                        E3dObject *pNewObj = 0;

                        switch (pSubObj->GetObjIdentifier())
                        {
			                case E3D_CUBEOBJ_ID	:
								pNewObj = new E3dCubeObj;
								*(E3dCubeObj*)pNewObj = *(E3dCubeObj*)pSubObj;
				                break;

			                case E3D_SPHEREOBJ_ID:
								pNewObj = new E3dSphereObj;
								*(E3dSphereObj*)pNewObj = *(E3dSphereObj*)pSubObj;
				                break;

			                case E3D_EXTRUDEOBJ_ID:
								pNewObj = new E3dExtrudeObj;
								*(E3dExtrudeObj*)pNewObj = *(E3dExtrudeObj*)pSubObj;
				                break;

			                case E3D_LATHEOBJ_ID:
								pNewObj = new E3dLatheObj;
								*(E3dLatheObj*)pNewObj = *(E3dLatheObj*)pSubObj;
				                break;

                            case E3D_COMPOUNDOBJ_ID:
								pNewObj = new E3dCompoundObject;
								*(E3dCompoundObject*)pNewObj = *(E3dCompoundObject*)pSubObj;
				                break;
                        }

                        Rectangle aBoundRect = pSubObj->GetCurrentBoundRect();

            			basegfx::B3DHomMatrix aMatrix;
            			aMatrix.translate(aBoundRect.Left() - aCenter.getX(), aCenter.getY(), 0.0);
			            pNewObj->SetTransform(aMatrix * pNewObj->GetTransform()); // #112587#

                        if (pNewObj) aBoundVol.expand(pNewObj->GetBoundVolume());
						pScene->Insert3DObj (pNewObj);
				}
            }

            nObj++;

            if (nObj < nCount)
            {
                pObj = GetMarkedObjectByIndex(nObj);
            }
            else
            {
                pObj = NULL;
            }
        }

	    double fW = aAllBoundRect.GetWidth();
	    double fH = aAllBoundRect.GetHeight();
	    Rectangle aRect(0,0, (long) fW, (long) fH);

	    InitScene(pScene, fW, fH, aBoundVol.getMaxZ() +  + ((fW + fH) / 4.0));
	    pScene->NbcSetSnapRect(aRect);

        Camera3D &aCamera  = (Camera3D&) pScene->GetCamera ();
		basegfx::B3DPoint aMinVec(aBoundVol.getMinimum());
        basegfx::B3DPoint aMaxVec(aBoundVol.getMaximum());
        double fDeepth(fabs(aMaxVec.getZ() - aMinVec.getZ()));

        aCamera.SetPRP(basegfx::B3DPoint(0.0, 0.0, 1000.0));
		double fDefaultCamPosZ(GetDefaultCamPosZ());
		aCamera.SetPosition(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ + fDeepth / 2.0));
	    aCamera.SetFocalLength(GetDefaultCamFocal());
        pScene->SetCamera (aCamera);

		// SnapRects der Objekte ungueltig
		pScene->SetRectsDirty();

		InsertObjectAtView(pScene, *(GetSdrPageViewOfMarkedByIndex(0)));

		// SnapRects der Objekte ungueltig
		pScene->SetRectsDirty();
    }
}

/*************************************************************************
|*
|* Possibilities, hauptsaechlich gruppieren/ungruppieren
|*
\************************************************************************/
void E3dView::CheckPossibilities()
{
	// call parent
	SdrView::CheckPossibilities();

	// Weitere Flags bewerten
	if(bGroupPossible || bUnGroupPossible || bGrpEnterPossible)
	{
		sal_Int32 nMarkCnt = GetMarkedObjectCount();
		sal_Bool bCoumpound = sal_False;
		sal_Bool b3DObject = sal_False;
		for(sal_Int32 nObjs = 0L; (nObjs < nMarkCnt) && !bCoumpound; nObjs++)
		{
			SdrObject *pObj = GetMarkedObjectByIndex(nObjs);
			if(pObj && pObj->ISA(E3dCompoundObject))
				bCoumpound = sal_True;
			if(pObj && pObj->ISA(E3dObject))
				b3DObject = sal_True;
		}

		// Bisher: Es sind ZWEI oder mehr beliebiger Objekte selektiert.
		// Nachsehen, ob CompoundObjects beteiligt sind. Falls ja,
		// das Gruppieren verbieten.
		if(bGroupPossible && bCoumpound)
			bGroupPossible = sal_False;

		if(bUnGroupPossible && b3DObject)
			bUnGroupPossible = sal_False;

		if(bGrpEnterPossible && bCoumpound)
			bGrpEnterPossible = sal_False;
	}
}

// eof
