/*************************************************************************\
* "$RCSfile: CPSApp.hpp,v $"                                              *
***************************************************************************
* Information by CVS or VSS:                                              *
*     Last check in on: $Date: 2011/10/20 07:13:11 $                      *
*     by                $Author: schluckebier $
*     Revision        : $Revision: 1.60 $                                 *
\*************************************************************************/
/*! \file CPSApp.hpp
*	\brief Header CPSApp class
**************************************************************************/

#define USE_FREETYPE 1			//!< Use FreeType library (Set 0 to reduce program size)

//! Image formats
namespace ImageFormat
{
	//! Enumeration
	enum eIMAGEFORMAT
	{
		NO = 0,		//!< Undefined
		BMP = 1,	//!< Bitmap
		PNG,		//!< PNG
		JPG,		//!< JPEG
		RAW			//!< Uncompressed RAW data
	};
}

//! Image format specifiers
namespace ImageType
{
	//! Enumeration
	enum eIMAGETYPE
	{
		UNDEFINED,	//!< Invalid type (e.g. image pointer is \p NULL)
		Y8,			//!< 8 bit gray image (\p YIMAGE.Width contains pixel)
		Y10,		//!< 10 bit gray image (\p YIMAGE.Width contains bytes which is twice the pixel value)
		Y12,		//!< 12 bit gray image (\p YIMAGE.Width contains bytes which is twice the pixel value)
		Y16,		//!< 16 bit gray image (\p YIMAGE.Width contains bytes which is twice the pixel value)
		C			//!< RGB color image (\p CIMAGE)
	};
}

//! Selected view of info displayed at the \ref IR of the screen.
namespace InfoType
{
	//! Enumeration
	enum eINFOTYPE
	{
		LOGFILE = 1,	//!< Log file
		HISTOGRAM,		//!< Histogram
		HISTOGRAM_LOG,	//!< Histogram logarithmic
		APP				//!< Information from application
	};
}

//! Selected graph to be displayed at the \ref GR of the screen.
namespace GraphType
{
	//! Enumeration
	enum eGRAPHTYPE
	{
		CPU_LOAD = 1,	//!< CPU load
		TEMPERATURE,	//!< DSP temperature
		FPS,			//!< Frames per second
		INFO			//!< Information of sensor module status line
	};
}

//! Selected view of live image displayed at the "Live Camera View Area" of the screen.
namespace ViewType
{
	//! Enumeration
	enum eVIEWTYPE
	{
		CAMERA = 1,	//!< Camera image
		APP			//!< Application image
	};
}

//! Selected view of info displayed at the \ref IR of the screen.
namespace HistogramMode
{
	//! Enumeration
	enum eHISTOGRAM_MODE
	{
		LINEAR = 1,	//!< Linear
		LOGARITHM	//!< Logarithmic
	};
}

//! String table
namespace StringTable
{
	//! Enumeration
	enum eSTRINGTABLE
	{
		YES,
		NO,
		BACK,
		CANCEL,
		TEMPERATURE,
		CPU_LOAD,
		FRAMERATE,
		CAM_INFO,
		HISTOGRAM,
		HISTOGRAM_LOG,
		FILE_EXISTS,
		OVERWRITE,
		XXLAST
	};
}

//! Dialog identifiers
namespace DialogId
{
	//! Enumeration
	enum eDIALOG
	{
		MAIN = 1,	//!< CDlgMain (initial)
		PREV,		//!< CDlgPreviewSettings
		LOG,		//!< CDlgLog
		CAM,		//!< CDlgCam
		CAMEX,		//!< CDlgCamExpert
		TOOLS,		//!< CDlgTools
		CONFIG,		//!< CDlgConfig
		DIGIO,		//!< CDlgDigIO
		APP,		//!< CDlgApp
		SAVEPIC,	//!< CDlgSaveImage
		NONE	= -2,
		END	= -1
	};
}

