//-----------------------------------------------------------------------------
#ifndef HistogramCanvasH
#define HistogramCanvasH HistogramCanvasH
//-----------------------------------------------------------------------------
#include <deque>
#include "DrawingCanvas.h"

//-----------------------------------------------------------------------------
class HistogramCanvas : public ImageAnalysisPlotCanvas
//-----------------------------------------------------------------------------
{
	int					m_DrawStepWidth;
protected:
	int**				m_ppHistogramBuffer;
	PlotPoint*			m_pHistogramMax;
	double*				m_pHistogramAverage;
	double*				m_pStandardDeviation;
	bool				m_boHandleStandardDeviation;
	PlotPoint			m_CurrentMax;
	void				CalculateMaxValue( void );
	void				CalculateNoiseHistogram( const RequestData& data );
	void				CalculateNoiseHistogram_8u_C3Packed( const ImageBuffer* pIB, int order[3] );
	template<typename _Ty>
	void				CalculateNoiseHistogramUYV( const ImageBuffer* pIB );
	template<typename _Ty>
	void				CalculateNoiseHistogramYUV( const ImageBuffer* pIB );
	void				CalculatePixelHistogram( const RequestData& data );
	void				CalculatePixelHistogram_8u_RGBPacked( const ImageBuffer* pIB, int order[3] );
	template<typename _Ty>
	void				CalculatePixelHistogramUYV( const ImageBuffer* pIB );
	template<typename _Ty>
	void				CalculatePixelHistogramYUV( const ImageBuffer* pIB );
	template<typename _Ty>
	void				CalculatePixelHistogramYUV444( const ImageBuffer* pIB );
	virtual void		CustomAlloc( int /*channelCount*/ ) {}
	virtual void		CustomDealloc( void ) {}
	void				DeallocateHistogramBuffer( void );
	void				PrepareHistogramBuffer( bool boImageFormatChanged, int channelCount, mvIMPACT::acquire::TImageBufferPixelFormat pixelFormat );
	void				DrawHistogramLine( wxPaintDC& dc, int h, double scaleX, double scaleY, TPlane plane );
	void				SetupNumericalDisplay( int channelCount, int rowCountNeeded );
	DECLARE_EVENT_TABLE()
public:
	explicit			HistogramCanvas() {}
	explicit			HistogramCanvas( wxWindow* parent, const wxString& configName, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition,
							const wxSize& size = wxDefaultSize, long style = wxSUNKEN_BORDER,
							const wxString& name = wxT("Histogram"), bool boActive = false, bool boHandleStandardDeviation = false );
	virtual			   ~HistogramCanvas();
	virtual void		OnPaint( wxPaintEvent & );
	void				SetDrawStepWidth( int value );
	static int			GetDrawStepWidthMax( void ) { return 8; }
	virtual wxString	GetGridValue( int row, int col ) const;
};

//-----------------------------------------------------------------------------
class PixelHistogramCanvas : public HistogramCanvas
//-----------------------------------------------------------------------------
{
	DECLARE_DYNAMIC_CLASS(PixelHistogramCanvas)
	virtual bool	CustomRefreshData( const RequestData& /*data*/, int /*x*/ = -1, int /*y*/ = -1, int /*w*/ = -1, int /*h*/ = -1 ) { return false; }
public:
	explicit		PixelHistogramCanvas() {}
	explicit		PixelHistogramCanvas( wxWindow* parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition,
						const wxSize& size = wxDefaultSize, long style = wxSUNKEN_BORDER,
						const wxString& name = wxT("Pixel Histogram"), bool boActive = false );
	virtual void	RefreshData( const RequestData& data, int x = -1, int y = -1, int w = -1, int h = -1, bool boForceRefresh = false );
};

//-----------------------------------------------------------------------------
class IntensityPlotCanvas : public PixelHistogramCanvas
//-----------------------------------------------------------------------------
{
public:
	explicit					IntensityPlotCanvas() {}
	explicit					IntensityPlotCanvas( wxWindow* parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition,
									const wxSize& size = wxDefaultSize, long style = wxSUNKEN_BORDER,
									const wxString& name = wxT("Intensity Plot"), bool boActive = false );
	virtual					   ~IntensityPlotCanvas();
	virtual wxString			GetPlotSelection( void ) const { return m_PlotNames[m_SelectedPlot]; }
	virtual void				SetPlotSelection( const wxString& plotName );
	virtual wxString			GetGridValue( int row, int col ) const;
	virtual void				OnPaint( wxPaintEvent & );
protected:
	virtual void				CustomAlloc( int channelCount );
	virtual void				CustomDealloc( void );
	virtual bool				CustomRefreshData( const RequestData& data, int x = -1, int y = -1, int w = -1, int h = -1 );
	virtual int					GetRowCountNeededForNumericalDisplay( void ) const;
	virtual void				UpdateInternalData( void );
private:
	DECLARE_DYNAMIC_CLASS(IntensityPlotCanvas)
	typedef double plot_datatype;

	//-----------------------------------------------------------------------------
	enum TPlotSelection
	//-----------------------------------------------------------------------------
	{
		psFIRST,
		psAverageIntensity = psFIRST,
		psMostFrequentValue,
		psLAST
	};

	TPlotSelection				m_SelectedPlot;
	std::deque<plot_datatype>**	m_ppPlotValues;
	std::vector<plot_datatype>	m_CurrentMaxPlotValues;
	std::vector<plot_datatype>	m_CurrentMinPlotValues;
	std::vector<plot_datatype>	m_CurrentPlotValues;
	size_t						m_PlotCount;
	int							m_CurrentMaxPlotValue;
	int							m_CurrentMinPlotValue;

	bool						RefreshPlotData( void );
};

//-----------------------------------------------------------------------------
class NoiseHistogramCanvas : public HistogramCanvas
//-----------------------------------------------------------------------------
{
	DECLARE_DYNAMIC_CLASS(NoiseHistogramCanvas)
public:
	explicit		NoiseHistogramCanvas() {}
	explicit		NoiseHistogramCanvas( wxWindow* parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition,
						const wxSize& size = wxDefaultSize, long style = wxSUNKEN_BORDER,
						const wxString& name = wxT("Noise Histogram"), bool boActive = false );
	virtual void	RefreshData( const RequestData& data, int x = -1, int y = -1, int w = -1, int h = -1, bool boForceRefresh = false );
};

#endif // HistogramCanvasH
