// WaterfallDisplay.h: interface for the CWaterfallDisplay class.
//
// COPYWRITE Reson Inc. 2002
//
// Written By:	Jonathan Marcus 2002
// 
// Purpose:		A single class that handles scrolling display of 
//				waterfall data, and manages internal ping history
//				as well as a DIB section abd profiler classes
//
// Notes:		CPingHistory/CDib/CPingProfiler are nested classes  
//				to keep this class as a stand-alone display w/ few 
//				included headers.
// 				Nested classes can be copied and pasted out for use
//				elsewhere, especially the profiler.					
// 
//
// Usage:
//
//
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_WATERFALLDISPLAY_H__D5FDB663_2ED5_4EEE_9EFB_BAE4EAF54F75__INCLUDED_)
#define AFX_WATERFALLDISPLAY_H__D5FDB663_2ED5_4EEE_9EFB_BAE4EAF54F75__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <vector>
#include <math.h>
using namespace std;

//This helper scales are width to 32bit boundary
//ESSENTIAL for proper display
#define  UPTO_DWORD(x)   (((x) & 0xfffffffc) + ((x) & 0x03 ? 4 : 0))

#define  DEFAULT_SCROLL			2
#define	 DEFAULT_MAX_PING		1500000


////////////////////////////////////////////////
//Internal Storage format of Pings in Vector
//Allocated once at configure time
//This can be expanded to store any kind of
//data, such as flags for pings etc...
#pragma pack(push, DISPLAY_H_PACK, 1)
typedef struct 
{
	UINT size;   
	BYTE *data;	
	 
}Record; 
#pragma pack( pop, DISPLAY_H_PACK )


typedef enum tagEScalingMode
{
	MEAN = 0, 
	PEAK, 
	RMS

} EScalingMode;


typedef enum tagEPaletteType
{
	GREYSCALE = 0,
	INVERSE,
	RED,
	GREEN,
	BLUE,
	RUST,
	SOIL,
	MOSS	

} EPaletteType;

typedef enum tagEScrollType
{
	TOP_DOWN = 0,
	BOTTOM_UP,
	LEFT_RIGHT,
	RIGHT_LEFT

} EScrollType;

typedef enum tagEErrorCode
{
	ERR_NONE = 0,
	ERR_NULL_CWND,
	ERR_DIB_HDR,
	ERR_DIB_BIT,
	ERR_PNG_HST,
	ERR_PLG_BLT,
	ERR_ADDLINE_ARG,
	ERR_PROFILER

} EErrorCode;
	
////////////////////////////////////////////////

class CWaterfallDisplay  
{

public:

	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//Standard Initialization/Destruction 
	//
	CWaterfallDisplay();
	virtual ~CWaterfallDisplay();
	
	//////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////
	//Configuration 
	//
	BOOL		Configure		(	CWnd		*pParentWnd,			//Ptr to our Parent CWnd where we get CDC*	
									CWnd		*pBltArea,				//ptr to an optional Frame that defines Blt area
									UINT		uiMaxPingSize,			//Max allocation/ping for history
									UINT		uiMaxVerticalPings,		//Max for vertical lines in image
									UINT		uiScrollSize,			//Numer of lines to buffer before Blt call
									EScrollType	eScrollType );			//Scroll Direction			
									 	
	//////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////
	//Optional Attribute set - defaults used otherwise
	//							
	void		SetAttributes	(	EPaletteType	palette,			//Starting palette
									EScalingMode	scaling );			//Starting scaling mode
									
	//////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////
	//Optional Attribute set - defaults used otherwise
	//If this function is called with NULL args, it
	//should probably default to above the waterfall
	//
	BOOL		EnableProfiler  (	CWnd		*pBltArea,				//The CWnd to get our blt rect from
									UINT		uiScrollSize );			//Option to update every n lines
	
	void		SetProfileBKClr (	COLORREF	crBack );				//Set Profiler BK color
	void		SetProfileColor	(	COLORREF	crLine );				//Set Profiler Line Color

	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//Add line to waterfall
	//
	BOOL	    AddImageLine8	(	BYTE	*byImagery,				//Anonymous 8 bit imagery bytes
									UINT	uiBytes	);				//number of bytes to get
							
	/*

	BOOL		AddImageryLine	(	void	*vpImagery,
									UINT	uiSamples,
									short	uiBytesPerSample );

    */

	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//Refresh and Resize of display
	//
	CRect		GetBltRect		(	void );							//Either returns CWnd client or Frame rect
	void		Resize			(	void );							//Call when parent wnd is resized
	void		Refresh			(	void );							//Call for manual refresh
	

	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//Image Setting Handlers
	void		SetBrightness	(	UINT			percent,
									BOOL			repaint );

	void		SetContrast		(	UINT			factor,
									BOOL			repaint );		
	
	void		Recalculate		(	int				iBrightness,
									int				iContrast );

	void		SetPalette		(	EPaletteType	paletteType );
	
	void		SetScaleMode	(	EScalingMode	scaleMode );

	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//DEBUG / ERROR HANDLING
	EErrorCode	GetLastError();
	EErrorCode  m_eLastError;

	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//CLEANUP ALL
	void		Cleanup				(	void );							//Destroy all internal objects and deallocate

private:

	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//Display Helper Functions
	void		FillDIBBuffer		(	void );	