//! Text styles
namespace TextStyle
{
	//! Enumeration
	enum eTEXTSTYLE
	{
		NORMAL = 0,	//!< Normal text
		ERROR,		//!< Error text (red)
		OK,			//!< OK text (green)
		BOLD,		//!< Bold text
		SHADOW,		//!< Shadow & opaque text
		MONOSPACE,	//!< Mono spaced text
		XXLAST		//!< End mark
	};
}

//! Global icons
namespace IconId
{
	//! Enumeration
	enum eICONS
	{
		OK,		//!< OK icon
		CANCEL,	//!< Cancel icon
		BACK,	//!< Back icon
		SAVE,	//!< Save icon
		SAVEA,	//!< Save icon (anim)
		APP,	//!< Application icon
		XXLAST	//!< End mark
	};
}

//! @brief Camera modes
//!
//! This is a bit field.
//! Bit 7..0 contain bits/pixel information.
//! Bit 15..8 contain tap information.
namespace CamMode
{
	//! Enumeration
	enum eCAMMODE
	{
		_2TAP_8BIT	= 0x0208,	//!< 2 Tap with 8 bit/pixel
		_2TAP_10BIT	= 0x020A,	//!< 2 Tap with 10 bit/pixel
		_2TAP_12BIT	= 0x020C,	//!< 2 Tap with 12 bit/pixel
		_1TAP_8BIT	= 0x0108,	//!< 1 Tap with 8 bit/pixel
		_1TAP_10BIT	= 0x010A,	//!< 1 Tap with 10 bit/pixel
		_1TAP_12BIT	= 0x010C	//!< 1 Tap with 12 bit/pixel
	};
}

//! Display styles of CDlgApp::OnImage
namespace AppImageType
{
	//! Enumeration
	enum eAPP_IMG_TYPE
	{
		COLOR = 0,		//!< Color image
		GRAY,			//!< Gray image
		NO_IMAGE		//!< No image
	};
}

//! Image union. Can contain a pointer to a color or gray image.
union uIMAGE
{
	CIMAGE *pcI;	//!< Color image
	YIMAGE *pyI;	//!< Gray image
};

//! Message between grab task and main task
typedef struct sCAM_MSG
{
	uIMAGE Image;					//!< Pointer on image
	int FrameCount;					//!< Frame number of this image
	int Type;						//!< Type of image
	unsigned int ImageCount;		//!< Image counter
	unsigned int TimeCount;			//!< Time of image
	unsigned int MissedTrigger;		//!< Missed trigger counter (from camera module status line)
	unsigned int AverageValue;		//!< Gray value average of image (from camera module status line)
	unsigned int ExposureCyles;		//!< Exposure time [camera clock cycles] (from camera module status line)
} CAM_MSG;

//! Returns array index of icon image.
inline int ICON(int x)
{
	return x & 0xFF;
}

//! Returns array index of dialog item.
inline int INDEX(int x)
{
	return x & 0xFF;
}

extern const char g_VersionString[60];

/*************************************************************************/
/*! @brief Application class

	Handles the global settings and resources of the camera.
**************************************************************************/
class CPSApp
{
friend class CDlgMain;
friend class CDlg;
friend class CDlgTools;
friend class CDlgPreviewSettings;
friend class CDlgApp;

public:
	//! Constants
	enum eCONST
	{
		LINEBUFFER_COUNT = 2,	//!< Number of line buffers
		MAILBOXSIZE = 3,		//!< Size of MBX
		MBX_POST_TIMEOUT = 10,	//!< Timeout value for MBX
		GRAPH_UPDATE_CYCLE = 50	//!< Update rate for CPU load graph
	};

	//! Information needed to store an image to SD card
	struct SAVE_IMAGE_SETTINGS
	{
		int  Counter;			//!< Image counter
		int  Format;			//!< Image format
		char Path[128];			//!< Path for picture files
		int  Autonumber;		//!< If 1, the picture counter is automatically incremented
		char FilenamePrefix[16];//!< String for the first 5 characters of the filename
		char FullFilename[256];	//!< Filename containing path, prefix, counter and type
		char Filename[12];		//!< Filename without path
	};

private:
	CPSApp();
	~CPSApp();
	static CPSApp *m_pThis;

public:
	static CPSApp *CreateInstance();
	//! Gets CPSApp instance.
	static CPSApp *GetInstance() { return m_pThis; }
	static void DisposeInstance();

