//================================================================
// 3DPanel header file
//
// AUTHOR:  Gabor Nagy
// DATE:    2026-Aug-10 18:03:08
//
// Copyright (C) 1996-2026 By Gabor Nagy. All rights reserved.
//================================================================
#ifndef _E3D_Panel_h
#define _E3D_Panel_h

#include <Xe/Menu.h>
#include <Xe/DropDownPanel.h>

#ifndef _E3D_Node_h
#include <E3D/Node.h>
#endif

#ifndef _E3D_WindowAdv_h
#include <E3D/UI/WindowAdv.h>
#endif

#ifndef _E3D_Rendering_h
#include <E3D/Rendering.h>
#endif

#ifndef _E3D_Scene_h
#include <E3D/Scene.h>
#endif

#include <E3D/Languages.h>

#include <E3D/UI/Prefs.h>

extern XeApp            Xe_App;

extern E3dPolygonFlags  E3dp_PolygonSelectFlag;
extern E3dEdgeFlags     E3dp_EdgeSelectFlag;
extern E3dVertexFlags   E3dp_VertexSelectFlag;

#define E3dDeleteSELECTED_NODES       0x0001
#define E3dDeleteSELECTED_OBJECTS     0x0002
#define E3dDeleteSELECTED_POLYGROUPS  0x0004
#define E3dDeleteSELECTED_POLYGONS    0x0008
#define E3dDeleteSELECTED_EDGES       0x0010
#define E3dDeleteSELECTED_POINTS      0x0020
#define E3dDisconnectSELECTED_POINTS  0x0040  // Remove corresponding VertexNodes of Polygons, but don't deleate the Mesh Vertex
#define E3dDeleteUNUSED_POINTS        0x0080


#if E3dFLOAT_BITS == 64
	#define XeScale_SetValue_Coord           XeScale_SetValue_f64
	#define XeScale_GetValue_Coord           XeScale_GetValue_f64
	#define XeScale_SetValueAndRange_Coord   XeScale_SetValueAndRange_f64
	#define XeScale_SetValueAndRanges_Coord  XeScale_SetValueAndRanges_f64
	#define XeScale_SetIncrement_Coord       XeScale_SetIncrement_f64
	#define m_Coordinate                    f64
	#define XeScale_New_Coord             XeScale_New_f64
#else
	#if E3dFLOAT_BITS == 32
		#define XeScale_SetValue_Coord           XeScale_SetValue_f32
		#define XeScale_GetValue_Coord           XeScale_GetValue_f32
		#define XeScale_SetValueAndRange_Coord   XeScale_SetValueAndRange_f32
		#define XeScale_SetValueAndRanges_Coord  XeScale_SetValueAndRanges_f32
	#define XeScale_SetIncrement_Coord         XeScale_SetIncrement_f32
		#define m_Coordinate                    f32
		#define XeScale_New_Coord             XeScale_ManagedNew_f32
	#else
ERROR
	#endif
#endif


