//================================================================
// 3DPanel mode stack header file
//
// AUTHOR:  Gabor Nagy
// DATE:    2024-May-23 01:23:37
//
// Copyright (C) 1996-2026 By Gabor Nagy. All rights reserved.
//================================================================
#ifndef _E3D_ModeStack_h
#define _E3D_ModeStack_h

#include <Xe/Xe.h>

#include <E3D/UI/Window.h>

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


// Pointer mode stacking
//
typedef struct E3dPointerModeClass_S  E3dPointerModeClass;
typedef struct E3dPointerMode_S       E3dPointerMode;
typedef struct E3dPointerMode_S*      E3dPointerModePtr;

struct E3dPointerModeClass_S
{
	EBaseClassCore(E3dPointerMode);

	EBool  (*IsChildModeAllowed)(const E3dPointerMode* PMode, const E3dPointerMode* PChildMode);
	XeString  (*GetMessage)(E3dPointerMode* PMode);

	E3dButtonEventFunc  ButtonEventFunc;
	E3dPointerMoveFunc  PointerMoveFunc;
	E3dKeyEventFunc     KeyEventFunc;
};
EListA_t(E3dPointerModePtr);

struct E3dPointerMode_S
{
	EObjectCore(E3dPointerMode);

	XeString  Message;
	uint32_t  MessageStatic : 1;     // Message doesn't have color change codes etc., so it doesn't have to be freed / rebuilt e.g. after Light / Dark UI mode changes

	E3dID     PMID;                  // Unique ID returned by E3dp_PushPointerMode when this PointerMode was pushed onto the stack
	E3dID     MessageID;             // Unique ID returned by E3dp_PushCompoundMessage when this PointerMode was pushed onto the stack
};


typedef struct E3dPointerModeEntry_S  E3dPointerModeEntry;

// PointerMode stack mode
//
struct E3dPointerModeEntry_S
{
	E3dID            PMID;
	E3dPointerMode*  Mode;    // Pointer to E3dPointerMode struct
};


extern E3dPointerMode*  E3dpPointerModeORBIT_STANDBY;
extern E3dPointerMode*  E3dpPointerModeORBIT_STANDBY_ORTHO;
extern E3dPointerMode*  E3dpPointerModeORBIT;

extern E3dPointerMode*  E3dpPointerModeZ_SCROLL_ZOOM_STANDBY;
extern E3dPointerMode*  E3dpPointerModeZ_SCROLL_ZOOM_SCROLL;
extern E3dPointerMode*  E3dpPointerModeZ_SCROLL_ZOOM_ZOOM;
extern E3dPointerMode*  E3dpPointerModeZ_SCROLL_ZOOM_SELECT_ZOOM_REGION;

extern E3dPointerMode*  E3dpPointerModeZ_TRACK_ZOOM_STANDBY;
extern E3dPointerMode*  E3dpPointerModeZ_TRACK_ZOOM_TRACK;
extern E3dPointerMode*  E3dpPointerModeZ_TRACK_ZOOM_ZOOM;

extern E3dPointerMode*  E3dpPointerModeDOLLY_STANDBY;
extern E3dPointerMode*  E3dpPointerModeDOLLY_STANDBY_ORTHO;
extern E3dPointerMode*  E3dpPointerModeDOLLY;

extern E3dPointerMode*  E3dpPointerModeBANK_STANDBY;
extern E3dPointerMode*  E3dpPointerModeBANK_STANDBY_ORTHO;
extern E3dPointerMode*  E3dpPointerModeBANK;

extern E3dPointerMode*  E3dpPointerModeCTRL_SCROLL_ZOOM_STANDBY;
extern E3dPointerMode*  E3dpPointerModeCTRL_SCROLL_ZOOM_SCROLL;
extern E3dPointerMode*  E3dpPointerModeCTRL_SCROLL_ZOOM_ZOOM;
extern E3dPointerMode*  E3dpPointerModeCTRL_SCROLL_ZOOM_SELECT_ZOOM_REGION;

