/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: dlgctl3d.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005/09/08 17:28:28 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SVX_DLGCTL3D_HXX
#define _SVX_DLGCTL3D_HXX

// includes --------------------------------------------------------------

#ifndef _TL_POLY_HXX
#include <tools/poly.hxx>
#endif

#ifndef _SV_CTRL_HXX
#include <vcl/ctrl.hxx>
#endif

#ifndef _B3D_B3DGEOM_HXX
#include <goodies/b3dgeom.hxx>
#endif

#ifndef _B3D_B3DTRANS_HXX
#include <goodies/b3dtrans.hxx>
#endif

#ifndef _B3D_MATRIL3D_HXX
#include <goodies/matril3d.hxx>
#endif

#ifndef _B3D_B3DLIGHT_HXX
#include <goodies/b3dlight.hxx>
#endif

#ifndef _SV_SCRBAR_HXX
#include <vcl/scrbar.hxx>
#endif

#ifndef _SV_BUTTON_HXX
#include <vcl/button.hxx>
#endif

#ifndef _SFXITEMSET_HXX //autogen
#include <svtools/itemset.hxx>
#endif

class Vector3D;
class FmFormModel;
class FmFormPage;
class E3dView;
class E3dPolyScene;
class E3dObject;

/*************************************************************************
|*
|*	Control zur Darstellung einer 3D-Scene
|*
\************************************************************************/

#define	PREVIEW_OBJECTTYPE_SPHERE			0x0000
#define	PREVIEW_OBJECTTYPE_CUBE  			0x0001

class Svx3DPreviewControl : public Control
{
protected:
	FmFormModel*		pModel;
	FmFormPage*			pFmPage;
	E3dView*			p3DView;
	E3dPolyScene*		pScene;
	E3dObject*			p3DObj;
	UINT16				nObjectType;

	void				Construct();

public:
					Svx3DPreviewControl( Window* pParent, const ResId& rResId );
					Svx3DPreviewControl( Window* pParent, WinBits nStyle = 0 );
					~Svx3DPreviewControl();

	virtual void 	Paint( const Rectangle& rRect );
	virtual void 	MouseButtonDown( const MouseEvent& rMEvt );
	virtual void	Resize();

	void			Reset();

	void			SetObjectType( UINT16 nType );
	UINT16			GetObjectType() const { return( nObjectType ); }

	SfxItemSet		Get3DAttributes() const;
	void			Set3DAttributes( const SfxItemSet& rAttr );

	void			Set3DObject( const E3dObject* pObj );
};

/*************************************************************************
|*
|*	Control zur Darstellung und Auswahl der Eckpunkte (und Mittelpunkt)
|*	eines Objekts
|*
\************************************************************************/
class SvxRectCtl3D : public Control
{
protected:
	long		nBW; // BorderWidth
	long		nBH; // BorderHeight
	USHORT		nRadius;
	Size		aSize;
	short		nActPoint;
	short		nOldPoint;
	short 		nDist;
	Point		aPointArray[20];
	Point 		aPolyPoints1[4];
	Point 		aPolyPoints2[4];
	Point 		aPolyPoints3[4];
	Polygon 	aPoly1;
	Polygon 	aPoly2;
	Polygon 	aPoly3;

	Vector3D	PointNumToVector( short nPoint );
	short 		VectorToPointNum( Vector3D aVect );

public:
	SvxRectCtl3D( Window* pParent,
				  const ResId& rResId,
				  USHORT nBorderW = 200,
				  USHORT nBorderH = 200,
				  USHORT nCircle = 80 );
	~SvxRectCtl3D();

	virtual void Paint( const Rectangle& rRect );
	virtual void MouseButtonDown( const MouseEvent& rMEvt );

	void		Reset();
	Vector3D	GetVector();
	void		SetPoint( Vector3D aVect );
};

/*************************************************************************
|*
|*	3D Preview Control
|*
\************************************************************************/

// Defines fuer NormalMode
#define	PREVIEW_NORMAL_MODE_OBJECT			0x0000
#define	PREVIEW_NORMAL_MODE_FLAT			0x0001
#define	PREVIEW_NORMAL_MODE_SPHERE			0x0002

