// GdStatic.cpp : implementation file
//

#include "stdafx.h"
#include "GdStatic.h"

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

/////////////////////////////////////////////////////////////////////////////
// CGdStatic

CGdStatic::CGdStatic()
{
	m_crText      = ::GetSysColor(COLOR_3DFACE);
	m_nFontWeight = FW_NORMAL;
	m_nFontSize   = 12;
}

CGdStatic::~CGdStatic()
{
	if (m_bitmap.GetSafeHandle())
		m_bitmap.DeleteObject();

	if (m_fontCaption.GetSafeHandle())
		m_fontCaption.DeleteObject();

	if (m_fontName.GetSafeHandle())
		m_fontName.DeleteObject();
}


BEGIN_MESSAGE_MAP(CGdStatic, CStatic)
	//{{AFX_MSG_MAP(CGdStatic)
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	ON_MESSAGE(WM_SETTEXT, OnSetText)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGdStatic message handlers

void CGdStatic::OnPaint() 
{
	CPaintDC dc(this); // device context for painting

	CFont *pfontOld = NULL;

	if (m_sFontName.GetLength() == 0) {
		CWnd *pwndParent = GetParent();

		if (pwndParent)
			dc.SelectObject(pwndParent->GetFont());
	}
	else {
		// create a font, if we need to
		if (!m_fontCaption.GetSafeHandle()) {
			m_fontCaption.CreateFont( m_nFontSize,
				0, 0, 0, m_nFontWeight,
				0, 0, 0, DEFAULT_CHARSET,
				OUT_DEFAULT_PRECIS,
				CLIP_DEFAULT_PRECIS,
				DEFAULT_QUALITY,
				FF_MODERN,
				m_sFontName);
		}

		if (m_fontCaption.GetSafeHandle())
			pfontOld = dc.SelectObject(&m_fontCaption);
	}

	// Draw text
	CString sText;
	GetWindowText(sText);

	dc.SetTextColor(m_crText);
	dc.SetBkMode(TRANSPARENT);

	// vertical center
	CRect rc;
	GetClientRect(rc); 

	rc.left += 5;
	dc.DrawText(sText, rc, DT_SINGLELINE | DT_LEFT | DT_VCENTER);

	if (pfontOld)
		dc.SelectObject(pfontOld);
}

BOOL CGdStatic::OnEraseBkgnd(CDC* pDC) 
{
	if (!m_bitmap.GetSafeHandle())
		MakeCaptionBitmap();

	if (m_bitmap.GetSafeHandle()) {
		CRect rc;
		GetClientRect(rc);

		CDC memDC;
		memDC.CreateCompatibleDC(pDC);

		CBitmap *pbitmap = memDC.SelectObject(&m_bitmap);

		pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &memDC, 0,0, SRCCOPY);

		memDC.SelectObject(pbitmap);
	}

	return TRUE;
}

LRESULT CGdStatic::OnSetText(WPARAM wParam, LPARAM lParam)
{
	DefWindowProc(WM_SETTEXT, wParam, lParam);

	Invalidate(TRUE);

	return (TRUE);
}

////////////////////////////////////////////////////////////////////////////////
// Helper to paint rectangle with a color.

static void PaintRect(CDC& dc, int x, int y, int w, int h, COLORREF cr)
{
	CBrush  br(cr);
	CBrush* pbrOld = dc.SelectObject(&br);

	dc.PatBlt(x, y, w, h, PATCOPY);
	dc.SelectObject(pbrOld);
}

void CGdStatic::MakeCaptionBitmap()
{
	if (m_bitmap.m_hObject)
		return;								   // already have bitmap; return

	CRect rc;
	GetClientRect(rc);

	int w = rc.Width();
	int h = rc.Height();

	// Create bitmap same size as caption area and select into memory DC
	CWindowDC dcWin(this);
	CDC dc;

	dc.CreateCompatibleDC(&dcWin);
	m_bitmap.DeleteObject();
	m_bitmap.CreateCompatibleBitmap(&dcWin, w, h);
	CBitmap* pbitmapOld = dc.SelectObject(&m_bitmap);

	COLORREF crBG = ::GetSysColor(COLOR_3DFACE); // background color

	int r = GetRValue(crBG);				// red..
	int g = GetGValue(crBG);				// ..green
	int b = GetBValue(crBG);				// ..blue color vals
	int x = 8*rc.right/8;					// start 5/6 of the way right
	int w1 = x - rc.left;					// width of area to shade

	const int NCOLORSHADES = 128;	// this many shades in gradient

	int xDelta = max(w / NCOLORSHADES , 1);	// width of one shade band

	PaintRect(dc, x, 0, rc.right-x, h, crBG);

	while (x > xDelta) {	// paint bands right to left
		x -= xDelta;						// next band
		int wmx2 = (w1-x)*(w1-x);			// w minus x squared
		int w2  = w1*w1;					// w squared
		PaintRect(dc, x, 0, xDelta, h, RGB(r-(r*wmx2)/w2, g-(g*wmx2)/w2, b-(b*wmx2)/w2));
	}

	PaintRect(dc,0,0,x,h,RGB(0,0,0));  // whatever's left ==> black

	// draw the 'constant' text

	// create a font, if we need to
	if (m_fontName.GetSafeHandle()==NULL) {
		m_fontName.CreateFont( 18, 0, 0, 0, FW_BOLD,
			0, 0, 0, ANSI_CHARSET,
			OUT_DEFAULT_PRECIS,
			CLIP_DEFAULT_PRECIS,
			DEFAULT_QUALITY,
			FF_MODERN,
			m_sFontName);	
	}

	CFont * pfontOld = dc.SelectObject(&m_fontName);

	// back up a little
	rc.right -= 5;

	// draw text in DC
	dc.SetBkMode(TRANSPARENT);
	dc.SetTextColor(::GetSysColor( COLOR_3DHILIGHT));
	dc.DrawText(m_sConstantText, rc + CPoint(1,1), DT_SINGLELINE | DT_RIGHT | DT_VCENTER);
	dc.SetTextColor(::GetSysColor( COLOR_3DSHADOW));
	dc.DrawText(m_sConstantText, rc, DT_SINGLELINE | DT_RIGHT | DT_VCENTER);

	// restore old font
	dc.SelectObject(pfontOld);

	// Restore DC
	dc.SelectObject(pbitmapOld);
}