extern E3dPointerMode*  E3dpPointerModeCTRL_ORBIT_DOLLY_TRACK_STANDBY;
extern E3dPointerMode*  E3dpPointerModeCTRL_ORBIT_DOLLY_TRACK_ORBIT;
extern E3dPointerMode*  E3dpPointerModeCTRL_ORBIT_DOLLY_TRACK_DOLLY;
extern E3dPointerMode*  E3dpPointerModeCTRL_ORBIT_DOLLY_TRACK_TRACK;

extern E3dPointerMode*  E3dpPointerModeALT_ORBIT_TRACK_DOLLY_STANDBY;
extern E3dPointerMode*  E3dpPointerModeALT_ORBIT_TRACK_DOLLY_ORBIT;
extern E3dPointerMode*  E3dpPointerModeALT_ORBIT_TRACK_DOLLY_TRACK;
extern E3dPointerMode*  E3dpPointerModeALT_ORBIT_TRACK_DOLLY_DOLLY;

extern E3dPointerMode*  E3dpPointerModeALT_NONE_TRACK_ZOOM_STANDBY;
extern E3dPointerMode*  E3dpPointerModeALT_NONE_TRACK_ZOOM_TRACK;
extern E3dPointerMode*  E3dpPointerModeALT_NONE_SCROLL_ZOOM_SCROLL;
extern E3dPointerMode*  E3dpPointerModeALT_NONE_SCROLL_ZOOM_ZOOM;

extern E3dPointerMode*  E3dpPointerModeDELETING;

extern E3dPointerMode*  E3dpPointerModeSELECT_NODE;
extern E3dPointerMode*  E3dpPointerModeSELECT_NODE_NODE;
extern E3dPointerMode*  E3dpPointerModeSELECT_NODE_BRANCH;
extern E3dPointerMode*  E3dpPointerModeSELECT_NODE_TREE;

extern E3dPointerMode*  E3dpPointerModeSELECT_OBJECT;
extern E3dPointerMode*  E3dpPointerModeSELECT_POLYGON;
extern E3dPointerMode*  E3dpPointerModeSELECT_EDGE;
extern E3dPointerMode*  E3dpPointerModeSELECT_VERTEX;
extern E3dPointerMode*  E3dpPointerModeSELECT_OBJECT_COMPONENT_MULTI;

extern E3dPointerMode*  E3dpPointerModeSELECT_POINTS_STANDBY;
extern E3dPointerMode*  E3dpPointerModeSELECT_POINTS_SELECT;
extern E3dPointerMode*  E3dpPointerModeSELECT_POINTS_UNSELECT;
extern E3dPointerMode*  E3dpPointerModeSELECT_POINTS_INVERT;

extern E3dPointerMode*  E3dpPointerModePICK;

extern E3dPointerMode*  E3dpPointerModeMOVE_POINT_STANDBY;
extern E3dPointerMode*  E3dpPointerModeMOVE_POINT;

extern E3dPointerMode*  E3dpPointerModeRECTANGLE_SELECT;

extern E3dPointerModeClass   E3dPointerMode_class[];

extern int                   E3dp_ModeChangeVerbosity;

extern E3dID                 E3dp_PushPointerMode(E3dPointerMode* PMode, XeString PMessage);
extern EBool                 E3dp_PopPointerMode(E3dPointerMode* PMode);
extern void                  E3dp_ResetPointerModeStack(void);
extern void                  E3dp_PointerModesFree(void);
extern void                  E3dPointerModes_FreeMessages(const EBool PFreeStatic);

extern EBool                 E3dPointerMode_IsCameraControl(const E3dPointerMode* PMode);

extern E3dPointerModeEntry*  E3dPointerMode_GetCurrentEntry(void);
extern E3dPointerMode*       E3dPointerMode_GetCurrent(void);
extern void                  E3dp_ResetWorkModes(void);


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

#endif	// _E3D_ModeStack_h