	void		StretchProfile		(	BYTE		*data, 
										UINT		size, 
										BYTE		*imageLine );  
	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////////////////
	//Display Drawing Functions - There are many, but the class just calls one to 
	//save some overhead of switching.
	void		(CWaterfallDisplay::*pBltFxn)	( );						//OUR DYNAMIC FXN POINTER FOR QUICK BLT
	void		DrawVertDib			(	void );								//Top-Down or Bottom-Up Scroll
	void		DrawLeftRightDib	(	void );								//Left-Right or Right-Left Scroll
	void		DrawRightLeftDib	(   void );								//Right-Left Scroll
	
	//////////////////////////////////
	//////////////////////////////////
	//Private Variables
	//
	CWnd		   *m_pParentWnd;									//Window that owns the DC
	CWnd		   *m_pBltWindow;									//An optional frame area
	
	CDC			   *m_pParentDC;									//Ptr to window DC 
	CDC				m_dcSideScroll;									//Used for sidescrolling
	
	CRect			currentDibRect;

	UINT			m_uiMaxPingSize;								//internal storage of Max ping size
	UINT			m_uiMaxVerticalPings;							//internal storage of Vertical lines
	UINT			m_uiScrollLines;								//Number of lines to scroll before BLT					
	UINT			m_uiLinesScrolled;								//How many weve scroll already

	EScalingMode	m_eScalingMode;									//Dessimation/Stretch mode
	EPaletteType	m_ePaletteType;									//Color Palette
	EScrollType		m_eScrollType;									//Scroll Direction of Waterfall

	int				m_uiBrightness;
	int				m_iLastBright;
	int				m_uiContrast;

	BYTE		   *m_byReverseProfile;
	////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////
	//SIMPLE DIB HANDLING NESTED CLASS - For your Convenience...
	class CDib
	{		
	
	public:	 
		/////////////////////////////////////////
		//Construction
		CDib();
		virtual ~CDib();
					
		/////////////////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////////////////////////////////////////////////////////////////////
		//Image Creation
		BOOL			InitDib				(	EScrollType  eScrollType, CWnd	*pParentWnd );	//Setup the dib header
		
		BOOL			CreateDib			(	CRect	size );		//Create the memory 
	  
		/////////////////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////////////////////////////////////////////////////////////////////
		//Image Properties Retrival
		UINT			GetWidth			(	void );
		
		UINT			GetHeight			(	void );
		
		/////////////////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////////////////////////////////////////////////////////////////////
		//Image Scrolling
		void			Scroll				(	void );		//Scroll the memory n lines
		
		/////////////////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////////////////////////////////////////////////////////////////////
		//Image Manipulation and Attributes
		void			FillBlack			(	void );						//Zero the memory
		
		void			FillPalette			(	EPaletteType palette );		//Fill in bitmap palette
	  	  


		EScrollType		m_eDibScrollType;
		CWnd			*m_pParentWnd;
		CBitmap			m_bmpSideScroll;									//Used for side scrolling
		BITMAPINFO		*m_pBitmapInfo;										// start of allocated header bytes
		BYTE			*m_pBitmapBits;										// start of allocated memory		  
		UINT			m_uiBytes;											// total bitmap bytes (data only)		  
		UINT			m_uiWidth;
		UINT			m_uiHeight;
	};
	//END CLASS CDIB...
	//////////////////////////////////////////////////////////


	////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////
	//SIMPLE HISTORY HANDLING NESTED CLASS - For your Convenience...	
	class CPingHistory
	{
	
	public:
		/////////////////////////////////////////
		//Construction
						CPingHistory		(	void );
		virtual		   ~CPingHistory		(   void );	

		/////////////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////////////////////////////////////////////////////////////////
		//History Size Configure
		BOOL			Configure			(	UINT		cx,				// cx = maxPingSize,
												UINT		cy );			// cy = maxVerticalPings	
		/////////////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////////////////////////////////////////////////////////////////
		//History Helpers
		Record 		   *AddImagery			(	BYTE		*byInput,		//ptr to byte stream 
												UINT		 uiSize );		//number of bytes in stream
		
		Record		   *GetRecord			(	UINT		 uiIndex );		//Get a record, ZERO BASED INDEX!!!					 
		
		UINT			GetCount			(	void );						//Get number of records					

	private:

		/////////////////////////////////////////////////////////////////////////////////////////////
		/////////////////////////////////////////////////////////////////////////////////////////////
		//History Variables
		vector<Record>  m_vecHistoryBuffer;									//Record Buffer pointers into BYTE buffer
		BYTE		   *m_byDataBuffer;										//Buffer stores imagery of MAX size
		
		UINT		    m_uiFront;											//Index to where next record goes
		UINT		    m_uiRear;											//Index to last record
		
		UINT			m_uiTotalRecords;									//Logical number of records								
		UINT			m_uiMaxRecords;										//Max records to store
		UINT			m_uiMaxLineBytes;									//Max bytes per imagery line
	};
	//END CLASS CPINGHISTORY...
	//////////////////////////////////////////////////////////
	
	///////////////////////////////////////
	//The one and only Dib object
	CDib			m_dibImage;			//Dib of Raw values only
	CDib			m_dibProcImage;		//Dib with Brightness Contrast 

	///////////////////////////////////////
	//The one and only Ping History object
	CPingHistory	m_pingHistory;
};

#endif // !defined(AFX_WATERFALLDISPLAY_H__D5FDB663_2ED5_4EEE_9EFB_BAE4EAF54F75__INCLUDED_)