// Defines fuer ShadeMode
#define	PREVIEW_SHADEMODE_FLAT				0x0000
#define	PREVIEW_SHADEMODE_PHONG				0x0001
#define	PREVIEW_SHADEMODE_GOURAUD			0x0002
#define	PREVIEW_SHADEMODE_DRAFT				0x0003

class SvxPreviewCtl3D : public Control
{
protected:
	// Geometrie des Objektes
	B3dGeometry				aGeometry;

	// Kameraset
	B3dCamera				aCameraSet;
	double					fDistance;
	double					fDeviceSize;

	// Rotation der Geometrie (bei Cube)
	double					fRotateX;
	double					fRotateY;
	double					fRotateZ;

	// Farben des Objektes
	B3dMaterial				aObjectMaterial;

	// Lichtquellen
	B3dLightGroup			aLights;

	// Segmentierung, wird bei Kugel verwendet
	UINT16					nHorSegs;
	UINT16					nVerSegs;

	// Modus fuer Normalen
	UINT16					nNormalMode;

	// Zeichenmodus
	UINT16					nShadeMode;

	// Art der Geometrie, Cube oder Sphere
	BOOL					bGeometryCube;

public:
	SvxPreviewCtl3D( Window* pParent, const ResId& rResId);
	SvxPreviewCtl3D( Window* pParent, WinBits nStyle = 0);
	~SvxPreviewCtl3D();

	// Zeichenmethode
	virtual void Paint( const Rectangle& rRect );
	void DrawGeometryClip(Base3D* pBase3D);
	virtual void DrawGeometry(Base3D* pBase3D);

	// Art der Geometrie setzen
	void SetGeometry(BOOL bGeomCube);

	// Rotation setzen
	void SetRotation(double fRotX, double fRotY, double fRotZ);
	void GetRotation(double& rRotX, double& rRotY, double& rRotZ);

	// Zugriffsfunktionen Materialien
	void SetMaterial(Color rNew,
		Base3DMaterialValue=Base3DMaterialAmbient);
	Color GetMaterial(Base3DMaterialValue=Base3DMaterialAmbient);
	void SetShininess(UINT16 nNew);
	UINT16 GetShininess();

	// Lichtquellen setzen
	void SetLightGroup(B3dLightGroup* pNew=0L);
	B3dLightGroup* GetLightGroup() { return &aLights; }

	// View-Einstellungen
	void SetUserDistance(double fNew);
	double GetUserDistance() { return fDistance; }
	void SetDeviceSize(double fNew);
	double GetDeviceSize() { return fDeviceSize; }

	// Zugriffsfunktionen Segmentierung
	UINT16 GetHorizontalSegments() { return nHorSegs; }
	UINT16 GetVerticalSegments() { return nVerSegs; }
	void SetHorizontalSegments(UINT16 nNew);
	void SetVerticalSegments(UINT16 nNew);
	void SetSegments(UINT16 nNewHor, UINT16 nNewVer);

	// Zugriff Normalenmodus
	UINT16 GetNormalMode() { return nNormalMode; }
	void SetNormalMode(UINT16 nNew);

	// Zugriff auf ShadeMode
	UINT16 GetShadeMode() { return nShadeMode; }
	void SetShadeMode(UINT16 nNew);

protected:

	// Geometrieerzeugung
	void CreateGeometry();

	// Lokale Parameter Initialisieren
	void Init();
};

/*************************************************************************
|*
|*	3D Light Preview Control
|*
\************************************************************************/

class SvxLightPrevievCtl3D : public SvxPreviewCtl3D
{
private:
	// Geometrie eines Lichtobjektes
	B3dGeometry			aLightGeometry;

	Base3DLightNumber	eSelectedLight;

	// Werte fuer Rendering
	double				fObjectRadius;
	double				fDistanceToObject;
	double				fScaleSizeSelected;
	double				fLampSize;

	// Callback bei interaktiven Aenderungen
	Link				aChangeCallback;
	Link				aSelectionChangeCallback;

	// Sichern der Interaktion
	double				fSaveActionStartHor;
	double				fSaveActionStartVer;
	double				fSaveActionStartRotZ;
	Point				aActionStartPoint;

	// Mindestentfernung fuer Interaktionsstart
	INT32				nInteractionStartDistance;