	void Init();
	void DisplayInfoArea(bool Refresh = false);
	void CopyInfoArea();
	void DisplayCameraLiveImage();
	void DisplayResultImage();
	void StartGrabTask();
	void StopGrabTask();
	void RecBackground(bool Redraw = false);
	void InitBackground();
	void DisplayDynamicElements();
	int  SetTriggerSource();
	int  SetStrobeOutput(int Output);
	void DisplayGraph(CIMAGE *pImage = NULL);
	int  MainUILoop();
	int  SaveImage();
	int  LoadImage(const char *pFilename);
	int  PostCalc();
	int  PostCalc(YIMAGE *pImage, int Frame = -1);
	int  PostCalc(CIMAGE *pImage, int Frame = -1);
	int  PostCam();
	int  PostCam(YIMAGE *pImage, int Frame = -1);
	void SetApplicationName(const char *pName);
	void SetApplicationIcon(CIMAGE *pIcon, const char *pLabel);
	void SetPVPos(int x, int y, double dScale);
	void InitStringTable();
	void ChangeInfoArea(GUI_DLG *pDlg);
	int  MessageBox(const char *pText, int YesNo = 0, const char *pTitle = NULL) const;
	int  ChangeIpAddr(const char *pIpAddr, const char *pSubnet);
	int  LoadPreset(const char *PresetName);
	const char *GetSubnetMask() const;
	void UpdateScaleFactors();
	void GenerateFilename();
	void PrintInit(const char *pText);

	//! Displays \p m_Image on TCP-Display.
	void Display() { GUI_Display(&m_Image, 0, 0); }

	//! \name Getter Functions
	//! \{

	//! Returns active strobe output.
	int GetStrobeOutput() const { return (m_TriggerSourceNStrobeOut & 0x1C) >> 2; }
	//! Returns width of TCP-Display.
	int GetWidth() const { return m_ScreenWidth; }
	//! Returns height of TCP-Display.
	int GetHeight() const { return m_ScreenHeight; }
	//! Returns width of grabbed camera image.
	int GetCamWidth() const { return m_CamReg.m_Width; }
	//! Returns height of grabbed camera image.
	int GetCamHeight() const { return m_CamReg.m_Height; }
	//! Returns serial port of camera.
	int GetCamSerialPort() const { return m_CamSerialPort; }
	//! Returns Ethernet error.
	int GetEthError() const { return m_EthError; }
	//! Returns dialog area width.
	int GetDlgAreaWidth() const { return m_DlgAreaWidth; }
	//! Returns XML port.
	int GetXmlPort() const { return m_XmlPort; }
	//! Returns Dialog focus.
	int GetDlgFocus() const { return m_DlgFocus; }
	//! Return Dialog new focus.
	int GetDlgNewFocus() const { return m_DlgNewFocus; }
	//! Returns mode of info area on the screen.
	int GetInfo() const { return m_Info; }
	//! Returns histogram stretching value.
	int *GetHistStretch() { return &m_HistStretch; }
	//! Gets value indicating whether grab loop is active.
	bool IsCameraActive() const { return m_bCameraActive; }
	//! Returns scale value of live image.
	double GetScale() const { return m_PVScale; }
	//! Returns Skin path.
	const char *GetSkinPath() const { return m_SkinPath; }
	//! Returns Cam MBX Handle.
	MBX_Handle GetMbxCam() { return m_MbxCam; }
	//! Returns XML command MBX Handle.
	MBX_Handle GetMbxXmlCmd() { return m_MbxXmlCmd; }
	//! Returns XML return MBX Handle.
	MBX_Handle GetMbxXmlRet() { return m_MbxXmlRet; }
	//! Returns display device.
	VIB_DISPLAYDEVICE *GetVIBDisplayDev() { return &m_VIBDisplay; }
	//! Returns background image.
	CIMAGE *GetBgImage() { return &m_Image; }
	//! Returns display image.
	CIMAGE *GetDispImage() { return m_pDisplayImage; }
	//! Returns global icon.
	CIMAGE *GetIcon(int Id) { return &m_Icon[Id]; }
	//! Returns keyboard handle.
	FILE *GetKeyboardHandle() { return m_fKB; }
	//! Returns background color of text outputs.
	COLOR GetBackgroundColor() { return m_ColBack; }
	//! Returns serial number.
	const char *GetSerialNumber() const { return m_SerialNumber; }
	//! Returns string from global string table.
	const char *GetStr(int Id) const { return m_Str[Id]; }
	//! Returns IP address.
	const char *GetIPAdr() const { return m_IP_Adr; }
	//! Returns framework library version.
	const char *GetLibVersion() const { return m_LibVersion; }
	//! Returns application name.
	const char *GetApplicationName() const { return m_ApplicationName; }
	//! Returns gradient colors.
	COLOR *GetGradCol() { return m_GradCol; }
	//! Returns zoom-factor class.
	class CZoomFactor *GetZoomFactor() { return m_pZoom; }
	//! Returns current ini.
	Config *GetCurrentIni() { return m_CurrentIni; }
	//! Returns string ini.
	Config *GetPSStringsIni() { return m_VicPsStrings; }
	//! Returns Vic ini.
	Config *GetVicIni() { return m_VicPs; }
	//! Returns image settings structure.
	SAVE_IMAGE_SETTINGS *GetImageSettings() { return &m_SI; }
	//! \}

