/**************************************************************
 * 
 * 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 "fucon3d.hxx"
#include <vcl/waitobj.hxx>

#include <svx/svxids.hrc>
#include <svl/aeitem.hxx>
#include <sfx2/app.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>
#include <tools/poly.hxx>

#include <math.h>
#include <svx/globl3d.hxx>
#include <svx/scene3d.hxx>
#include <svx/sphere3d.hxx>
#include <svx/cube3d.hxx>
#include <svx/lathe3d.hxx>
#include <svx/camera3d.hxx>

#include "app.hrc"
#include "res_bmp.hrc"
#include "View.hxx"
#include "Window.hxx"
#include "ViewShell.hxx"
#include "drawdoc.hxx"
#include "ViewShellBase.hxx"
#include "ToolBarManager.hxx"
#include <svx/svx3ditems.hxx>

// #97016#
#include <svx/polysc3d.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>

namespace sd {

TYPEINIT1( FuConstruct3dObject, FuConstruct );

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

FuConstruct3dObject::FuConstruct3dObject (
    ViewShell* 	pViewSh,
    ::sd::Window*		pWin,
    ::sd::View*			pView,
    SdDrawDocument*	pDoc,
    SfxRequest&		rReq) 
    : FuConstruct(pViewSh, pWin, pView, pDoc, rReq)
{
}

FunctionReference FuConstruct3dObject::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq, bool bPermanent )
{
	FuConstruct3dObject* pFunc;
	FunctionReference xFunc( pFunc = new FuConstruct3dObject( pViewSh, pWin, pView, pDoc, rReq ) );
	xFunc->DoExecute(rReq);
	pFunc->SetPermanent(bPermanent);
	return xFunc;
}

void FuConstruct3dObject::DoExecute( SfxRequest& rReq )
{
	FuConstruct::DoExecute( rReq );
    mpViewShell->GetViewShellBase().GetToolBarManager()->SetToolBar(
        ToolBarManager::TBG_FUNCTION,
        ToolBarManager::msDrawingObjectToolBar);
}

/*************************************************************************
|*
|* MouseButtonDown-event
|*
\************************************************************************/

