//================================================================
// 2DPanel library
//
// 2DWindow header file
//
// AUTHOR:  Gabor Nagy
// DATE:    2026-Jul-12 14:02:09
//
// Copyright (C) 1996-2026 By Gabor Nagy. All rights reserved.
//================================================================
#ifndef _E2DWindow_h
#define _E2DWindow_h


#ifdef EX11

#ifndef USEOpenGL
#define USEOpenGL
#endif

#ifndef sgi
	#define GL_GLEXT_PROTOTYPES  1
#endif

#ifdef __APPLE__
	#include <OpenGL/gl.h>
#else
	#include <GL/gl.h>
#endif	// __APPLE__

#include <GL/glx.h>

#endif // EX11


#include <Xe/GLDraw.h>
#include <Xe/DropDownPanel.h>
#include <Xe/FSBox.h>

#include <Color/Panel.h>
#include <Image/Picture.h>


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


//--------------------------------
// AREAS
//--------------------------------

typedef int	EpAreaID;            // For area selection

#define EpMAX_NUM_OF_AREAS  256  // Max number of sub-areas displayable on a window


enum
{
	EpAREA_RECTANGULAR,
	EpAREA_FREEHAND,
	EpAREA_SPLINE_CONTOUR
};


// Area states
//
#define EpAREA_HIDDEN   0x01
#define EpAREA_VISIBLE  0x02
#define EpAREA_ACTIVE   0x04
#define EpAREA_ALL      (EpAREA_HIDDEN|EpAREA_VISIBLE|EpAREA_ACTIVE)

typedef struct EpWindow_S   EpWindow;
typedef struct EpWindow_S*  EpWindowPtr;
EListA_t(EpWindowPtr);

typedef void  (*EpAreaCallbackFunc)(EpWindow* P3DWindow, const EpAreaID PAreaID, const int PX, const int PY, const int PSizeX, const int PSizeY, EPointer PClientData);

//----------------------------------------------------------------------------------------
// A sub-area to indicate a cropping area, a subimage, a brush to pick up etc.
//----------------------------------------------------------------------------------------
typedef struct
{
	int                 Shape;             // Shape (see the enum above)
	int                 State;
	EpAreaID            ID;                // Unique ID of the Area
	EpPicture*          Picture;           // The Picture the Area is relative to
	EIndex2             IPosition, ISize;  // Picture-relative, hardware and zoom-factor independent coordinates
	EIndex2             Position;          // Window-relative, hardware-dependent coordinates
	EIndex2             Size;              // Depends on zoom-factor, unlike ISize!
	EpAreaCallbackFunc  Callback;          // Address of callback-function (for change detection)
	EPointer            ClientData;        // Clientdata for callback-function
} EpArea;




// What to show on the InfoPanel
//
#define EpInfoPanelSIZE           0x01
#define EpInfoPanelCURSOR         0x02
#define EpInfoPanelCOLOR_VALUES   0x04
#define EpInfoPanelZOOM           0x08
#define EpInfoPanelCHANNELS       0x10
#define EpInfoPanelUNDODISPLAY    0x20
#define EpInfoPanelCUSTOMLABEL    0x40
#define EpInfoPanelMESSAGE_LABEL  0x80
#define EpInfoPanelALL            0xFF

#define EpWindowFlagOUTER_FRAME       0x01
#define EpWindowFlagINNER_FRAME       0x02
#define EpWindowFlagINFOPANEL_CREATE  0x04
#define EpWindowFlagINFOPANEL_ON      0x08
#define EpWindowFlagZOOMPANEL_CREATE  0x10
#define EpWindowFlagZOOMPANEL_ON      0x20
#define EpWindowFlagALL               0x3F

//------------------------------------------------
// Window callback reasons
//------------------------------------------------
enum
{
	EpCR_PICTURE_MOVED = 0,  // Picture was scrolled
	EpCR_ZOOM_CHANGED        // Zoom was changed
};


//------------------------
// Sub-image
//------------------------
typedef struct
{
	char*   Name;
	EIndex  X, Y;          // Window-relative coordinates
	EIndex  SizeX, SizeY;
} EpSubImage;


#define EpPICTYPE_NONE            0
#define EpPICTYPE_MONOCHROME   0x01
#define EpPICTYPE_GRAYSCALE    0x02
#define EpPICTYPE_COLORINDEX   0x04
#define EpPICTYPE_DIRECTCOLOR  0x08

#define EpNONE		-1