	//! Gets value indicating whether XML interface is allowed.
	bool IsXmlAllowed() const { return (m_XmlAllowed != 0); }
	//! Gets value indicating whether grab task is active.
	bool IsGrabTaskActive() const { return (m_hGrabTask == NULL) ? false : true; }
	//! Gets value indicating whether dialog \p Id has focus.
	bool IsDlgInFocus(int Id) const { return ((m_DlgFocus == Id) && (m_DlgNewFocus == Id)); }
	//! Gets value indicating whether dialog is getting focus.
	bool IsDlgGettingFocus(int Id) const { return ((m_DlgFocus != Id) && (m_DlgNewFocus == Id)); }
	//! Gets value indicating whether program is in application view mode.
	bool IsAppView() const { return (m_View == ViewType::APP); }
	//! Gets value indicating whether camera is present.
	bool IsCameraPresent() const { return m_bCameraPresent; }

	//! Restores old camera/application mode.
	void RestoreView() { m_View = m_ViewOld; }

	//! \name Setter Functions
	//! \{

	//! Sets task delay.
	void SetTaskDelay(int Delay) { m_TaskDelay = Delay; }
	//! Selects text-parameter.
	void SetTP(int TPSet) { GUI_SetTxtParam(&m_TPSet[TPSet]); }
	//! Sets camera pixel format.
	void SetCamPixelFormat(int Format) { m_CamPixelFormat = Format; }
	//! Sets info mode.
	void SetInfoMode(int Mode) { m_Info = Mode; }
	//! Sets new Dialog focus.
	void SetDlgNewFocus(int Focus) { m_DlgNewFocus = Focus; }
	//! \}

	CRegion m_CamReg;			//!< ROI of camera live image which is displayed on the screen
	char *m_DefaultPreset;		//!< Name of default preset .INI file

protected:
	void DrawCameraInfoPic();
	void InitIndexHtml();
	void OpenCameraLink(int LineCamCheck = 0);
	void OpenPflib();
	void ClosePflib();
	void InitNetwork();
	void InitDisplay();
	void SetColors();
	void DrawCPULoadPic();
	void DrawTemperaturePic();
	void DrawFrameRatePic();
	void CalcLut(int Low, int High, int *pLut);
	int  CalcHistogram(YIMAGE *pImage, int *pHistogram);
	void DrawHistogram(CIMAGE *pImage, int *pHistogram, int Mode);
	void CalcLowHigh(int &Low, int &High, int *pHistogram);
	void PrepareHistogram();
	void DisplayImage(CIMAGE *pImage, int PosX, int PosY);
	void ChangeGraphArea(GUI_DLG *pDlg);
	void PrepareFullScreen();
	int  FullScreenMode(int nKey);
	int  GetBytesPerPixel() const;
	void PSGrab();
	void ReadAppIni();
	void (*FxnDisplayDlgAppInfo)(unsigned int);	//!< Pointer to display function
	static void TaskPSGrab();
	static void TaskDisplay();