	// Maus-Status
	unsigned			bMouseMoved						: 1;
	unsigned			bGeometrySelected				: 1;

public:
	SvxLightPrevievCtl3D( Window* pParent, const ResId& rResId);
	SvxLightPrevievCtl3D( Window* pParent, WinBits nStyle = 0);
	~SvxLightPrevievCtl3D();

	void SelectLight(Base3DLightNumber=Base3DLightNone);
	Base3DLightNumber GetSelectedLight() { return eSelectedLight; }

	void SelectGeometry();
	BOOL IsGeometrySelected() { return bGeometrySelected; }

	void SetObjectRadius(double fNew);
	double GetObjectRadius() { return fObjectRadius; }

	void SetDistanceToObject(double fNew);
	double GetDistanceToObject() { return fDistanceToObject; }

	void SetScaleSizeSelected(double fNew);
	double GetScaleSizeSelected() { return fScaleSizeSelected; }

	void SetLampSize(double fNew);
	double GetLampSize() { return fLampSize; }

	// Zeichenmethode
	virtual void DrawGeometry(Base3D* pBase3D);
	void DrawLightGeometry(Base3DLightNumber eLightNum, Base3D* pBase3D);

	// Selektion gueltig
	BOOL IsSelectionValid();

	// Selektierte Lampe Position in Polarkoordinaten holen/setzen
	// dabei geht Hor:[0..360.0[ und Ver:[-90..90] Grad
	void GetPosition(double& rHor, double& rVer);
	void SetPosition(double fHor, double fVer);

	// Callback eintragen
	void SetChangeCallback(Link aNew) { aChangeCallback = aNew; }
	void SetSelectionChangeCallback(Link aNew) { aSelectionChangeCallback = aNew; }

	// Interaktion
	virtual void		MouseButtonDown( const MouseEvent& rMEvt );
	virtual void		Tracking( const TrackingEvent& rTEvt );

protected:

	// Geometrieerzeugung Lampe
	void CreateLightGeometry();

	// Selektion einer Lampe
	void TrySelection(Point aPosPixel);

	// Lokale Parameter Initialisieren
	void Init();
};

/*************************************************************************
|*
|*	3D Light Control
|*
\************************************************************************/

class SvxLightCtl3D : public Control
{
private:
	// Lokale Controls
	SvxLightPrevievCtl3D	aLightControl;
	ScrollBar				aHorScroller;
	ScrollBar				aVerScroller;
	PushButton				aSwitcher;
	Vector3D				aVector;

// Callback bei interaktiven Aenderungen
	Link					aUserInteractiveChangeCallback;
	Link					aUserSelectionChangeCallback;

	// Flags
	unsigned				bVectorValid					: 1;
	unsigned				bSphereUsed						: 1;

public:
	SvxLightCtl3D( Window* pParent, const ResId& rResId);
	SvxLightCtl3D( Window* pParent, WinBits nStyle = 0);
	~SvxLightCtl3D();

	// Altes Interface
	void SetVector(const Vector3D& rNew);
	const Vector3D& GetVector();
	BOOL GetVectorValid() { return bVectorValid; }

	// Reagiere auf Groessenaenderungen
	virtual void		Resize();
	void NewLayout();

	// Selektion auf Gueltigkeit pruefen
	void CheckSelection();

	// Um weitere Einstellungen nach Aussen zu bringen...
	SvxLightPrevievCtl3D& GetPreviewControl() { return aLightControl; }

	// User Callback eintragen
	void SetUserInteractiveChangeCallback(Link aNew)
		{ aUserInteractiveChangeCallback = aNew; }
	void SetUserSelectionChangeCallback(Link aNew)
		{ aUserSelectionChangeCallback = aNew; }

	virtual void KeyInput( const KeyEvent& rKEvt );
    virtual void GetFocus();
    virtual void LoseFocus();

	// ...um Kompatibel zu bleiben, kann spaeter wieder raus
	//DECL_LINK( InteractiveChange, void*);
	//DECL_LINK( SelectionChange, void*);

protected:

	DECL_LINK( InternalInteractiveChange, void*);
	DECL_LINK( InternalSelectionChange, void*);
	DECL_LINK( ScrollBarMove, void*);
	DECL_LINK( ButtonPress, void*);

	// Lokale Parameter Initialisieren
	void Init();

	void move( double fDeltaHor, double fDeltaVer );
};

#endif // _SCH_DLGCTL3D_HXX

