// ProgressDialog.cpp : implementation file
//

#include "stdafx.h"
#include "wincvs.h"
#include "ProgressDialog.h"

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

/////////////////////////////////////////////////////////////////////////////
// CProgressDialog dialog


CProgressDialog::CProgressDialog(bool & abort, bool interruptable, CWnd* pParent /*=NULL*/)
	: m_abort(abort), m_stopable(interruptable), m_pParent(pParent), hWndParent(0L),
	CDialog(CProgressDialog::IDD, pParent)
{
	//{{AFX_DATA_INIT(CProgressDialog)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
}


void CProgressDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CProgressDialog)
	DDX_Control(pDX, IDC_PROGRESS, m_progress);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CProgressDialog, CDialog)
	//{{AFX_MSG_MAP(CProgressDialog)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CProgressDialog message handlers

void CProgressDialog::PostNcDestroy() 
{
	MSG msg;
	if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)
		::SetActiveWindow(hWndParent);
	PostModal();
	while (PeekMessage(&msg, m_hWnd, 0, 0, PM_NOREMOVE) == TRUE)
		AfxGetApp()->PumpMessage();
	delete this;
}

void CProgressDialog::OnOK() 
{
	m_abort = true;
	DestroyWindow();
}

BOOL CProgressDialog::OnInitDialog() 
{
	CenterWindow();

	CDialog::OnInitDialog();
		
	CWnd *wnd = GetDlgItem(IDOK);
	if(wnd != 0L && !m_stopable)
	{
		wnd->EnableWindow(FALSE);
	}
	ShowWindow(SW_SHOW);

	return TRUE;  // return TRUE unless you set the focus to a control
}

BOOL CProgressDialog::Create()
{
	hWndParent = PreModal();
	return CDialog::Create(CProgressDialog::IDD, m_pParent);
}

static void flushDisplay(CDialog *dlg, bool & abort)
{
	MSG msg;
	while (PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE) == TRUE)
		AfxGetApp()->PumpMessage();
	while (PeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_NOREMOVE) == TRUE)
	{
		CPoint pt(LOWORD(msg.lParam), HIWORD(msg.lParam));
		ClientToScreen(msg.hwnd, &pt);
		CWnd *hwnd = CWnd::WindowFromPoint(pt);
		if(!abort && (*hwnd == *dlg || dlg->IsChild(hwnd)))
			AfxGetApp()->PumpMessage();
		else
			PeekMessage(&msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE);
	}
}

CProgress::CProgress(bool interruptable, const char *title) : m_dlg(0L), m_abort(false)
{
	m_dlg = new CProgressDialog(m_abort, interruptable);
	if (!m_dlg->Create())
	{
		TRACE0("Failed to create DlgBar\n");
		delete m_dlg;
		m_dlg = 0L;
		return;      // fail to create
	}
	if(title != 0L)
		m_dlg->SetWindowText(title);
	::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
}

CProgress::~CProgress()
{
	if(m_dlg != 0L)
		m_dlg->DestroyWindow();
}

void CProgress::SetProgress(int percent)
{
	if(m_dlg == 0L)
		return;

	m_dlg->m_progress.SetPos(percent);
	flushDisplay(m_dlg, m_abort);
	::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_WAIT));
	if(m_abort)
		m_dlg = 0L;
}

void CProgress::DoAbort(void)
{
	if(m_dlg != 0L)
		m_dlg->DestroyWindow();
	m_dlg = 0L;
}
