/***************************************************************************
**
**    $Header$
**
**    $Log$
** 
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  File name:  SHLMSHBR.CPP
//
//  Description:The implement file for the class: CMessageBar
//
//  Author:     Roger Zhang
//
//  Date:       03/18/95
//
//  Modification:
//
//      1. 03/18/95, Initial version 
//
//
//  Copyright (C) 1995 Microtek International. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"
#include "address.h"
#include "colors.h"            
#include "shlcom.h"         
#include "spin.h"
#include "shlmsgbr.h"
//#include "hosterrs.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif



extern void DrawFrame(CDC * pDC, CRect &rect, int nConvex);

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CMessageBar::Create(LONG style, const RECT& rect, CWnd * pParent)
{
    const char * pszMessageBarClass =
        AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW,
            LoadCursor(NULL, IDC_ARROW),
            (HBRUSH)(GetStockObject(LTGRAY_BRUSH)));
    return CWnd::Create(pszMessageBarClass, "SHLMSGBR",
        style, rect, pParent, IDW);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
CMessageBar::CMessageBar() 
: CWnd() , m_nTextPos(0), m_nTextLen(0), m_nFont(ANSI_FIXED_FONT), 
  m_isSpinOn(FALSE)
{ 
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
CMessageBar::~CMessageBar()
{
    FreeLibrary(m_hLib);
}                                   


/////////////////////////////////////////////////////////////////////////////
// CMessageBar  DECLARE_DYNAMIC
/////////////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC(CMessageBar, CWnd)
BEGIN_MESSAGE_MAP(CMessageBar, CWnd)
    //{{AFX_MSG_MAP(CMessageBar)
    ON_WM_CREATE()
    ON_WM_PAINT()
    ON_WM_SIZE()
    ON_WM_HSCROLL()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CMessageBar::GetLength(void)
{
    CRect rect;
    GetClientRect(&rect);
    int i = m_isSpinOn ? SPINWD - 1 : 0;
    m_rectFrame.SetRect(BARHZEDGE, BARVTEDGE, 
        rect.Width()-i-BARHZEDGE, rect.Height()-BARVTEDGE - 1);       
    m_ptChar.x = m_rectFrame.left + 1;
    m_nLen = (m_rectFrame.Width() - 2)/m_szFont.cx;
}

// szText == 0: Clear
/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
/*
void CMessageBar::ShowText(char * szText)
{                           
	if(szText)
		strcpy(m_pszText, szText);
    m_nTextPos = 0;
    m_nTextLen = szText ? strlen(m_pszText) : 0;
    if(m_nTextLen > m_nLen && !m_isSpinOn) {
        m_isSpinOn = CreateSpin();   
        ASSERT(m_isSpinOn);
    }                
    else if(m_nTextLen <= m_nLen && m_isSpinOn) {
        m_Spin.DestroyWindow();   m_isSpinOn = FALSE;
    }
    InvalidateRect(NULL);
}              
*/
void CMessageBar::ShowText(int nArgc, SynColor syncolor[])
{
	if (nArgc > 0) {
	    CString strTemp;
	    m_nArgc = nArgc;                          
	    	    
	    for (int i = 0; i < m_nArgc; i++) {    	    	
	    	m_syncolor[i] = syncolor[i]; 
	    	strTemp += m_syncolor[i].strText;    
	    }                               
	    m_nTextPos = 0;
	    m_nTextLen = strTemp.GetLength();
	    
	    if(m_nTextLen > m_nLen && !m_isSpinOn) {
	        m_isSpinOn = CreateSpin();   
	        ASSERT(m_isSpinOn);
	    }                
	    else if(m_nTextLen <= m_nLen && m_isSpinOn) {
	        m_Spin.DestroyWindow();   m_isSpinOn = FALSE;
	    }
	    InvalidateRect(NULL);
    }
    else {
    	m_nArgc = 0;         
	    InvalidateRect(NULL);    	
    }
}                               

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
BOOL CMessageBar::CreateSpin(void)
{
    CRect rect;
    GetClientRect(&rect);
    rect.left = rect.right - SPINWD;
    rect.top -= 1;
    rect.bottom += 1;
    if(m_Spin.Create(WS_VISIBLE|WS_CHILD|MSS_HORIZONTAL, rect, this,IDC_SPIN)
        == FALSE)   return FALSE;;
 //   m_Spin.SetAssociate(this);     
    return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CMessageBar::DrawFrame(CDC * pDC, CRect &rect)
{        
    ::DrawFrame(pDC, rect, 0);
}

/////////////////////////////////////////////////////////////////////////////
// CMessageBar message handlers


/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
int CMessageBar::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CWnd::OnCreate(lpCreateStruct) == -1)
        return -1;

    // Load MUSCROLL.DLL
    if ((m_hLib = LoadLibrary("MUSCROLL.DLL")) < HINSTANCE_ERROR)
    {
        AfxMessageBox("Can't find MUSCROLL.DLL");
//        char pchText[256];
//        ErrGetErrorText(ER_NOT_FIND_DLL, pchText);
//		AfxMessageBox(pchText);
        // prevent it from happening again
        return -1;
    }

    // TODO: Add your specialized creation code here
    // Get Font Size
    TEXTMETRIC tm;
    CDC * pDC = GetDC();
    pDC->SelectStockObject(m_nFont);
    pDC->GetTextMetrics(&tm);
    m_szFont.cy = tm.tmHeight + tm.tmExternalLeading;
    m_szFont.cx = tm.tmAveCharWidth;
    ReleaseDC(pDC);
    
    return 0;
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CMessageBar::OnPaint()
{
    CPaintDC dc(this); // device context for painting
    
    // TODO: Add your message handler code here
    GetLength();
/*    CRect rect(dc.m_ps.rcPaint.left+8, dc.m_ps.rcPaint.top+1, 
        dc.m_ps.rcPaint.right-8, dc.m_ps.rcPaint.bottom-2);    */
    DrawFrame(&dc, m_rectFrame);

    //if(!m_nTextLen)  return;

    dc.SelectStockObject(m_nFont);
    dc.SetBkColor(PALETTEINDEX(COLOR_LTGRAY));
    /*
    dc.SetTextColor(PALETTEINDEX(COLOR_BLACK));
    int l = m_nTextLen - m_nTextPos > m_nLen ? 
            m_nLen : m_nTextLen - m_nTextPos;
    dc.TextOut(m_ptChar.x, m_ptChar.y, m_pszText+m_nTextPos, l);
    */         
    if (m_nArgc == 0) {
    	return;
    }
           
	int l ;
	int i ; 
	int nTextLen = 0;                                                                     
    if (m_nTextPos == 0) {
		for ( i = 0; i < m_nArgc; i++) {
	    	if (m_syncolor[i].nColor == COLOR_RED) {
	    		dc.SetTextColor(RGB(255,0,0));//PALETTEINDEX(m_syncolor[i].nColor));		
	    	}
	    	else {	
				dc.SetTextColor(RGB(0,0,0));	    	
	    	}
	    	//int l = (strlen(synArgv[i].pszText) > m_nLen) ? 
	    	//	    m_nLen : strlen(synArgv[i].pszText);		      
	    	nTextLen += m_syncolor[i].strText.GetLength();
	    	if (nTextLen <= m_nLen ) { 	    	
		    	l = m_syncolor[i].strText.GetLength();
		    	dc.TextOut(m_ptChar.x, m_ptChar.y, m_syncolor[i].strText, l);    	
		    }	                                      
		    else {  
		        l = m_nLen - (nTextLen- m_syncolor[i].strText.GetLength());                                                                     
				dc.TextOut(m_ptChar.x, m_ptChar.y, m_syncolor[i].strText, l);    		                                                                            
		    }		    
		    m_ptChar.x = m_ptChar.x + m_syncolor[i].strText.GetLength()
		    	 * m_szFont.cx;
		}                                      
	}                                                           
	else {      
		int nCount = 0;
		int nLength;
		CString strTemp("");
		for ( i = 0; i < m_nArgc; i++) {
			nLength = strTemp.GetLength();
			strTemp += m_syncolor[i].strText;
			if ( m_nTextPos <= strTemp.GetLength() ) {	
				if (m_nTextPos < nLength) {
					if (i == 0) {
						nCount = 0;
					}
					else { 
						nCount = i-1;                              
					}	
					break;
				}
				else {
					nCount = i;
					break;
				}	
			}			
		}              
		//dc.SetTextColor(PALETTEINDEX(m_syncolor[nCount].nColor));		        
    	if (m_syncolor[i].nColor == COLOR_RED) {
    		dc.SetTextColor(RGB(255,0,0));//PALETTEINDEX(m_syncolor[i].nColor));		
    	}
    	else {	
			dc.SetTextColor(RGB(0,0,0));	    	
    	}
		
		int j = m_nTextPos - nLength; 
		int nLen = m_syncolor[i].strText.GetLength() - j;
		l = (nLen > m_nLen) ? m_nLen : nLen;
		dc.TextOut(m_ptChar.x, m_ptChar.y, m_syncolor[nCount].strText.
			Right(nLen), l);    	
		
		if (l == m_nLen)  return;                                                     

    	m_ptChar.x = m_ptChar.x + l * m_szFont.cx;
		nTextLen = l;
		                                                      
		if (nCount != m_nArgc - 1) {
			for ( i = nCount+1; i < m_nArgc; i++) {
		    	//dc.SetTextColor(PALETTEINDEX(m_syncolor[i].nColor));		
		    	if (m_syncolor[i].nColor == COLOR_RED) {
		    		dc.SetTextColor(RGB(255,0,0));//PALETTEINDEX(m_syncolor[i].nColor));		
		    	}
		    	else {	
					dc.SetTextColor(RGB(0,0,0));	    	
		    	}
		    	
				nTextLen += m_syncolor[i].strText.GetLength();

		    	if (nTextLen < m_nLen ) { 	    	
			    	l = m_syncolor[i].strText.GetLength();
			    	dc.TextOut(m_ptChar.x, m_ptChar.y, m_syncolor[i].strText, l);    	
			    }	                                      
			    else {  
			        l = m_nLen - (nTextLen- m_syncolor[i].strText.GetLength());                                                                     
					dc.TextOut(m_ptChar.x, m_ptChar.y, m_syncolor[i].strText, l);    		                                                                            
			    }		    
			    m_ptChar.x = m_ptChar.x + m_syncolor[i].strText.GetLength()
			    	 * m_szFont.cx;
			}	
		}
							
	}           	

    // Do not call CWnd::OnPaint() for painting messages
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CMessageBar::OnSize(UINT nType, int cx, int cy)
{
    CWnd::OnSize(nType, cx, cy);
    
    // TODO: Add your message handler code here     
    m_ptChar.y = BARVTEDGE + 1;
    m_nTextPos = 0;
    GetLength();    
    if(m_nTextLen > m_nLen && !m_isSpinOn) {
        m_isSpinOn = CreateSpin();   
        ASSERT(m_isSpinOn);    
    }                
    else if(m_nTextLen <= m_nLen && m_isSpinOn) {
        m_Spin.DestroyWindow();   m_isSpinOn = FALSE;
    }                       
    if(m_isSpinOn)
        m_Spin.MoveWindow(cx-SPINWD+1, -1, SPINWD, cy+2, TRUE);
}

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   
//
//  Description: 
//
//  Input:  
//
//  Output: 
//
//  Return: 
//
/////////////////////////////////////////////////////////////////////////////
void CMessageBar::OnHScroll(UINT nSBCode, UINT /*nPos*/, 
    CScrollBar* /*pScrollBar*/)
{
    // TODO: Add your message handler code here and/or call default
    int nDelta = 0;
    if(nSBCode == SB_LINELEFT)          nDelta = -1;
    else if(nSBCode == SB_LINERIGHT)    nDelta = +1;
    else        return; // nothing special

    int nNew = m_nTextPos + nDelta;
    if(nNew <= m_nTextLen - m_nLen && nNew >= 0) {
        m_nTextPos = nNew;    InvalidateRect(NULL);
    }
    else    MessageBeep(-1);
}

///////////////////////////////(EOF)/////////////////////////////////////////