	//! Closes CL channel.
	void CloseCameraLink() { VIB_ClInCloseChannel(&m_ClInChannel); }

	char				*m_LibVersion;			//!< Version information of framework library
	MBX_Handle			m_MbxCam;				//!< Mailbox for sending camera live images from grab to main task to display at \p VIEW_CAMERA
	MBX_Handle			m_MbxVis;				//!< Mailbox for sending images from grab to main task to display
	MBX_Handle			m_MbxXmlCmd;			//!< Mailbox for XML command
	MBX_Handle			m_MbxXmlRet;			//!< Mailbox for XML return
	SEM_Handle			m_GrabTaskSem;			//!< Semaphore to synchronize setting start/stop of the grab task
	CAM_MSG				m_GMsg;					//!< Message for \p m_MbxCam
	CAM_MSG				m_CMsg;					//!< Message for \p m_MbxVis
	CIMAGE				m_Image;				//!< Image displayed on TCP-Display after connection or when a full screen dialog is closed. (All areas)
	CIMAGE				*m_pDisplayImage;		//!< Display image
	CIMAGE				m_LogImage;				//!< Image for info screen area
	CIMAGE				m_CPULoadPic;			//!< Image for graph screen area
	YIMAGE				m_YPVImage;				//!< Live-Y camera image, cut and scaled to selected ROI to fit in live camera area of screen
	CIMAGE				m_CPVImage;				//!< Live-color camera image, cut and scaled to selected ROI to fit in live camera area of screen
	YIMAGE				m_CPVImageSC[3];		//!< Image used to scale the RGB-image with Y-image scale functions
	CIMAGE				m_CVImage;				//!< Live-RGB camera image, cut and scaled to selected ROI to fit in live camera area of screen
	CIMAGE				m_HistImage;			//!< Image of histogram
	YIMAGE				*m_pCamImage;			//!< Pointer to displayed camera image
	CIMAGE				m_Icon[IconId::XXLAST];	//!< Global symbols
	COLOR				m_GradCol[4];			//!< Color set for GUI gradients
	COLOR				m_ColBack;				//!< Background color of text outputs
	COLOR				m_ColText;				//!< Text color
	GUI_DISPLAY			m_GUIDisplay;			//!< GUIDisplay device
	FILE				*m_fKB;					//!< Keyboard handle
	time_t				m_StartTime;			//!< Time of program start
	SAVE_IMAGE_SETTINGS m_SI;					//!< Filename information (Counter, path,...) to save an image on SD card
	VIB_DISPLAYDEVICE	m_VIBDisplay;			//!< Display device
	Config				*m_VicPs;				//!< Config instance \p m_SI is stored in
	Config				*m_VicPsStrings;		//!< Config instance the string table is stored in
	Config				*m_ColIni;				//!< Config instance with application color set information
	Config 				*m_EthernetIni;			//!< Config instance Ethernet settings are stored in
	Config				*m_AppIni;				//!< Config instance application settings (e.g. screen width) are stored in
	Config				*m_PresetIni;			//!< Config instance preset
	Config				*m_CurrentIni;			//!< Config instance current is stored in
	char				*m_SkinPath;			//!< Path where icons and string table are read from
	char				m_SerialNumber[32];		//!< Serial number of DSP-module
	char				m_IP_Adr[32];			//!< IP-address of the camera as string
	char				m_ApplicationName[32];	//!< Name in application window title
	char				*m_Str[64];				//!< Pointer to string table
	int					m_EthError;				//!< Error of Ethernet initialization
	int					m_CamSerialPort;		//!< COM port the camera module is connected to.
	int 				m_DlgFocus;				//!< Current dialog focus
	int 				m_DlgNewFocus;			//!< New dialog focus
	int					m_TcpDisplayPort;		//!< TCP-Port for TCP-Display device
	int					m_CamTimeout;			//!< Timeout for grabbing
	int					m_LogPosX;				//!< X-position of log area on the screen
	int					m_LogPosY;				//!< Y-position of log area on the screen
	int					m_CamPixelFormat;		//!< Pixel format of camera module
	int					m_ScreenWidth;			//!< Width of TCP-Display
	int					m_ScreenHeight;			//!< Height of TCP-Display
	int					m_PVPosX;				//!< X-position of ROI (live image displayed at the camera view are of the screen)
	int					m_PVPosY;				//!< Y-position of ROI (live image displayed at the camera view are of the screen)
	double				m_PVScale;				//!< Scale coefficent for ROI
	int					m_PVWidth;				//!< Width of ROI (live image displayed at the camera view are of the screen)
	int					m_PVHeight;				//!< Height of ROI (live image displayed at the camera view are of the screen)
	int 				m_VCamWidth;			//!< Virtual width of scaled camera image if it is displayed uncut
	int 				m_VCamHeight;			//!< Virtual height of scaled camera image if it is displayed uncut
	int 				m_VCamPosX;				//!< X-position of ROI in virtual camera image
	int 				m_VCamPosY;				//!< Y-position of ROI in virtual camera image
	int					m_DlgAreaWidth;			//!< Width of the dialog area of the screen (Height is always full screen height)
	int					m_NetShowLinks;			//!< If set on the generated website a FTP-link is displayed
	int					m_NetAutoRedraw;		//!< If set screen is redrawn when a network connection is established
	int					m_ShowGraph;			//!< Mode of graph area on the screen
	int					m_View;					//!< Mode of the live camera view on the screen
	int					m_ViewOld;				//!< Mode of the live camera view on the screen
	int					m_Info;					//!< Mode of info area on the screen
	int					m_GraphUpdateCounter;	//!< If \p m_GraphUpdateCounter==GRAPH_UPDATE_CYCLE the graph is redrawn
	int					m_UseHalcon;			//!< Flag if Halcon can be used. (e.g. if no license file is in the flash, it has to be disabled)
	int					m_TaskDelay;			//!< Time for \p TSK_sleep() in main loop
	int					m_XmlPort;				//!< TCP/IP port for XML-interface
	int					m_XmlAllowed;			//!< XML interface allowed
	int					m_TriggerSourceNStrobeOut;	//!< Trigger source and strobe out are located in the same register in the FPGA, so they have to be written together
	int					m_HistStretch;			//!< Enable histogram stretching
	int					m_FullScreen;			//!< Full screen mode enabled
	bool				m_bForceRedraw;			//!< Flag to force CDlg::Show() to redraw even when nothing changed
	bool				m_bAppActive;			//!< If false the application will shut down
	bool				m_bCameraActive;		//!< Camera is active
	bool				m_bCameraPresent;		//!< Camera is present
	CRegion				m_RegionPV;				//!< Displayed region of grabbed image
	CL_IN_CHANNEL		m_ClInChannel;			//!< Used Camera link channel (Camera link is not physically present, just logical)
	CL_IN_RECEIVER		m_ClInReceiver;			//!< Used Camera link receiver (Camera link is not physically present, just logical)
	TEXTPARAMETER		m_TPSet[TextStyle::XXLAST];		//!< Text-parameter set for different text styles
	class Ftp			*m_pFtp;				//!< Instance of \p Ftp class
	class CZoomFactor	*m_pZoom;				//!< Zoom-factor-list for camera live image

	char m_InfoCamModulTypecode[16];	//!< Version string
	char m_InfoCamModulSerial[16];		//!< Version string
	char m_InfoCamModulFPGASensor[16];	//!< Version string
	char m_InfoCamModulFPGAAdc[16];		//!< Version string
	char m_InfoCamModuluC[16];			//!< Version string
	char m_Framerate[16];				//!< Frame rate string

private:
	TSK_Handle m_hGrabTask;				//!< Grab Task Handle
};

/*************************************************************************/