#define EpWIDGET_NONE           0  // DrawWidget types
#define EpWIDGET_COLORINDEX  0x01
#define EpWIDGET_12BIT       0x02
#define EpWIDGET_15BIT       0x08
#define EpWIDGET_16BIT       0x10
#define EpWIDGET_24BIT       0x20
#define EpWIDGET_ALL         0x3F


//--------------------------------
// Window Modes
//--------------------------------
enum { EpWM_VIEW = 0,EpWM_PAINT };

// Window display types (EpWDT_COLORINDEX and EpWDT_TRUECOLOR are hardware independent values)
//
enum
{
	EpWDT_NONE = 0,
	EpWDT_COLORINDEX,
	EpWDT_TRUECOLOR,
	EpWDT_8BIT_COLORINDEX,
	EpWDT_12BIT_RGB,EpWDT_12BIT_RGB_DITHERED,
	EpWDT_15BIT_RGB,EpWDT_15BIT_RGB_DITHERED,
	EpWDT_16BIT_RGB,EpWDT_16BIT_RGB_DITHERED,
	EpWDT_24BIT_RGB
};


enum
{
	EpPTR_NORMAL = 0,
	EpPTR_ZOOM,
	EpPTR_DRAW,
	EpPTR_CLONE,
	EpPTR_PICK_COLOR,
	EpPTR_AREA_TOP_LEFT,EpPTR_AREA_TOP_RIGHT,EpPTR_AREA_BOTTOM_RIGHT,EpPTR_AREA_BOTTOM_LEFT,
	EpPTR_AREA_LEFT,EpPTR_AREA_RIGHT,EpPTR_AREA_TOP,EpPTR_AREA_BOTTOM,EpPTR_AREA_MOVE
};

typedef struct
{
	XeInfoPanelCore;

	EpWindow*  Window;
	XeWidget   DialogW,
	           TimeLabelW, SoftwareLabelW, CommentLabelW;
} EpInfoDialog;

typedef struct
{
	XeWidget      TopMatrixW,
	              PointerPosW, PixelValueW,
	              SizeW,
	              ZoomLabelW, HDRSettingsBW,
	              ShowIW, ShowRW, ShowGW, ShowBW, ShowAW, ShowPreMultAW, ShowAlphaIsTransparencyW,
	              SubImagesOptionMenuW, SubImagesOptionMenuPaneW,
	              UndoBufferDisplayW, CustomLabelW, NameLabelW;

	XeProgressIndicator  ProgressIndicator;

	EList(, XeWidget, SubImageOptionMenuButtonWs);

	EBool         Visible;
	uint16_t      Flags;      // EpInfoPanelSIZE, EpInfoPanelCOLOR_VALUES etc
	uint32_t      PixelValuesWAllowShrinking : 1;
	XeIntervalId  MessageTimerID;

	EpInfoDialog  InfoDialog;
} EpInfoPanel;


typedef struct
{
	XeWidget              AdaptiveExposureW, FastExposureW,
	                      WhiteBalancePickGrayW, WhiteBalanceResetW,
	                      WhiteBalanceRW, WhiteBalanceGW, WhiteBalanceBW,
	                      BiasW, GainW, GammaW,
	                      ColorSaturationW,
	                      ResetAllW, ResetAllToLinearW;
	XeFileSelectionPanel  LUTFileSelectionPanel;
	XeWidget              LUTActiveW, LUTInfoLabelW;
	EBool                 PickingColorForWhiteBalance;
} EpExposurePanel;


typedef void (*EpWindowEventHandlerFunc)(EpWindow* P2DWindow, XeEvent* PEvent, EPointer PClientData);

typedef struct
{
	EpWindowEventHandlerFunc  Func;
	EPointer                  ClientData;
	uint32_t                  EventMask;
} EpWindowCallback;


typedef struct
{
	EcRGBAiColor  RGBAiColor;
	unsigned int  CIColor;

	uint16_t      BlendFunction;  // EpSRCxALPHA_plus_DSTxONE_MINUS_ALPHA or EpSRC_plus_DSTxONE_MINUS_ALPHA (premultiplied alpha)
	EcRGBAiColor  AlphaCheckerRGBAiColor0, AlphaCheckerRGBAiColor1;
	uint32_t      AlphaCheckerSize;  // Must be a power of 2
} EpWindowBackground;


//--------------------------------
// 2DWindow
//--------------------------------
struct EpWindow_S
{
	EObjectCore(EObject);

	XeWidget         ShellW;              // Container widgets of this window

