// StatusDlgThread.cpp : implementation file
//

#include "stdafx.h"
#include "ProgressDlg.h"

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

/////////////////////////////////////////////////////////////////////////////
// CStatusDlgThread

CStatusDlgThread *CStatusDlgThread::aplCreateStatusThread(CWnd *pParent, bool bShowBreakBtn, bool bShowOnTop, bool bEnableSlave)
{
	CStatusDlgThread *pStatusThread = (CStatusDlgThread*)AfxBeginThread(RUNTIME_CLASS(CStatusDlgThread));

	pStatusThread->m_bShowOnTop = bShowOnTop;
	pStatusThread->m_bShowBreakBtn = bShowBreakBtn;
	pStatusThread->m_bSlave = bEnableSlave;

	pStatusThread->SetParent(pParent);
	pStatusThread->ResumeThread();

	while(!pStatusThread->IsInitialized())
	{
		MSG msg; 
		while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE|  PM_NOYIELD)) 
			DispatchMessage(&msg);
		while (::PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE|  PM_NOYIELD))
			DispatchMessage(&msg);
		while (::PeekMessage(&msg, NULL, WM_SHOWWINDOW, WM_SHOWWINDOW, PM_REMOVE|  PM_NOYIELD))
			DispatchMessage(&msg);
		while (::PeekMessage(&msg, NULL, WM_SIZE, WM_SIZE, PM_REMOVE|  PM_NOYIELD))
			DispatchMessage(&msg);
		while (::PeekMessage(&msg, NULL, WM_COMMAND, WM_COMMAND, PM_REMOVE|  PM_NOYIELD))
			DispatchMessage(&msg);
	}
	
	return pStatusThread;
}

IMPLEMENT_DYNCREATE(CStatusDlgThread, CWinThread)

CStatusDlgThread::CStatusDlgThread()
{
	m_pParent = NULL;
	m_pMainWnd = NULL;
	m_bInitialed = false;
	m_bEnd = false;
	m_bBreak = false;
	m_bShowOnTop = false;
	m_bShowBreakBtn = true;
	m_bSlave = false;

	OldHInst = 0;
	InitializeCriticalSection(&m_CriticalSection);
}

CStatusDlgThread::~CStatusDlgThread()
{
	if(OldHInst != 0)
		AfxSetResourceHandle(OldHInst);
	OldHInst = 0;
	DeleteCriticalSection(&m_CriticalSection);
}

BOOL CStatusDlgThread::InitInstance()
{
	OldHInst = AfxGetResourceHandle();

	AfxSetResourceHandle(module_inst);

	CProgressDlg dlg(m_pParent, this, m_bSlave);
	m_pMainWnd = &dlg;
	dlg.DoModal();
	m_pMainWnd = NULL;

	if(OldHInst != 0)
		AfxSetResourceHandle(OldHInst);
	OldHInst = 0;

	return TRUE;
}

int CStatusDlgThread::ExitInstance()
{
	// TODO:  perform any per-thread cleanup here
	return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CStatusDlgThread, CWinThread)
	//{{AFX_MSG_MAP(CStatusDlgThread)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CStatusDlgThread message handlers
void CStatusDlgThread::End()
{
	CProgressDlg *pDlg = (CProgressDlg*)m_pMainWnd;
	m_bEnd = true;
	if(pDlg && ::IsWindow(pDlg->m_hWnd)) 
	{
		HWND hWnd = m_pMainWnd->m_hWnd;
		m_pMainWnd->SendMessage(WM_CLOSE);
		while(::IsWindow(hWnd))
		{
			MSG msg;
			while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE|  PM_NOYIELD))
				DispatchMessage(&msg);
			while (::PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE|  PM_NOYIELD))
				DispatchMessage(&msg);
			while (::PeekMessage(&msg, NULL, WM_SHOWWINDOW, WM_SHOWWINDOW, PM_REMOVE|  PM_NOYIELD))
				DispatchMessage(&msg);
			while (::PeekMessage(&msg, NULL, WM_SIZE, WM_SIZE, PM_REMOVE|  PM_NOYIELD))
				DispatchMessage(&msg);
			while (::PeekMessage(&msg, NULL, WM_COMMAND, WM_COMMAND, PM_REMOVE|  PM_NOYIELD))
				DispatchMessage(&msg);
			while (::PeekMessage(&msg, NULL, WM_CLOSE, WM_COMMAND, PM_REMOVE|  PM_NOYIELD))
				DispatchMessage(&msg);
		}
	}
}

void CStatusDlgThread::SetParent(CWnd* pParent)
{
	m_pParent = pParent;
}

void CStatusDlgThread::StepIt()
{
	if(!m_bInitialed) return;
	EnterCriticalSection(&m_CriticalSection);
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if(pDlg && (!pDlg->m_ProgressCtrl.IsMarqueeMode())) pDlg->m_ProgressCtrl.StepIt();
	LeaveCriticalSection(&m_CriticalSection);
}

