/*
 =======================================================================================
  Name        :progbar.cpp
 
  Author      :Vincent Lhullier             Date :15/07/97
 
  Description :A beautiful progress bar
 =======================================================================================
  Modification -> Author :                  Date :
  Description :
 =======================================================================================
 */

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include "stdafx.h"
#include "mngdata5.h"
#include "progbar.h"
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*
 =======================================================================================
	CMyProgressBar implementation 
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : constructor
 ----------------------------------------------------------------------------------------
 */
CMyProgressBar::CMyProgressBar()
{
	m_bInit = FALSE;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : destructor
 ----------------------------------------------------------------------------------------
 */
CMyProgressBar::~CMyProgressBar()
{
}

/*
 ----------------------------------------------------------------------------------------
  Description   : message map
 ----------------------------------------------------------------------------------------
 */
BEGIN_MESSAGE_MAP(CMyProgressBar, CProgressCtrl)
	//{{AFX_MSG_MAP(CMyProgressBar)
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/*
 =======================================================================================
	CMyProgressBar message handlers
 =======================================================================================
 */


/*
 ----------------------------------------------------------------------------------------
  Description   : WM_PAINT Message
 ----------------------------------------------------------------------------------------
 */
void CMyProgressBar::OnPaint() 
{
	RECT			stWinRect;
	RECT			stDrawRect;
	int				iCol;

	CPaintDC dc(this); // device context for painting
	GetClientRect( &stWinRect );
	stDrawRect = stWinRect;

	iCol = (stDrawRect.right * OffsetPos(0)) / (m_iEnd - m_iStart + 1);

	if ( iCol > 256 )
	{
		stDrawRect.right = iCol - 257;
		dc.FillSolidRect( &stDrawRect, m_xForegroundColor );
		dc.BitBlt( iCol - 256, 0, 256, stDrawRect.bottom, &m_oDC, 0, 0, SRCCOPY );
	}
	else
	{
		dc.BitBlt( 0, 0, iCol, stDrawRect.bottom, &m_oDC, 256 - iCol, 0, SRCCOPY );
	}

	if ( m_cNumberOfFrames )
	{
		dc.BitBlt( iCol - m_cFrameWidth, 0, m_cFrameWidth, stDrawRect.bottom, &m_oAnimDC, m_cCurrentFrame * m_cFrameWidth, 0, SRCINVERT );
		m_cCurrentFrame = (m_cCurrentFrame + 1) % m_cNumberOfFrames;
	}

	stDrawRect.left = iCol + 1;
	stDrawRect.right = stWinRect.right;
	dc.FillSolidRect( &stDrawRect, m_xBackgroundColor );
}

/*
 =======================================================================================
	Specific functions 
 =======================================================================================
 */


/*
 ----------------------------------------------------------------------------------------
  Description   : set range of progression
  _iStart             -> beginning value
  _iEnd               -> end value
 ----------------------------------------------------------------------------------------
 */
void CMyProgressBar::m_fn_vSetRange( int _iStart, int _iEnd )
{
	m_iStart = _iStart;
	m_iEnd = _iEnd;
	SetRange( _iStart, _iEnd );
}



/*
 ----------------------------------------------------------------------------------------
  Description   : initialize DC and bitmap to draw
 ----------------------------------------------------------------------------------------
 */
void CMyProgressBar::m_fn_vInitDC( void )
{
	if (!m_bInit)
	{
		RECT			stRect;

		GetClientRect( &stRect );

		m_oDC.CreateCompatibleDC( GetDC() );
		m_oBitmap.CreateCompatibleBitmap( GetDC() , 256, stRect.bottom );
		m_oDC.SelectObject( &m_oBitmap );

		m_oAnimDC.CreateCompatibleDC( GetDC() );
		m_oAnimBitmap.CreateCompatibleBitmap( GetDC() , 256, stRect.bottom );
		m_oAnimDC.SelectObject( &m_oBitmap );
		m_cNumberOfFrames = 0;

		m_bInit = TRUE;
	}
}

/*
 ----------------------------------------------------------------------------------------
  Description   : set position of progression to beginning value, change drawing type
 ----------------------------------------------------------------------------------------
 */
void CMyProgressBar::m_fn_vReinit( void )
{
	SetPos( m_iStart );
}

/*
 =======================================================================================
	function to prepare drawing 
 =======================================================================================
 */


/*
 ----------------------------------------------------------------------------------------
  Description   : colored bar with random color value
  _xBackground        -> background color
 ----------------------------------------------------------------------------------------
 */
void CMyProgressBar::m_fn_vInitDrawing( COLORREF _xBackground )
{
	char	cColor;
	int		a_iColor[3];

	//srand( (unsigned) time ( NULL ) );
	
	for (cColor = 0; cColor < 3; cColor ++ )
	{
		a_iColor[ cColor ] = (rand() % 3) - 2;
		
		if (a_iColor[ cColor ] == 0)
			a_iColor[ cColor ] = rand() & 0xFF;
	}

	m_fn_vInitDrawing( a_iColor[0], a_iColor[1], a_iColor[2], _xBackground );
}


/*
 ----------------------------------------------------------------------------------------
  Description   : colored bar with given color
  _iRed               -> red value (-2 = increasing, -1 = decreasing)
  _iGreen             -> green value
  _iBlue              -> blue value
  _xBackground        -> background color
 ----------------------------------------------------------------------------------------
 */
void CMyProgressBar::m_fn_vInitDrawing( int _iRed, int _iGreen, int _iBlue, COLORREF _xBackground )
{
	char			cColor;
	int				iColor;
	unsigned char	ucColor[3];
	int				a_iColor[3];
	RECT			stRect;

	a_iColor[0] = _iRed;
	a_iColor[1] = _iGreen;
	a_iColor[2] = _iBlue;

	m_fn_vInitDC();

	for (cColor = 0; cColor < 3; cColor ++ )
	{
		if (a_iColor[ cColor ] == -2)
			ucColor[ cColor ] = (unsigned char) 0xFF;
		else if (a_iColor[ cColor ] == -1)
			ucColor[ cColor ] = (unsigned char) 0x7F;
		else
			ucColor[ cColor ] = (unsigned char) a_iColor[ cColor ]; 
	}

	m_xBackgroundColor = _xBackground;
	m_xForegroundColor = RGB( ucColor[0], ucColor[1], ucColor[2] );

	GetClientRect( &stRect );
	stRect.left  = 0;
	stRect.right = 2;

	for (iColor = 0; iColor < 128; iColor ++)
	{
		m_oDC.FillSolidRect( &stRect, RGB( ucColor[0], ucColor[1], ucColor[2] ) );
		for (cColor = 0; cColor < 3; cColor++)
		{
			if (a_iColor[ cColor ] == -2)
				ucColor[ cColor ]--;
			else if (a_iColor[ cColor ] == -1)
				ucColor[ cColor ]++;
		}
		stRect.left  += 2;
		stRect.right += 2;
	}
}


/*
 ----------------------------------------------------------------------------------------
  Description   : draw a bitmap
  uiBitmap            -> id of bimap
  _xForeground        -> foreground color
  _xBackground        -> background color
 ----------------------------------------------------------------------------------------
 */
void CMyProgressBar::m_fn_vInitDrawing( UINT _uiBitmap, COLORREF _xForeground, COLORREF _xBackground )
{
	m_fn_vInitDC();

	m_oBitmap.DeleteObject();
	m_oBitmap.LoadBitmap( _uiBitmap );
	m_oDC.SelectObject( &m_oBitmap );
	
	m_xBackgroundColor = _xBackground;
	m_xForegroundColor = _xForeground;
}

void CMyProgressBar::m_fn_vInitDrawing( tdstProgressBarDrawingData *_p_stPBDD )
{
	float			a_fColor[3];
	float			a_fDelta[3];
	RECT			stRect;
	unsigned char	cColor;

	m_fn_vInitDC();

	m_xBackgroundColor = _p_stPBDD->xBackColor;
	m_xForegroundColor = _p_stPBDD->xTailColor;

	a_fColor[0] = (float) GetRValue( _p_stPBDD->xTailColor );
	a_fColor[1] = (float) GetGValue( _p_stPBDD->xTailColor );
	a_fColor[2] = (float) GetBValue( _p_stPBDD->xTailColor );

	a_fDelta[0] = ((float) GetRValue(_p_stPBDD->xHeadColor) - a_fColor[0]) / 128;
	a_fDelta[1] = ((float) GetGValue(_p_stPBDD->xHeadColor) - a_fColor[1]) / 128;
	a_fDelta[2] = ((float) GetBValue(_p_stPBDD->xHeadColor) - a_fColor[2]) / 128;

	GetClientRect( &stRect );
	stRect.left  = 0;
	stRect.right = 2;
	
	for (cColor = 0; cColor < 128; cColor ++)
	{
		m_oDC.FillSolidRect( &stRect, RGB( (char) a_fColor[0], (char) a_fColor[1], (float) a_fColor[2] ) );
		a_fColor[0] += a_fDelta[0];
		a_fColor[1] += a_fDelta[1];
		a_fColor[2] += a_fDelta[2];
		stRect.left  += 2;
		stRect.right += 2;
	}

	if ( *_p_stPBDD->szText != 0)
	{
		stRect.left = stRect.top = 0;
		stRect.bottom = 20;
		stRect.right = 256 - ( (_p_stPBDD->cAnimNbFrames == 0 ) ? 0 : _p_stPBDD->cAnimFrameWidth );
		m_oDC.SetTextColor( _p_stPBDD->xTextColor );
		m_oDC.SetBkMode( TRANSPARENT );
		m_oDC.DrawText( _p_stPBDD->szText, strlen(_p_stPBDD->szText), &stRect, DT_VCENTER | DT_RIGHT );
	}

	m_fn_vInitAnim( _p_stPBDD->uiAnimBitmap, _p_stPBDD->cAnimNbFrames, _p_stPBDD->cAnimFrameWidth );
}

void CMyProgressBar::m_fn_vInitAnim( UINT _uiBitmap, char _cFrame, char _cFrameWidth )
{
	if ( (m_cNumberOfFrames = _cFrame) == 0)
		return;

	m_cFrameWidth = _cFrameWidth;

	m_fn_vInitDC();
	
	m_oAnimBitmap.DeleteObject();
	m_oAnimBitmap.LoadBitmap( _uiBitmap );
	m_oAnimDC.SelectObject( &m_oAnimBitmap );

	m_cCurrentFrame = 0;
}
