//================================================================
// lib2D
//
// Camera, higher-level code. Image processing etc.
//
// AUTHOR:  Gabor Nagy
// DATE:    2023-Aug-17 18:54:11
//
// Copyright (C) 1996-2026 by Gabor Nagy. All rights reserved.
//================================================================
#ifndef _EpCameraRec_h
#define _EpCameraRec_h

#ifndef EClass_h
#include <EClass.h>
#endif  // EClass_h

#include <Image/Camera.h>

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


typedef struct  EpCameraRec_S  EpCameraRec;

typedef int  (*EpCameraInitCallbackFunc)(EpCameraRec* PCameraRec, EPointer PClientData);

//================================================================
// EpCamera wrapper for recording, processing, drawing etc.
//================================================================
struct EpCameraRec_S
{
	EpCamera*      Camera;

	EIndex         LastDrawnFrame;

	EPointer       ClientData;

	EpGLTexture*   DstOpenGLTexture;  // If not NULL, capture into this OpenGL texture

// Multi-threading
//
	pthread_t      CameraInit_pthread;
	XeIntervalId   CameraInit_CheckTimerID;


	int            RecordingState;
	EpPixelFormat  RecordedFrames_PixelFormat;
	EIndex2        RecordedFrames_Size;
	EListA(, uint8_t*, RecordedFrames);  // Pixel buffers used when recording to memory

	EpImage*       TmpAccumulationImage;
	EpImage*       AccumulationImage;

	EpCameraInitCallbackFunc  CameraInitCallbackFunc;EPointer  CameraInitCallbackClientData;
};


typedef struct EpCamerasPanel_S  EpCamerasPanel;

enum
{
	EMicrosecond = 1,
	EMillisecond,
	ESecond
};


typedef struct
{
	XeWidget  SeparatorW, HMatrixW;
	XeWidget  PickGrayW;
	XeWidget  WhiteBalanceRW, WhiteBalanceGW, WhiteBalanceBW,  GainW,  GammaW,  ColorSaturationW,  AdaptiveExposureW;
} EpTonemappingUI;

typedef struct
{
	EpCamerasPanel*  CamerasPanel;

	EpCameraRec*     CameraRec;

	XeDrawer         Folder;
	XeWidget         CameraActiveW,  StatusMatrixW, StatusLabelW, ExposureProgressScaleW,  StatusLabel1W;

	XeWidget         ShutterGainFpsMatrixW;
	XeWidget         ShutterTimeW, ShutterTimeUnitOptionMenuW, GainW;

	XeWidget         FramesPerSecondW, FrameRateOptionMenuW, FrameRateOptionMenuPaneW;
	EList(, XeWidget, FrameRateOptionMenuButtonWs);

	XeWidget         LumaGammaAndSaturation_MatrixW;
	XeWidget         LumaGammaW, SaturationW;

	int              ShutterTimeUnit;  // EMicrosecond, EMillisecond, or ESecond

	XeWidget         FlipMatrixW,  FlipXW, FlipYW;
	XeWidget         WhiteBalanceMatrixW;

	XeWidget         CapturePixelFormatWs[EpPixelFormatCOUNT];

	XeWidget         Demosaic_MatrixW,  Demosaic_RawW, Demosaic_DropInW, Demosaic_NearestW, Demosaic_BilinearW, Demosaic_MalvarW, Demosaic_VNGW, Demosaic_SmoothHueW;

	XeWidget         HDR_ButtonW, HDR_MatrixW, HDR_T1W, HDR_K1W,  HDR_T2W, HDR_K2W;

	XeWidget         ResolutionsMatrixW;
	EList(, XeWidget, ResolutionRadioButtonWs);
	XeWidget         ResolutionOptionMenu, ResolutionsOptionMenuPaneW;
	EList(, XeWidget, ResolutionOptionMenuButtonWs);

	XeWidget         ROI_ButtonW, ROI_MatrixW, ROI_PositionXW, ROI_PositionYW, ROI_SizeXW, ROI_SizeYW;

	XeWidget         WhiteBalance_MatrixW, WhiteBalance_AutoW, WhiteBalance_ColorTemperatureW;

	XeWidget         SharpnessW;

	XeWidget         BadPixelCorrectionBW;
	XeWidget         DarkFieldSubtractionBW, DarkFieldFileNameW;

	EpTonemappingUI  ToneMapping;

	XeWidget         CoolingMatrixW, Cooling_OnW, Cooling_PowerW, Cooling_TargetTemperatureW;

	XeWidget         FilterWheelMatrixW, FilterWheelRadioMatrixW;
	EList(, XeWidget, FilterWheelSlotRadioButtonWs);
	XeWidget         FilterWheelAutoCycleBW, FilterWheelAutoCycleTextW;

	XeWidget         GraticuleMatrixW;XeWidget  GraticuleNoneW, GraticuleCrosshairW, GraticuleCircleW;
	XeWidget         FocusAssistW;
} EpCameraPanel;


typedef void (*EpCamerasPanelCallbackFunc)(EpCamerasPanel* PCamerasPanel, EpCameraPanel* PCameraPanel, const int PReason, EPointer PClientData);

// Callback reasons
enum
{
	EpCR_CAMERA_STATUS_CHANGED = 1,
	EpCR_WHITEBALANCE_PICK_GRAY
};

struct EpCamerasPanel_S
{
	XeWidget                    ParentW;
	XeWidget                    ApplyChangesToAllCamerasW, StatusLabelW;
	EBool                       ApplyChangesToAllCameras;

	EpCamerasPanelCallbackFunc  CallbackFunc;
	EPointer                    CallbackClientData;

	EListA(, EpCameraPanel*, CameraPanels);

	EBool                       CreatePickGrayButtons;

	XeIntervalId  CameraGUIChangeCheckTimerID;
};

extern EpCamerasPanel*  EpCameras_Panel;
extern XeIntervalId     EpCamera_RedrawTimerID;

extern EpCameraRec*     EpCameraRec_New(const char* PName);
extern void             EpCameraRec_Free(EpCameraRec* PCameraRec);
extern int              EpCameraRec_Disconnect(EpCameraRec* PCameraRec, const uint16_t PVerbosity);

extern EpCameraPanel*   EpCameraPanel_New(EpCamerasPanel* PCamerasPanel, XeWidget PParentW, EpCameraRec* PCameraRec);
extern void             EpCameraPanel_Free(EpCameraPanel* PPanel);
extern void             EpCameraPanel_Update(EpCameraPanel* PCameraPanel);

extern EpCamerasPanel*  EpCamerasPanel_New(XeWidget PParentW,  EpCamerasPanelCallbackFunc PCallbackFunc, EPointer PCallbackClientData,  EpImage* PIconImage);
extern void             EpCamerasPanel_Free(EpCamerasPanel* PCamerasPanel);
extern void             EpCamerasPanel_Update(EpCamerasPanel* PCamerasPanel, EpCameraRec** PCameraRecs, const EIndex PCameraRecs_Count);

extern int              EpCB_CameraRecConnectCamera(EpCameraRec* PCameraRec, EPointer PClientData);

extern void             EpCameraRec_ConnectCamera(EpCameraRec* PCameraRec, EpCameraInitCallbackFunc PCallbackProc, EPointer PClientData);
extern void             EpTH_CameraGUIChangeCheck(EPointer PClientData, XeIntervalId* PTID, const int PCount);


extern EpCamerasPanelCallbackFunc  EpCamera_CallbackFunc;
extern EPointer                    EpCamera_CallbackClientData;


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

#endif // _EpCameraRec_h