void CStatusDlgThread::Slave_StepIt()
{
	if(!m_bInitialed) return;
	EnterCriticalSection(&m_CriticalSection);
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if(pDlg && (!pDlg->m_ProgressCtrl2.IsMarqueeMode())) pDlg->m_ProgressCtrl2.StepIt();
	LeaveCriticalSection(&m_CriticalSection);
}

void CStatusDlgThread::SetRange(int iStart, int iEnd, int Position)
{
	if(!m_bInitialed) return;
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if(pDlg)
	{
		if(Position>-1)
		{
			pDlg->m_ProgressCtrl.SetRange32(iStart, iEnd);
			pDlg->m_ProgressCtrl.SetPos(Position);
			pDlg->m_ProgressCtrl.SetStep(1);
		}
		else
		{
			Position = pDlg->m_ProgressCtrl.GetPos();
			pDlg->m_ProgressCtrl.SetRange32(iStart, iEnd);
			pDlg->m_ProgressCtrl.SetPos(Position);
		}
	}
}

void CStatusDlgThread::Slave_SetRange(int iStart, int iEnd, int Position)
{
	if(!m_bInitialed) return;
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if(pDlg)
	{
		if(Position>-1)
		{
			pDlg->m_ProgressCtrl2.SetRange32(iStart, iEnd);
			pDlg->m_ProgressCtrl2.SetPos(Position);
			pDlg->m_ProgressCtrl2.SetStep(1);
		}
		else
		{
			Position = pDlg->m_ProgressCtrl2.GetPos();
			pDlg->m_ProgressCtrl2.SetRange32(iStart, iEnd);
			pDlg->m_ProgressCtrl2.SetPos(Position);
		}
	}
}

void CStatusDlgThread::GetRange(int& iStart, int& iEnd, int& Position)
{
	iStart = iEnd = Position = 0;
	if(!m_bInitialed) return;
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if(pDlg)
	{
		pDlg->m_ProgressCtrl.GetRange(iStart, iEnd);
		Position = pDlg->m_ProgressCtrl.GetPos();
	}
}

void CStatusDlgThread::Slave_GetRange(int& iStart, int& iEnd, int& Position)
{
	iStart = iEnd = Position = 0;
	if(!m_bInitialed) return;
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if(pDlg)
	{
		pDlg->m_ProgressCtrl2.GetRange(iStart, iEnd);
		Position = pDlg->m_ProgressCtrl2.GetPos();
	}
}

void CStatusDlgThread::SetText(LPCTSTR lpszText)
{
	if(!m_bInitialed) return;
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if(pDlg) pDlg->m_DescrCtrl.SetWindowText(lpszText);
}

void CStatusDlgThread::GetText(CString &sText)
{
	if(!m_bInitialed) return;
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if(pDlg) pDlg->m_DescrCtrl.GetWindowText(sText);
}

void CStatusDlgThread::Slave_SetText(LPCTSTR lpszText)
{
	if(!m_bInitialed) return;
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if(pDlg) pDlg->m_DescrCtrl2.SetWindowText(lpszText);
}

bool CStatusDlgThread::SetTitle(LPCTSTR lpszTitle)
{
	if(m_pMainWnd==NULL) return false;
	if(!::IsWindow(m_pMainWnd->m_hWnd)) return false;
	
	m_pMainWnd->SetWindowText(lpszTitle);
	
	return m_bInitialed;
}

void CStatusDlgThread::SetBreakMsg(LPCTSTR lpszMsg, LPCTSTR lpszBreakStatusMsg)
{
	m_sBreakMsg = lpszMsg;
	m_sBreakStatusMsg = lpszBreakStatusMsg;
}

bool CStatusDlgThread::SetMarquee(bool bMarqueeMode, int nInterval)
{
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if (pDlg)
		return pDlg->m_ProgressCtrl.SetMarqueeMode(bMarqueeMode, nInterval);

	return false;
}

void CStatusDlgThread::Start()
{
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if (pDlg)
		return pDlg->m_ProgressCtrl.Start();
}

void CStatusDlgThread::Stop()
{
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if (pDlg)
		return pDlg->m_ProgressCtrl.End();
}

bool CStatusDlgThread::Slave_SetMarquee(bool bMarqueeMode, int nInterval)
{
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if (pDlg)
		return pDlg->m_ProgressCtrl2.SetMarqueeMode(bMarqueeMode, nInterval);

	return false;
}

void CStatusDlgThread::Slave_Start()
{
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if (pDlg)
		return pDlg->m_ProgressCtrl2.Start();
}

void CStatusDlgThread::Slave_Stop()
{
	CProgressDlg* pDlg = (CProgressDlg*)m_pMainWnd;
	if (pDlg)
		return pDlg->m_ProgressCtrl2.End();
}