	char*            TitlePrefix;
	char*            CurrentDir;
	int              Mode;                // Mode of the window ( EpWM_VIEW or EpWM_PAINT )
	int              DisplayType;         // Display type of the window (EpWDT_COLORINDEX or EpWDT_TRUECOLOR)
	int              ExactDisplayType;    // Exact display type of the window (EpWDT_8BIT_COLORINDEX, EpWDT_12BIT_RGB etc)
	int              ActiveWidget;        // Active Drawing Widget
	EBool            Alive;
	EBool            DoubleBuffering;
	int              Origin;
	int              PointerMode, GrabMode;
	int              PtrXOffset, PtrYOffset;  // For grabbing (area frame, control point, etc.)
	int              PrevMX, PrevMY;
	XeWidget         ActiveDrawWidget;        // The Widget ID of the active drawing Widget
	XeWidget         MainW,                   // Container widgets of this window
	                 HMatrixW;                // Horizontal Matrix Widget for the Drawing widget in a frame and the ZoomPanel
	XeWidget         DrawFrameW;
	XeWidget         DColorIndexW,            // The Drawing widgets
	                 D12BitW,
	                 D15BitW,
	                 D16BitW,
	                 D24BitW;
	EpCoord2         Offset;
	EpCoordinate     Zoom;                    // Multiplied by EpZOOMMULT
	EpCoordinate     XZoom, YZoom;
	EBool            GridOn;
	unsigned int     GridColorIndex;
	EcRGBAiColor     GridRGBColor;
	EIndex2          Size;                    // In pixels
	int              Depth;

	EpWindowBackground  Background;

	uint32_t         EUptodateFlags;          // These flags indicate which buffers are up-to-date

	EIndex2          CopySrcPosition, CopyDstPosition, CopySize;

	EpPicture*       Picture;                 // Pointer of the picture assigned to this window

	EpImage*         DisplayBuffer;             // Used if not all channels (RGBA) are on
	EpPixelFormat    DisplayBufferPixelFormat;  // If the Type field is 0, use the native format when possible.

	int              NumOfAreas;
	EpArea           Areas[EpMAX_NUM_OF_AREAS];  // Sub-areas
	EpArea*          CurrentArea;

	uint32_t         Flags;

	EpChannelFlags   ShowChannels;

	EBool            FullScreenModeOn;

// InfoPanel
//
	EpInfoPanel      InfoPanel;

	void             (*DisplayBufferUpdateCallback)(EpImage* PImage, const float PZoom, EPointer PClientData);
	EPointer         DisplayBufferUpdateClientData;

// Exposure control for viewing HDR images
//
	XeWidget         HDRSettingsDialogW;
	EpToneMapper     ToneMapper;
	EpExposure       Exposure;
	EpExposurePanel  ExposurePanel;

	void             (*AbortCallback)(EPointer PClientData);  // For the progress indicator
	EPointer         AbortClientData;

	EListA(, EpWindowCallback, Callbacks);

	EcColorPanel*		 ColorPanel;

	unsigned int		 NumOfPictureMovedCallbacks;
	EpCallback*      PictureMovedCallbacks;
	unsigned int     NumOfZoomChangedCallbacks;
	EpCallback*      ZoomChangedCallbacks;
	EBool            ZoomPanelOn, UseExposeBuffer;
	XeWidget         ZoomPanelMatrixW, ZoomScaleW;

	int              CenterImageOnResize, FullRedrawOnResize;

#ifdef EX11
	GLXContext       WGLXContext;
	Colormap         XColormap;               // X Colormap of this window
	Colormap         GLXColormap;             // X Colormap of this window's colorindex GL window
#endif // EX11
};

#define EpWINDOW_NONE	((EpWindow*)0)
#define	EpWINDOW_ALL	((EpWindow*)1)


//--------------------------------
// Panel/Window.c
//--------------------------------
extern EBool      EpWindow_CheckToneMapper(EpWindow* P2DWindow, EpImage* PImage, EpToneMapper* PToneMapper);

extern void       EpWindow_CallPictureMovedCallbacks(EpWindow* P2DWindow);
extern void       EpWindow_CallZoomChangedCallbacks(EpWindow* P2DWindow);

extern EpWindow*  EpWindow_New(const char* PName, XeWidget PPanelW, const int PDisplayType, const EBool PCreatePicture,
                   const int PWindowMode, const unsigned int PWindowFlags, const unsigned int PInfoPanelFlags);

extern EpWindow*  Ep_CreateViewWindow(const char* PName, XeWidget PPanelW, const int PDisplayType, const EBool PCreatePicture,
                   const unsigned int PWindowFlags, const unsigned int PInfoPanelFlags);

extern EpWindow*  Ep_CreatePaintWindow(const char* PName, XeWidget PPanelW, const int PDisplayType, const EBool PCreatePicture, const unsigned int PWindowFlags);