// #97016#
E3dCompoundObject* FuConstruct3dObject::ImpCreateBasic3DShape()
{
	E3dCompoundObject* p3DObj = NULL;

	switch (nSlotId)
	{
		default:
		case SID_3D_CUBE:
		{
			p3DObj = new E3dCubeObj(
				mpView->Get3DDefaultAttributes(),
				::basegfx::B3DPoint(-2500, -2500, -2500),
				::basegfx::B3DVector(5000, 5000, 5000));
			break;
		}

		case SID_3D_SPHERE:
		{
			p3DObj = new E3dSphereObj(
				mpView->Get3DDefaultAttributes(),
				::basegfx::B3DPoint(0, 0, 0),
				::basegfx::B3DVector(5000, 5000, 5000));
			break;
		}

		case SID_3D_SHELL:
		{
			XPolygon aXPoly(Point (0, 1250), 2500, 2500, 0, 900, sal_False);
			aXPoly.Scale(5.0, 5.0);

			::basegfx::B2DPolygon aB2DPolygon(aXPoly.getB2DPolygon());
			if(aB2DPolygon.areControlPointsUsed())
			{
				aB2DPolygon = ::basegfx::tools::adaptiveSubdivideByAngle(aB2DPolygon);
			}
			p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aB2DPolygon));

			// Dies ist ein offenes Objekt, muss daher defaultmaessig
			// doppelseitig behandelt werden
			p3DObj->SetMergedItem(Svx3DDoubleSidedItem(sal_True));
			break;
		}

		case SID_3D_HALF_SPHERE:
		{
			XPolygon aXPoly(Point (0, 1250), 2500, 2500, 0, 900, sal_False);
			aXPoly.Scale(5.0, 5.0);

			aXPoly.Insert(0, Point (2400*5, 1250*5), XPOLY_NORMAL);
			aXPoly.Insert(0, Point (2000*5, 1250*5), XPOLY_NORMAL);
			aXPoly.Insert(0, Point (1500*5, 1250*5), XPOLY_NORMAL);
			aXPoly.Insert(0, Point (1000*5, 1250*5), XPOLY_NORMAL);
			aXPoly.Insert(0, Point (500*5, 1250*5), XPOLY_NORMAL);
			aXPoly.Insert(0, Point (250*5, 1250*5), XPOLY_NORMAL);
			aXPoly.Insert(0, Point (50*5, 1250*5), XPOLY_NORMAL);
			aXPoly.Insert(0, Point (0*5, 1250*5), XPOLY_NORMAL);

			::basegfx::B2DPolygon aB2DPolygon(aXPoly.getB2DPolygon());
			if(aB2DPolygon.areControlPointsUsed())
			{
				aB2DPolygon = ::basegfx::tools::adaptiveSubdivideByAngle(aB2DPolygon);
			}
			p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aB2DPolygon));
			break;
		}

		case SID_3D_TORUS:
		{
			::basegfx::B2DPolygon aB2DPolygon(::basegfx::tools::createPolygonFromCircle(::basegfx::B2DPoint(1000.0, 0.0), 500.0));
			if(aB2DPolygon.areControlPointsUsed())
			{
				aB2DPolygon = ::basegfx::tools::adaptiveSubdivideByAngle(aB2DPolygon);
			}
			p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aB2DPolygon));
			break;
		}

		case SID_3D_CYLINDER:
		{
			::basegfx::B2DPolygon aInnerPoly;

			aInnerPoly.append(::basegfx::B2DPoint(0, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(50*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(100*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(200*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(300*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(400*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(450*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(500*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(500*5, -1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(450*5, -1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(400*5, -1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(300*5, -1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(200*5, -1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(100*5, -1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(50*5, -1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(0*5, -1000*5));
			aInnerPoly.setClosed(true);

			p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aInnerPoly));
			break;
		}

		case SID_3D_CONE:
		{
			::basegfx::B2DPolygon aInnerPoly;

			aInnerPoly.append(::basegfx::B2DPoint(0, -1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(25*5, -900*5));
			aInnerPoly.append(::basegfx::B2DPoint(50*5, -800*5));
			aInnerPoly.append(::basegfx::B2DPoint(100*5, -600*5));
			aInnerPoly.append(::basegfx::B2DPoint(200*5, -200*5));
			aInnerPoly.append(::basegfx::B2DPoint(300*5, 200*5));
			aInnerPoly.append(::basegfx::B2DPoint(400*5, 600*5));
			aInnerPoly.append(::basegfx::B2DPoint(500*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(400*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(300*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(200*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(100*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(50*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(0*5, 1000*5));
			aInnerPoly.setClosed(true);

			p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aInnerPoly));
			break;
		}

		case SID_3D_PYRAMID:
		{
			::basegfx::B2DPolygon aInnerPoly;

			aInnerPoly.append(::basegfx::B2DPoint(0, -1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(25*5, -900*5));
			aInnerPoly.append(::basegfx::B2DPoint(50*5, -800*5));
			aInnerPoly.append(::basegfx::B2DPoint(100*5, -600*5));
			aInnerPoly.append(::basegfx::B2DPoint(200*5, -200*5));
			aInnerPoly.append(::basegfx::B2DPoint(300*5, 200*5));
			aInnerPoly.append(::basegfx::B2DPoint(400*5, 600*5));
			aInnerPoly.append(::basegfx::B2DPoint(500*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(400*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(300*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(200*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(100*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(50*5, 1000*5));
			aInnerPoly.append(::basegfx::B2DPoint(0, 1000*5));
			aInnerPoly.setClosed(true);

			p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aInnerPoly));
			p3DObj->SetMergedItem(Svx3DHorizontalSegmentsItem(4));
			break;
		}
	}

	return p3DObj;
}

// #97016#
void FuConstruct3dObject::ImpPrepareBasic3DShape(E3dCompoundObject* p3DObj, E3dScene *pScene)
{
	Camera3D &aCamera  = (Camera3D&) pScene->GetCamera ();

	// get transformed BoundVolume of the new object
	basegfx::B3DRange aBoundVol;
	basegfx::B3DRange aObjVol(p3DObj->GetBoundVolume());
	aObjVol.transform(p3DObj->GetTransform());
	aBoundVol.expand(aObjVol);
	double fDeepth(aBoundVol.getDepth());

	aCamera.SetPRP(::basegfx::B3DPoint(0.0, 0.0, 1000.0));
	aCamera.SetPosition(::basegfx::B3DPoint(0.0, 0.0, mpView->GetDefaultCamPosZ() + fDeepth / 2));
	aCamera.SetFocalLength(mpView->GetDefaultCamFocal());
	pScene->SetCamera(aCamera);
	basegfx::B3DHomMatrix aTransformation;

	switch (nSlotId)
	{
		case SID_3D_CUBE:
		{
			aTransformation.rotate(DEG2RAD(20), 0.0, 0.0);
		}
		break;

		case SID_3D_SPHERE:
		{
//				pScene->RotateX(DEG2RAD(60));
		}
		break;

		case SID_3D_SHELL:
		case SID_3D_HALF_SPHERE:
		{
			aTransformation.rotate(DEG2RAD(200), 0.0, 0.0);
		}
		break;

		case SID_3D_CYLINDER:
		case SID_3D_CONE:
		case SID_3D_PYRAMID:
		{
//				pScene->RotateX(DEG2RAD(25));
		}
		break;

		case SID_3D_TORUS:
		{
//				pScene->RotateX(DEG2RAD(15));
			aTransformation.rotate(DEG2RAD(90), 0.0, 0.0);
		}
		break;

		default:
		{
		}
		break;
	}

	pScene->SetTransform(aTransformation * pScene->GetTransform());

	SfxItemSet aAttr (mpViewShell->GetPool());
	pScene->SetMergedItemSetAndBroadcast(aAttr);
}

sal_Bool FuConstruct3dObject::MouseButtonDown(const MouseEvent& rMEvt)
{
	sal_Bool bReturn = FuConstruct::MouseButtonDown(rMEvt);

	if ( rMEvt.IsLeft() && !mpView->IsAction() )
	{
		Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) );

		mpWindow->CaptureMouse();
		sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );

		E3dCompoundObject* p3DObj = NULL;

		WaitObject aWait( (Window*)mpViewShell->GetActiveWindow() );

		// #97016#
		p3DObj = ImpCreateBasic3DShape();
		E3dScene* pScene = mpView->SetCurrent3DObj(p3DObj);

		// #97016#
		ImpPrepareBasic3DShape(p3DObj, pScene);
		bReturn = mpView->BegCreatePreparedObject(aPnt, nDrgLog, pScene);

		SdrObject* pObj = mpView->GetCreateObj();

		if (pObj)
		{
			SfxItemSet aAttr(mpDoc->GetPool());
			SetStyleSheet(aAttr, pObj);

			// LineStyle rausnehmen
			aAttr.Put(XLineStyleItem (XLINE_NONE));

			pObj->SetMergedItemSet(aAttr);
		}
	}

	return bReturn;
}

/*************************************************************************
|*
|* MouseMove-event
|*
\************************************************************************/

sal_Bool FuConstruct3dObject::MouseMove(const MouseEvent& rMEvt)
{
	return FuConstruct::MouseMove(rMEvt);
}

/*************************************************************************
|*
|* MouseButtonUp-event
|*
\************************************************************************/

sal_Bool FuConstruct3dObject::MouseButtonUp(const MouseEvent& rMEvt)
{
	sal_Bool bReturn = sal_False;

	if ( mpView->IsCreateObj() && rMEvt.IsLeft() )
	{
		Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
		mpView->EndCreateObj(SDRCREATE_FORCEEND);
		bReturn = sal_True;
	}

	bReturn = FuConstruct::MouseButtonUp(rMEvt) || bReturn;

	if (!bPermanent)
		mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON);

	return bReturn;
}

/*************************************************************************
|*
|* Tastaturereignisse bearbeiten
|*
|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert sal_True, andernfalls
|* sal_False.
|*
\************************************************************************/

sal_Bool FuConstruct3dObject::KeyInput(const KeyEvent& rKEvt)
{
	return( FuConstruct::KeyInput(rKEvt) );
}

/*************************************************************************
|*
|* Function aktivieren
|*
\************************************************************************/

void FuConstruct3dObject::Activate()
{
	mpView->SetCurrentObj(OBJ_NONE);

	FuConstruct::Activate();
}

/*************************************************************************
|*
|* Function deaktivieren
|*
\************************************************************************/

void FuConstruct3dObject::Deactivate()
{
	FuConstruct::Deactivate();
}

// #97016#
SdrObject* FuConstruct3dObject::CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle)
{
	// case SID_3D_CUBE:
	// case SID_3D_SHELL:
	// case SID_3D_SPHERE:
	// case SID_3D_TORUS:
	// case SID_3D_HALF_SPHERE:
	// case SID_3D_CYLINDER:
	// case SID_3D_CONE:
	// case SID_3D_PYRAMID:

	E3dCompoundObject* p3DObj = ImpCreateBasic3DShape();

	// E3dView::SetCurrent3DObj part		
	// get transformed BoundVolume of the object
	basegfx::B3DRange aObjVol(p3DObj->GetBoundVolume());
	aObjVol.transform(p3DObj->GetTransform());
	basegfx::B3DRange aVolume(aObjVol);
	double fW(aVolume.getWidth());
	double fH(aVolume.getHeight());
	Rectangle a3DRect(0, 0, (long)fW, (long)fH);
	E3dScene* pScene = new E3dPolyScene(mpView->Get3DDefaultAttributes());

	// mpView->InitScene(pScene, fW, fH, aVolume.MaxVec().Z() + ((fW + fH) / 4.0));
	// copied code from E3dView::InitScene
	double fCamZ(aVolume.getMaxZ() + ((fW + fH) / 4.0));
	Camera3D aCam(pScene->GetCamera());
	aCam.SetAutoAdjustProjection(sal_False);
	aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
	::basegfx::B3DPoint aLookAt;
	double fDefaultCamPosZ = mpView->GetDefaultCamPosZ();
	::basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);
	aCam.SetPosAndLookAt(aCamPos, aLookAt);
	aCam.SetFocalLength(mpView->GetDefaultCamFocal());
	aCam.SetDefaults(::basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ), aLookAt, mpView->GetDefaultCamFocal());
	pScene->SetCamera(aCam);
	
	pScene->Insert3DObj(p3DObj);
	pScene->NbcSetSnapRect(a3DRect);
	pScene->SetModel(mpDoc);
		
	ImpPrepareBasic3DShape(p3DObj, pScene);
		
	SfxItemSet aAttr(mpDoc->GetPool());
	SetStyleSheet(aAttr, p3DObj);
	aAttr.Put(XLineStyleItem (XLINE_NONE));
	p3DObj->SetMergedItemSet(aAttr);
	
	// make object interactive at once
	pScene->SetRectsDirty();

	// Take care of restrictions for the rectangle
	Rectangle aRect(rRectangle);

	switch(nID)
	{
		case SID_3D_CUBE:
		case SID_3D_SPHERE:
		case SID_3D_TORUS:
		{
			// force quadratic
			ImpForceQuadratic(aRect);
			break;
		}

		case SID_3D_SHELL:
		case SID_3D_HALF_SPHERE:
		{
			// force horizontal layout
			break;
		}

		case SID_3D_CYLINDER:
		case SID_3D_CONE:
		case SID_3D_PYRAMID:
		{
			// force vertical layout
			break;
		}
	}

	// #97016#, #98245# use changed rectangle, not original one
	pScene->SetLogicRect(aRect);

	return pScene;
}

} // end of namespace sd