#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
extern "C" {
#endif

// Macros for Xe compound strings with Mode/Object names, mouse buttons etc.
//
#define E3dp_LMouseButtonS     XeFONT, XeFontFIXEDWIDTH,  XeCOLOR_RGBA, LPrefs->ButtonNameRGBAp8Color,  XeTEXT, "LMB",  XeCOLOR_RGBA, Xe_ForegroundRGBA8pColor,  XeFONT, XeFontDEFAULT
#define E3dp_MMouseButtonS     XeFONT, XeFontFIXEDWIDTH,  XeCOLOR_RGBA, LPrefs->ButtonNameRGBAp8Color,  XeTEXT, "MMB",  XeCOLOR_RGBA, Xe_ForegroundRGBA8pColor,  XeFONT, XeFontDEFAULT
#define E3dp_RMouseButtonS     XeFONT, XeFontFIXEDWIDTH,  XeCOLOR_RGBA, LPrefs->ButtonNameRGBAp8Color,  XeTEXT, "RMB",  XeCOLOR_RGBA, Xe_ForegroundRGBA8pColor,  XeFONT, XeFontDEFAULT
#define E3dp_RMouseButtonEscS  XeFONT, XeFontFIXEDWIDTH,  XeCOLOR_RGBA, LPrefs->ButtonNameRGBAp8Color,  XeTEXT, "RMB/Esc",  XeCOLOR_RGBA, Xe_ForegroundRGBA8pColor,  XeFONT, XeFontDEFAULT
#define E3dp_NodeS(pName)      XeCOLOR_RGBA, LPrefs->NodeBracketRGBAp8Color,  XeTEXT, "[",  XeCOLOR_RGBA, LPrefs->NodeNameRGBAp8Color,  XeTEXT, pName ? pName : "",  XeCOLOR_RGBA, LPrefs->NodeBracketRGBAp8Color,  XeTEXT,  "]",  XeCOLOR_RGBA, Xe_ForegroundRGBA8pColor
#define E3dp_ObjectS(pName)    XeCOLOR_RGBA, LPrefs->ObjectBracketRGBAp8Color,  XeTEXT, "<",  XeCOLOR_RGBA, LPrefs->ObjectNameRGBAp8Color,  XeTEXT, pName ? pName : "",  XeCOLOR_RGBA, LPrefs->ObjectBracketRGBAp8Color,  XeTEXT, ">",  XeCOLOR_RGBA, Xe_ForegroundRGBA8pColor
#define E3dp_PolyGroupS(pName) XeCOLOR_RGBA, LPrefs->PolyGroupBracketRGBAp8Color,  XeTEXT, "<",  XeCOLOR_RGBA, LPrefs->PolyGroupNameRGBAp8Color,  XeTEXT, pName ? pName : "",  XeCOLOR_RGBA, LPrefs->PolyGroupBracketRGBAp8Color,  XeTEXT, ">",  XeCOLOR_RGBA, Xe_ForegroundRGBA8pColor


typedef struct
{
	E3dNodeComponentCore;

//	uint32_t  SubCameras;
} E3dCameraDependenceNodeComponent;


#define	E3dpPOINTERMODE_STACKDEPTH  16


#define E3dSCHEMATICS_MIN_MAG    0.000001
#define E3dSCHEMATICS_MAX_MAG    0.136


#define E3dpNselectingEnabled  "selectingEnabled"
#define E3dpNdeletingEnabled   "deletingEnabled"

#define  E3dp3DPANEL_FRACTION_BASE  10000

// Maximum displayed grid-count for perspective mode
//
#define E3dpGRID_MAX  1000


enum { E3dp_MSG_ERROR };

// Transformation targets
//
enum
{
	E3dpUPDATE = -2,
	E3dpDO_NOT_CHANGE = -1,
};

enum
{
	E3dpTransformTargetMODEL = 1,
	E3dpTransformTargetSELECTED_POINTS,
	E3dpTransformTargetCENTER,
	E3dpTransformTargetTEXTURE,
	E3dpTransformTargetANIMATION
};


// Selecting modes
//
enum
{
	E3dpSELM_SINGLE,
	E3dpSELM_MULTI
};


#define E3dpSCALE_X      0x001
#define E3dpSCALE_Y      0x002
#define E3dpSCALE_Z      0x004
#define E3dpROTATE_X     0x010
#define E3dpROTATE_Y     0x020
#define E3dpROTATE_Z     0x040
#define E3dpTRANSLATE_X  0x100
#define E3dpTRANSLATE_Y  0x200
#define E3dpTRANSLATE_Z  0x400


//----------------------------------------
// Rendering hardware information
//----------------------------------------
// Vertex-array support
//
enum
{
	E3dVtxArrNONE = 0,
	E3dVtxArrNORMAL,
	E3dVtxArrFAST
};


// Shadow-mapping modes
//
enum
{
	E3dShadowNONE = 0,
	E3dShadowDUAL_TEXTURE,
	E3dShadowDEPTH_MAPPING
};



#ifndef _E3dPanel
#define _E3dPanel
typedef struct E3dPanel_S   E3dPanel;
typedef struct E3dPanel_S*  E3dPanelPtr;
EList_t(E3dPanelPtr);
#endif


typedef struct E3dTransformPanel_S  E3dTransformPanel;

struct E3dPanel_S
{
	EObjectCore(EObject);
	EList_s(, E3dWindowPtr, Windows);

	XeWidget     TopMatrixW, MiddleMatrixW;

	XeMenuRec*   VerticalMenuBar;
	XeWidget     MenuBarScrolledWindowW;

	XeWidget     M3DWindowLayoutW;

	XeWidget     RightPanelW,      // Panel to the right of the 3DWindows. Transform, Selection info, etc.
	             TransformTargetW, TransformModeW;
	XeWidget     ToolBarW, ToolBarBW, ToolBarPW,
	             StatusPanelW, StatusPanelBW, StatusPanelPW,
	             TimePanelW, TimePanelBW, TimePanelPW, TimeExtPanelMatrixW;

	int          GLFontFirstID;

	EBool        WindowRedrawEnabled, VerticalMenuBarOn, TransformPanelOn;

	E3dTransformPanel*  TransformPanel;
};





enum
{
	AM_ANIM,
	AM_MOVIE
};


#define E3dpICONSIZEBASE  26

#define E3dp_SetVMenuBArgs(mMode) do\
{\
	int  lSizeBase = 1;\
	switch(mMode)\
	{\
		case E3dpMBT_ICON:\
			EXeSetArg(XeNLabelType, XeIMAGE);\
			EXeSetArg(XeNMarginSizeX, 0);\
			EXeSetArg(XeNMarginLeft, 0);EXeSetArg(XeNMarginRight, 0);\
			EXeSetArg(XeNArrowSpacing, 0);\
			lSizeBase = E3dp_Prefs.VMenuIconSize;\
		break;\
\
		case E3dpMBT_TEXT:\
			EXeSetArg(XeNLabelType, XeSTRING);\
			EXeSetArg(XeNMarginSizeX, 0);\
			EXeSetArg(XeNMarginLeft, 0);EXeSetArg(XeNMarginRight, 0);\
			EXeSetArg(XeNArrowSpacing, 12);\
			lSizeBase = 32;\
		break;\
\
		case E3dpMBT_ICON_AND_TEXT:\
			EXeSetArg(XeNLabelType, XeIMAGE_STRING_VERTICAL);\
			EXeSetArg(XeNMarginSizeX, 0);\
			EXeSetArg(XeNMarginLeft, 0);EXeSetArg(XeNMarginRight, 0);\
			EXeSetArg(XeNArrowSpacing, 4);\
			lSizeBase = 32;\
		break;\
	}\
\
	EXeSetArg(XeNArrowWidth,   lSizeBase * 6 / E3dpICONSIZEBASE);\
	EXeSetArg(XeNArrowLength,  lSizeBase * 4 / E3dpICONSIZEBASE);\
	EXeSetArg(XeNMarginSizeY,  lSizeBase * 2 / E3dpICONSIZEBASE);\
} while(0)


typedef void  (*E3dCameraFlyToCallback)(const int PID, const float PSecondsLeft);


extern E3dLock  E3dObject_EditLock;
extern E3dLock  E3dNode_EditLock;


//--------------------------------
// From the app
//--------------------------------
extern void        E3dpCB_SaveImageAs(XeWidget PW, EPointer PClientData, EPointer PCallData);


extern XeCursor    E3dp_BusyCursor;
extern XeCursor    E3dp_OrbitCursor, E3dp_DollyCursor, E3dp_RollCursor, E3dp_TrackZoomCursor, E3dp_TrackCursor, E3dp_ZoomCursor;

extern void        E3dp_SetPushButtonArgs(EArg* PArgs, int* PArgCnt);



//--------------------------------
// GL/Scene.c
//--------------------------------
#define E3dGLM_PrintState() E3dGL_PrintState(__FUNCTION__, __FILE__, __LINE__)
extern void            E3dGL_PrintState(const char* PFunction, const char* PFile, const int PLine);
extern E3dHWDrawFlags  E3dGL_AimPointNodeGLDraw(void* P3DWin,  const E3dDrawContext* LDrawContext,  E3dNode* PNode, E3dNodeComponent* PInfo);
extern E3dHWDrawFlags  E3dGL_JointNodeGLDraw(void* P3DWin,  const E3dDrawContext* PDrawContext,  E3dNode* PNode, E3dNodeComponent* PInfo);



typedef int  (*E3dShadowMapUpdateFunc)(E3dWindow* P3DWindow, E3dRenderer* PRenderer, E3dScene* PScene, E3dRLightInstance* PLightInstance);

extern E3dShadowMap*           (*E3dShadowMap_New)(void);
extern void (*E3dShadowMap_DrawFrustum)(E3dShadowMapT* PShadowMap);
extern E3dHWShadowMapSettings*  E3dShadowMap_Settings;
extern E3dShadowMapUpdateFunc  E3dShadowMap_Update;


//--------------------------------
// Panel/GL/FullWindowEffects.c
//--------------------------------
// Information used to generate a full-window pass fragment program
//
typedef struct
{
	int       AAMult;    // Anti-aliasing multiplier (e.g. 2 = 2x2 supersampling)
	EBool     UseGain, UseAdaptiveExposure, UseGamma,
	          UseGain1;  // Gain for 2nd texture (Texture1)
	EBool     Clamp;
	int       NumOfInputs;
	uint16_t  ReorientDstImage[2];
	float     LensCorrection, LensCorrectionR, LensCorrectionB;
	uint8_t   StereoMode;
} E3dFWCodeGenParams;

extern char*  E3dGL_FWGenerateFragmentProgram(const E3dFWCodeGenParams* PCodeGenParams, const int PLanguage);

extern int    E3dGL_Accumulate(E3dGPUContext* PGPUContext, EpGPUFrameBuffer* PFBO0, EpGPUFrameBuffer* PFBO1,  const EIndex PX, const EIndex PY,  const EIndex PSizeX, const EIndex PSizeY);

extern void   EpGPUFrameBuffer_ToWindow(EpGPUFrameBuffer* PFBO, E3dWindow* P3DWindow, E3dRenderer* PRenderer, const EpExposure* PExposure, const E3dBloom* PBloom, const int PAAMult, const uint16_t PSrcReorient);


#ifdef EpGL_HAS_FBO
extern void   E3dGL_HDR_WindowFinishDrawing(E3dWindow* P3DWindow, E3dRenderer* PRenderer, E3dScene* PScene,  EpGPUFrameBuffer* PFBO, EpGPUFrameBuffer* PDstFBO, const int PAAMult, const uint16_t PSrcReorient);
#endif



//--------------------------------
// GL/Renderers.c
//--------------------------------
extern void   E3dGL_MainShadowMapInit(E3dScene* PScene, E3dWindow* P3DWindow, E3dRenderer* PRenderer, E3dRLightInstance* PLightInstance);


//--------------------------------
// GL/Window.c
//--------------------------------
extern void   E3dWindow_DrawAreas(E3dpWindow* P3DWindow);



//--------------------------------
// Panel/Camera.c
//--------------------------------
extern E3dNodeComponentClass*  E3dCameraDependenceNodeComponent_class;

extern E3dModel*   E3d_SceneAddCameraModels(E3dScene* PScene,  E3dCamera* PCamera, E3dModel* PCameraModel,  E3dModel** PAimModelRet, const char* PCameraName);

extern EBool       E3dp_CameraControlButtonPress(E3dWindow* P3DWindow, E3dScene* PScene,  const int PPtrX, const int PPtrY,  const int PButton, const unsigned int PModifiers);
extern EBool       E3dp_CameraControlButtonRelease(E3dWindow* P3DWindow, E3dScene* PScene,  const int PPtrX, const int PPtrY,  const int PButton, const unsigned int PModifiers);
extern int         E3dp_CameraControlPointerMove(E3dWindow* P3DWindow, E3dScene* PScene,  const int PPtrX, const int PPtrY, const unsigned int PState);

extern int         E3dp_CameraFlyTo(E3dWindow** P3DWindows, const EIndex PNumOf3DWindows,  E3dScene* PScene,  const float PDuration, const float PTimeStep, E3dCameraFlyToCallback PCallback);
extern float       E3dScene_FrameCameras(E3dScene* PScene, E3dWindow* P3DWindow, E3dWindow*** LFlyToWindowsP, EIndex* LNumOfFlyToWindowsP,  E3dBBox* PAllBBox,  unsigned int PWhatToInclude);

extern E3dCamera*  E3d_IsActiveCameraNodeOnWindow(const E3dNode* PNode, const E3dWindow* P3DWindow);


EList(extern, E3dShadowMap*, E3d_ShadowMaps);
extern EBool          E3dp_RedrawShadowMap;

extern void           E3dp_DisplayExit(void);
extern void           E3dGL_GLSLFree(void);


//--------------------------------
// Panel/MenuBar.c
//--------------------------------
extern void    E3dp_SetSelectionMode(int PMode);
extern void    E3dp_MenuBarOnOff(E3dPanel* P3DPanel, const EBool PSwitch);

#define E3dUIMAX_VERTEX_ATTRIBUTE_COMPONENTS  4  // Float32, Float32_2, Float32_3, Float32_4 for now

//--------------------------------
// Panel/Panel.c
//--------------------------------
typedef struct
{
	XeWidget  SemanticW, NameW,  ShowComponentsMatrixW, ShowWs[E3dUIMAX_VERTEX_ATTRIBUTE_COMPONENTS], ShowAllW,  RemoveW;
} E3dVertexAttributeGUI;

EList_t(E3dVertexAttributeGUI);  // E3dVertexAttributeGUIList


#define E3dVertexGeometryGUICore\
	XeWidget                   VertexAttributesMatrixW,\
	                           AddVertexAttributeW,\
	                           AddVertexAttributeTypeW,  AddVertexAttributeTypeFloatW, AddVertexAttributeTypeFloat2W, AddVertexAttributeTypeFloat3W, AddVertexAttributeTypeFloat4W, AddVertexAttributeTypeUInt8_4W,\
	                           AddVertexAttributeSemanticW,  AddVertexAttributeSemanticNoneW, AddVertexAttributeSemanticRGBAW, AddVertexAttributeSemanticRGBW,\
	                           AddVertexAttributeTypeSelectorW, AddVertexAttributeOkW, AddVertexAttributeCancelW, VertexAttributePaintW;\
	uint16_t                   NewAttributeType;char*  NewAttributeSemantic;\
	EBool                      AddingVertexAttribute;\
	E3dVertexAttributeGUIList  VertexAttributesGUI

typedef struct
{
	E3dVertexGeometryGUICore;
} E3dVertexGeometryGUI;


extern void     E3dVertexAttributesGUI_Update(const EResourceList* PAttributes, const EIndex PVAStartIndex, XeWidget PParentW, E3dVertexAttributeGUIList* PVertexAttributesGUI,  XeCallbackFunc PCallback, EPointer PCallbackClientData);
extern void     E3dVertexAttributeGUI_Clear(E3dVertexAttributeGUIList* PVertexAttributeGUIs, const EResourceList* PVertexAttributes, const EIndex PVAStartIndex, const EResource* PVAttr, const uint16_t PVisualizationType);
extern int      E3dVertexAttributeGUI_Callback(XeWidget PW, EPointer PClientData, EPointer PCallData, XeCallbackFunc PCallback,  EObject* PObject, const EResourceList* PVertexAttributes, const EIndex PVAStartIndex,  XeWidget PMatrixW, E3dVertexAttributeGUIList* PVertexAttributeGUIs, E3dVertexAttributeVisualizationListA* PVis);

extern const EObjectClass  E3dPanel_class[];

extern XeFontSize*  E3dp_SchematicsFontSize;

extern int      (*E3dp_TextureGUIUpdate)(E3dMaterial* PMaterial, E3d2DTexture* PTexture, EChangeFlags PChangedFlags);
extern int      (*E3dRendererSet_RenderFramesFunc)(E3dRendererSet* PRendererSet, E3dScene* PScene, E3dCamera* PCamera, E3dModel* PCameraModel);

extern int      E3dp_SelectionMode;

extern EBool    E3dp_Exiting;
extern E3dDrawContext  E3dp_NormalDrawContext;

extern E3dpWindow*     E3dp_Renderer3DWindow;

extern void            E3dp_GUIUpdateForNewScene(void);

extern void            E3dp_AddDrawStartCallback(EChangeFlags PEventMask, ECallbackFunc PCallbackProc, EPointer PClientData);
extern EIndex          E3dp_RemoveDrawStartCallback(ECallbackFunc PCallbackFunc, EPointer PClientData);

extern void            E3dp_AddDrawEndCallback(EChangeFlags PEventMask, ECallbackFunc PCallbackFunc, EPointer PClientData);
extern EIndex          E3dp_RemoveDrawEndCallback(ECallbackFunc PCallbackFunc, EPointer PClientData);


//--------------------------------
// Panel/PanelLayout.c
//--------------------------------
extern void    E3dWindows_Layout(E3dPanel* P3DPanel);
extern void    E3dWindows_PanelSetAttachments(E3dPanel* P3DPanel);
extern void    E3dp_MenuBarSetPanelAttachments(E3dPanel* P3DPanel);


//--------------------------------
// Panel/Renderer.c
//--------------------------------
extern const ETime      E3d_MaxInteractiveFrameMilliseconds;

extern void             E3dRenderer_GUIFromResources(ECoreObject* PObject, XeInfoPanel* PPanel, void* PDrawer, const int PAction);
extern int              E3dRendererSet_RenderFrame(E3dRendererSet* PRendererSet, E3dScene* PScene);

extern E3dRendererSet*  E3dp_RendererSet;
extern EIndex           E3d_BuiltInRendererClasses_Count;

extern E3dGPUContext*   E3dGL_Context;
extern E3dGPUContext*   E3dGL_ContextMSAA4;
extern E3dGPUContext*   E3dGL_ContextStereo;

#ifdef EpGL_HAS_FBO
	extern EpGPUFrameBuffer*  E3dGL_SharedFBO0;extern E3dWindow*  E3dGL_SharedFBO0Last3DWindow;
	extern EpGPUFrameBuffer*  E3dGL_SharedFBO1;extern E3dWindow*  E3dGL_SharedFBO1Last3DWindow;
#endif

EList_s(extern, E3dPanelPtr, E3dp_Panels);

extern XeWidget      E3dp_RendererCanvasDialogW;
extern XeWidget      E3dp_RendererCanvasW;


// Default plugin icons, linked to ToolBar.a
//
extern EpImagePtr  _Image_Plugin, _Image_Plugin_Active, _Image_Plugin_Armed;

extern EpImagePtr  _Image_Key, _Image_Key_Active, _Image_Key_Armed;

extern EUndoStack  E3dp_UndoStack;

extern XeWidget      E3dp_TopShellW;

#define	E3dMAX_CLASS_RESOURCES  256

extern void          E3dScene_Read2DTextures(E3dScene* PScene, const EBool PForceReread, const EBool PAnimatedOnly);

extern void          E3dpCB_RenderAbort(EPointer PClientData);

#define E3dpOPENGL_CANVAS  1

extern int     (*E3dp_RenderWindowPopupFunc)(E3dpWindow* P3DWindow);
extern int     E3dp_RenderWindowPopup(E3dpWindow* P3DWindow);

extern const ETime  E3dRenderer_ThreadsLazyFreeIncativeMilliseconds;

extern int     E3dpWindow_RenderFrame(E3dpWindow* P3DWindow, E3dScene* PScene,  E3dCamera* PCamera, E3dModel* PCameraModel,  const EChangeFlags PSceneChangeFlags, const EChangeFlags PRendererChangeFlags);
extern void    E3dWindow_AddRendererProgressbarUpdateTimer(E3dWindow* P3DWindow);

extern int     E3dWindow_RayTrace(E3dWindow* P3DWindow, E3dRayTracer* PRenderer, E3dScene* PScene, E3dTraceRayFunc PTraceRayFunc);

extern void    E3dPanel_RedrawWindows(E3dPanel* P3DPanel, const E3dViewModeFlags PViewModes, const E3dDisplayFlags PDisplayMode, const EChangeFlags PSceneChangedFlags, const EChangeFlags PRendererChangedFlags, E3dScene* PScene);

extern XeVisual*     E3dGL_Visual;
extern XeVisual*     E3dGL_VisualMSAA4;
extern XeVisual*     E3dGL_VisualStereo;

extern E3dPanel*     E3dPanel_New(const char* PName);
extern E3dPanel*     E3dPanel_Create(const char* PName, E3dScene* PScene, XeWidget PTopShellW, XeWidget PParentW,  const int PCols, const int PRows,  void (*PExitFunction)(void));

extern void          E3dp_Exit(void);

extern void          E3dpUndoStack_AddOps(EOps* POps, const char* PName);
extern void          E3dpUndoStack_AddOperator(EOperator* POperator, const char* PName);
extern EChangeFlags  E3dp_RunOperators(EOps* POps, const int PAction);
extern void          E3dp_Undo(void);
extern void          E3dp_Redo(void);


//--------------------------------
// Panel/ToolBar.c
//--------------------------------
extern XeWidget  E3dTool_FolderWs[];extern int  E3dTool_FolderWs_Count;

extern XeWidget  E3dTool_LightMatrixW,
                 E3dTool_CreateMatrixW,
                 E3dTool_SplineMatrixW,
                 E3dTool_SurfaceMatrixW,
                 E3dTool_GeometryMatrixW,
                 E3dTool_CloneMatrixW,
                 E3dTool_TransformMatrixW,
                 E3dTool_HierarchyMatrixW,
                 E3dTool_AnimationMatrixW;

extern void    E3dp_ToolBarOnOff(E3dPanel* P3DPanel, const EBool PSwitch);
extern void    E3dp_ToolBarExit(void);


//--------------------------------
// Panel/TransformPanel.c
//--------------------------------
extern int        E3dp_SelectionMode;

extern void       E3dp_TransformsInit(const char* PDataPath);
extern void       E3dp_TransformsExit(void);
extern void       E3dp_TransformPanelExit(void);

extern void       E3dTransformPanel_Free(E3dTransformPanel* PTransformPanel);

typedef struct
{
	E3dMatrix     WorldToLocalMatrix, LocalToWorldMatrix;

	E3dGeometry*  ActiveGeometry;
	E3dSpline*    ActiveSpline;               // If ActiveGeometry is a Face, this will point to the active contour
	E3dVertex*    ActiveVertex;
	E3dSplineCV*  ActiveSplineCV;
	int           ActiveSubCV;                // Which component of the Bezier CV to move
	uint32_t      OldPointFlags;

	E3dCoord3     ActivePointOriginalPos, ActivePointMoveOffset;

	E3dCoord4     Plane;    // The coefficients of the plane used to move a point
} E3dpPointMove;

extern EIndex2  E3dp_BasePtr;

extern E3dpPointMove  E3dp_PointMove;


EList(extern, E3dShapeSnapshot*, E3dp_ShapeSnapshots);

extern EChangeFlags  E3dp_InteractiveTransformFree(void);

extern EOperator*    E3dp_MovePoint(E3dWindow* P3DWindow,  const int PPtrX, const int PPtrY,  unsigned int PModifierState);
extern EChangeFlags  E3dp_StopMovePoint(void);



extern E3dLight*     E3dp_SceneAddDefaultLight(E3dScene* PScene);


// State object for Interactive transforms, custom manipulation action etc.
//
#define E3dInteractionCore\
	EObjectCore(EObject);\
	E3dManipulator*  ActiveManipulator;\
	EOperator*       CurrentOperator;\
	EBool            PushOperatorsForUndo

typedef struct
{
	E3dInteractionCore;
} E3dInteraction;

extern EObjectClass  E3dInteraction_class[];
extern EObjectClass  E3dTransformGlobals3D_class[];


typedef struct
{
	E3dInteractionCore;

// Nodes being transformed
//
	EListA_s(, E3dNodePtr, TransformedNodes);

// Root Nodes of hierarchies that have Nodes being transformed
//
	EListA_s(, E3dNodePtr, TransformedBranchRoots);

	E3dMatrix  ManipulatorMatrix;  // When transforming points, the Manipulator will be transformed by this Matrix, in addition to the Node's LocalToWorldMatrix, because the latter will not be changing for point transforms.
} E3dTransformGlobals3D;

extern E3dInteraction*  E3dp_InteractionObject3D;

extern void          E3dp_PointMoveInit(E3dWindow* P3DWindow, E3dInteraction* PGlobals,  const int PPtrX, const int PPtrY,  const E3dCoordinate PX, const E3dCoordinate PY, const E3dCoordinate PZ,  const EBool PStoreForUndo);

extern EBool         E3dp_PointMoveInit2D(E3dWindow* P3DWindow, E3dInteraction* PTransformGlobals,  const int PPtrX, const int PPtrY,  const E3dCoordinate PX, const E3dCoordinate PY, const E3dCoordinate PZ,  const EBool PStoreForUndo);
extern EBool         E3dp_PointMoveInitPlane(E3dWindow* P3DWindow, E3dInteraction* PTransformGlobals, int PPtrX, int PPtrY, E3dCoordinate PX, E3dCoordinate PY, E3dCoordinate PZ, EBool PStoreForUndo);

extern void          E3dp_InitSplineCVMove(E3dSpline* PSpline, E3dSplineCV* PCV, const EIndex PPointIndex, const int PItemType, E3dMatrix PLocalToWorldMatrix, E3dMatrix PWorldToLocalMatrix, E3dCoord3* LPosition);

extern void          E3dp_TransformPointsSetMatrices(void);

extern void          _E3dp_Load3DManipulators(const char* PDataPath);

EList(extern, E3dInteraction*, E3dp_InteractionObjects);


#define E3dTrPanelTRANSFORM_VALUESTATES  0x01
#define E3dTrPanelOBJECT_LIST            0x02
#define E3dTrPanelALL                    0x03

#define E3dTransformTargetStackMAX_DEPTH  2

struct E3dTransformPanel_S
{
	int       TransformTargetStack[E3dTransformTargetStackMAX_DEPTH];        // The current transform target
	int       TransformTargetStackPtr;
	int       TransformMode;
	uint16_t  ScaleFlags, RotateFlags, TranslateFlags;

	XeWidget  ScaleXW, ScaleYW, ScaleZW,
	          RotateXW, RotateYW, RotateZW,
	          TranslateXW, TranslateYW, TranslateZW,
	          ScaleXBW, ScaleYBW, ScaleZBW,
	          RotateXBW, RotateYBW, RotateZBW, 
	          TranslateXBW, TranslateYBW, TranslateZBW,
	          FindW;
	XeWidget  TTB_ModelW, TTB_PointsW, TTB_CenterW, TTB_TextureW, TTB_AnimW;

	XeWidget  FoundObjectsListW;    // Names of selected Objects

	XeDrawer  TransformDrawer, FindDrawer;
	uint32_t  Transforming,                              // Scaling, Rotating, Translating etc. selected Models (keep buffer of rendered unselected models, grid, axis...)
	          TransformObjectsSensitive, FindDrawerObjectListNeedsUpdate;
	EListA_s(, EObjectPtr, FoundObjects);
};


extern E3dCoord3   E3dp_Scaling;

extern const char  E3dStrMODEL[];
extern const char  E3dStrSELECTED_POINTS[];
extern const char  E3dStrCENTER[];
extern const char  E3dStrTEXTURE[];
extern const char  E3dStrANIMATION_CURVE[];
extern const char  E3dStr[];

extern void    E3dTransformPanel_SetTransformingMessage(E3dTransformPanel* PPanel);
extern void    E3dTransformPanel_Update(E3dTransformPanel* PPanel, const uint8_t PScaleFlags, const uint8_t PRotateFlags, const uint8_t PTranslateFlags,  const int PTransformTarget,  const uint16_t PUpdateFlags);
extern void    E3dTransformPanel_UpdateScalingUI(E3dTransformPanel* PPanel,  const E3dCoordinate PX, const E3dCoordinate PY, const E3dCoordinate PZ,  const uint16_t PFlags);
extern void    E3dTransformPanel_UpdateRotationUI(E3dTransformPanel* PPanel,  const E3dCoordinate PX, const E3dCoordinate PY, const E3dCoordinate PZ,  const uint16_t PFlags);
extern void    E3dTransformPanel_UpdateTranslationUI(E3dTransformPanel* PPanel,  const E3dCoordinate PX, const E3dCoordinate PY, const E3dCoordinate PZ,  const uint16_t PFlags);

extern void    E3dPanel_TransformPanelOnOff(E3dPanel* P3DPanel, const EBool PSwitch);

extern void    E3dp_ModelRemoveHrcFromScene(E3dModel* PRootModel);

extern void    E3dManipulator_FreeContents(E3dManipulator* PThis);

extern EChangeFlags  E3dp_ScaleNodes(E3dInteraction* PGlobals, E3dNodePtrListA* PTransformedNodes,  const E3dCoordinate PX, const E3dCoordinate PY, const E3dCoordinate PZ,  const unsigned int PTransformAxes, const EBool PRelative, const int PTarget, EOperator* POperator);
extern EChangeFlags  E3dp_ScalePoints(E3dInteraction* PGlobals,  E3dShapeSnapshot** PShapeSnapshots, const EIndex PNShapeSnapshots,  const E3dCoord3* PScaling, const unsigned int PTransformAxes, const EBool PPushForUndo);

extern EChangeFlags  E3dp_RotateNodes(E3dInteraction* PGlobals, E3dNodePtrListA* PTransformedNodes,  const E3dEulerRotation* LEulerRotation, const E3dRotation* LRotation,  const unsigned int LTransformAxes, const EBool PRelative, const int PTarget, EOperator* POperator);
extern EChangeFlags  E3dp_RotatePoints(E3dInteraction* PGlobals, E3dMatrix PMatrix, EBool PPushForUndo);

extern EChangeFlags  E3dp_TranslateNodes(E3dInteraction* PGlobals,  E3dNodePtrListA* PTransformedNodes,  const E3dCoordinate PX, const E3dCoordinate PY, const E3dCoordinate PZ,  const unsigned int PTransformAxes, const EBool PRelative, const int PTarget, E3dGridSettings* PGridSettings, EOperator* POperator);
extern EChangeFlags  E3dp_TranslatePoints(E3dInteraction* PGlobals, const E3dCoord3* PDelta, unsigned int PTranslateAxes, const EBool PPushForUndo);

extern uint16_t      E3dWindow_GetTranslateAxes(E3dWindow* P3DWindow, E3dTransformPanel* PPanel, const uint16_t PTranslateFlags, unsigned int PButtonState);

extern E3dManipulator  E3dp_RotateManipulator;
extern E3dManipulator  E3dp_TranslateManipulator;

//----------------------------------------
// Panel/GL/Display.c
//----------------------------------------
extern void    E3dGL_ViewDrawInit(E3dWindow* P3DWindow);
extern void    E3dGL_RenderWindowRedraw(E3dWindow* P3DWindow, E3dRenderer* PRenderer, E3dScene* PScene,  const EBool PSwapBuffers);


//----------------------------------------
// GL/Renderers.c
//----------------------------------------
extern void  E3dWindow_DrawExtras(E3dWindow* P3DWindow, E3dRenderer* PRenderer, E3dDrawContext* PDrawContext,  E3dScene* PScene);



//----------------------------------------
// Application
//----------------------------------------
//--------------------------------
// gui.c
//--------------------------------
extern int     E3dp_ScaleWidth, E3dp_SliderLength, E3dp_SliderWidth;
extern void    E3dp_AddBuiltInFunctionsGUI(void);
extern void    E3dp_RemoveBuiltInFunctionsGUI(void);


//--------------------------------
// main.c
//--------------------------------
extern void    App_LoadSettings(const char* PName, EResource* PResources, void* PStructAddress);
extern void    App_SaveSettings(const char* PName, EResource* PResources, void* PStructAddress);


extern void    E3dp_IOModuleShowGUI(void* PIOModule, EIOModuleGUI* PIOModules, const EIndex PN, XeWidget PFormatsOptionMenuW);

EListA_s(extern, ECallbackRec, _E3dp_DrawStartCallbacks);
EListA_s(extern, ECallbackRec, _E3dp_DrawEndCallbacks);


#if defined (__cplusplus) && (!(defined (__CPLUSLIBS)))
}	// Close scope of 'extern "C"' declaration
#endif

#endif	// _E3D_Panel_h