extern void       EpWindow_AddCallback(EpWindow* P2DWindow, const int PType, EpCallbackFunc PFunction, EPointer PClientData);
extern void       EpWindow_RemoveCallback(EpWindow* P2DWindow, const int PType, EpCallbackFunc PFunction, EPointer PClientData);
extern EBool      EpWindow_CalcWindowRect(EpWindow* P2DWindow, EBool PForceUpdate);

extern void       EpWindow_CallbackAdd(EpWindow* P2DWindow, const uint32_t PEventMask, EpWindowEventHandlerFunc PFunc, EPointer PClientData);

//----------------------------------------
// Panel/InfoPanel.c
//----------------------------------------
extern void       EpWindow_PrintMessage(EpWindow* P2DWindow, const int PType, const int PTime, char* PMessage, ...);
extern void       EpWindows_PrintMessage(const int PType, const int PTime, char* PMessage, ...);

extern void       EpWindow_SetProgressIndicator(EpWindow* P2DWindow, const float PProgress, void (*PAbortCallback)(EPointer), EPointer PClientData);

extern void       EpWindow_UpdatePtrPos(EpWindow* P2DWindow,  EIndex PPX, EIndex PPY);




extern void       Ep_AreasUpdateCoordinates(EpWindow* P2DWindow, const unsigned long PStateMask);
extern void       Ep_AreasDraw(EpWindow* P2DWindow, const unsigned long PStateMask);
extern void       EpWindow_AreasUndraw(EpWindow* P2DWindow, const unsigned long PStateMask);

// Display/XX.c
//
extern void       EpWindow_CreateDrawWidget(EpWindow* P2DWindow);


extern EpWindow*  Ep_CurrentWindow;

//--------------------------------
// Panel/Display/x.c
//--------------------------------
extern void       Ep_DisplayInit(XeDisplay* PDisplay);
extern void       Ep_DisplayFree(void);

extern EBool      EpWindow_Scroll(EpWindow* P2DWindow,  EpCoordinate PWinOffsetX, EpCoordinate PWinOffsetY,  const EBool PForceUpdate);
extern void       EpWindow_Redraw(EpWindow* P2DWindow);


extern void       EpWindow_CenterPicture(EpWindow* P2DWindow, const EpPicture* PPicture);
extern void       EpWindow_CenterPictureToXY(EpWindow* P2DWindow,  const EIndex PX, const EIndex PY);

extern void       EpWindow_SetFullScreenMode(EpWindow* P2DWindow, const EBool PFullScreen);

extern int        EpWindow_LoadPicture(EpWindow* P2DWindow, const char* PFileName, EpImageIOModule* PFileFormat, const EBool PCenterImageInWindow);
extern int        EpWindow_SavePicture(EpWindow* P2DWindow, char* PFileName, EpImageIOModule* PFileFormat);

extern EBool      EpWindow_SetZoom(EpWindow* P2DWindow,  const EpCoordinate PXZoom, const EpCoordinate PYZoom,  const EBool PUpdateDisplay);
extern EBool      EpWindow_SetZoomI(EpWindow* P2DWindow, const EIndex PZoom);

extern void       EpWindow_FitToPicture(EpWindow* P2DWindow,  const EIndex PMarginSizeX, const EIndex PMarginSizeY,  const EBool PAdjustZoom);

extern void       Ep_DrawPictureOnWindow(EpWindow* P2DWindow);

extern void       EpWindow_CreateExposeBuffer(EpWindow* P2DWindow);


//--------------------------------
// Panel/InfoPanel.c
//--------------------------------
extern void      EpWindow_HDRSettingsDialogPopUp(EpWindow* P2DWindow);
extern void      EpWindow_HDRSettingsDialogUpdate(EpWindow* P2DWindow);

extern void      EpInfoPanel_Init(EpInfoPanel* PPanel, const unsigned int PInfoPanelFlags);
extern void      EpInfoPanel_FreeContents(EpInfoPanel* PPanel);
extern void      EpWindow_InfoPanelOnOff(EpWindow* P2DWindow, const EBool PSwitch);
extern void      EpWindow_UpdateInfoPanel(EpWindow* P2DWindow);
extern XeString  EpImage_PixelColorToXeString(const EpImage* PImage,  const EIndex PX, const EIndex PY);
extern void      EpWindow_UpdateZoomLabel(EpWindow* P2DWindow);


//--------------------------------
// Panel/GUI.c
//--------------------------------
extern void      EpWindow_SetZoomPanel(EpWindow* P2DWindow, const EBool PSwitch);



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

#endif // _E2DWindow_h
