// DiagView.cpp : implementation of the CDiagView class
//

#include "stdafx.h"
#include "Diagnostic.h"

#include "DataSource.h"
#include "DiagView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CDiagView

IMPLEMENT_DYNCREATE(CDiagView, CTracePage)

BEGIN_MESSAGE_MAP(CDiagView, CTracePage)
	//{{AFX_MSG_MAP(CDiagView)
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDiagView construction/destruction

CDiagView::CDiagView() : CTracePage(CDiagView::IDD)
{
	//{{AFX_DATA_INIT(CDiagView)
	//}}AFX_DATA_INIT
	// TODO: add construction code here
	m_Highlight = (COLORREF)GetSysColor(COLOR_HIGHLIGHT);
}

CDiagView::~CDiagView()
{
}

void CDiagView::DoDataExchange(CDataExchange* pDX)
{
	CTracePage::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDiagView)
	//}}AFX_DATA_MAP
	DDX_Control(pDX, IDC_LUTxFrame, m_LUFrame[0]);
	DDX_Control(pDX, IDC_LURxFrame, m_LUFrame[1]);
	DDX_Control(pDX, IDC_FPSTxFrame, m_FPSFrame[0]);
	DDX_Control(pDX, IDC_FPSRxFrame, m_FPSFrame[1]);
	DDX_Control(pDX, IDC_BPSTxFrame, m_BPSFrame[0]);
	DDX_Control(pDX, IDC_BPSRxFrame, m_BPSFrame[1]);
}

/////////////////////////////////////////////////////////////////////////////
// CDiagView message handlers

void CDiagView::PercentFrame(CStatic& frame, const sMCM& data, CDC *dc)
{
	CRect rect;
	frame.GetWindowRect(rect);
	ScreenToClient(rect);
	rect.DeflateRect(2, 2);

	if ((BYTE)::GetVersion() >= 4)
		rect.DeflateRect(1, 1);

	int oldright = rect.right;
	if (data.Max > 0)
		rect.right = rect.left + __min((DWORD)rect.Width(), round(rect.Width() * float(data.Cur) / data.Max));
	else
		rect.right = rect.left;

	dc->FillSolidRect(rect, m_Highlight);
	rect.left = rect.right;
	rect.right = oldright;
	dc->FillSolidRect(rect, RGB(255, 255, 255));
}

void CombineRectRgn(CWnd *UpdateWnd, CWnd& Wnd, CRgn& UpdateRgn)
{
	CRect rct;
	Wnd.GetWindowRect(rct);
	UpdateWnd->ScreenToClient(rct);
	
	CRgn rgn;
	rgn.CreateRectRgnIndirect(rct);

	UpdateRgn.CombineRgn(&UpdateRgn, &rgn, RGN_OR);
}

void CDiagView::OnUpdate(WPARAM lHint) 
{
	// TODO: Add your specialized code here and/or call the base class
	if (lHint == uavTraceFasterPeriod) {
		const CTraceData *td = GetTraceData();

		CDataExchange dx(this, FALSE);

		DDX_Text(&dx, IDC_LUTxCur, (DWORD&)td->LU[0].Cur);
		DDX_Text(&dx, IDC_LURxCur, (DWORD&)td->LU[1].Cur);

		DDX_Text(&dx, IDC_FPSCurTx, (DWORD&)td->FPS[0].Cur);
		DDX_Text(&dx, IDC_FPSCurRx, (DWORD&)td->FPS[1].Cur);
		DDX_Text(&dx, IDC_FPSMaxTx, (DWORD&)td->FPS[0].Max);
		DDX_Text(&dx, IDC_FPSMaxRx, (DWORD&)td->FPS[1].Max);

		DDX_Text(&dx, IDC_BPSCurTx, (DWORD&)td->Th[0].Cur);
		DDX_Text(&dx, IDC_BPSCurRx, (DWORD&)td->Th[1].Cur);
		DDX_Text(&dx, IDC_BPSMaxTx, (DWORD&)td->Th[0].Max);
		DDX_Text(&dx, IDC_BPSMaxRx, (DWORD&)td->Th[1].Max);

		CRgn UpdateRgn;
		UpdateRgn.CreateRectRgn(0, 0, 0, 0);
		
		for (short i = 0; i < 2; i++) {
			CombineRectRgn(this, m_LUFrame[i], UpdateRgn);
			CombineRectRgn(this, m_FPSFrame[i], UpdateRgn);
			CombineRectRgn(this, m_BPSFrame[i], UpdateRgn);
			}

		RedrawWindow(NULL, &UpdateRgn, RDW_INVALIDATE | RDW_NOERASE | RDW_UPDATENOW);
		}
}

extern BOOL GenericEraseBkgnd(CDC* pDC, CWnd *parent);
BOOL CDiagView::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
	return GenericEraseBkgnd(pDC, this) ? CPropertyPage::OnEraseBkgnd(pDC) : TRUE;
}

void CDiagView::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	const CTraceData *td = GetTraceData();

	for (short i = 0; i < 2; i++)
		if (td) {
			sMCM lu = { 0, td->LU[i].Cur, 100 };

			PercentFrame(m_LUFrame[i], lu, &dc);
			PercentFrame(m_FPSFrame[i], td->FPS[i], &dc);
			PercentFrame(m_BPSFrame[i], td->Th[i], &dc);
			}
		else {
			sMCM empty = { 0, 0, 1 };

			PercentFrame(m_LUFrame[i], empty, &dc);
			PercentFrame(m_FPSFrame[i], empty, &dc);
			PercentFrame(m_BPSFrame[i], empty, &dc);
			}
	// Do not call CPropertyPage::OnPaint() for painting messages
}
