// BootloadDlg.cpp : implementation file
//

#include "stdafx.h"
#include "USBRadio.h"
#include "BootloadDlg.h"
#include "FMRadioBootloader.h"

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

/////////////////////////////////////////////////////////////////////////////
// CBootloadDlg dialog

CBootloadDlg::CBootloadDlg(BYTE swVersion, BYTE hwVersion, HANDLE fmRadioDataHandle /*=NULL*/, BYTE* pEndpoint0ReportBuffer /*=NULL*/, DWORD endpoint0ReportBufferSize /*=0*/, BYTE* pEndpoint2ReportBuffer /*=NULL*/, DWORD endpoint2ReportBufferSize /*=0*/, CWnd* pParent /*=NULL*/)
	: CDialog(CBootloadDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CBootloadDlg)
	m_Percentage = _T("0%");
	//}}AFX_DATA_INIT


	//Check that the handles and buffer pointers are valid, and if so set
	//up a new bootloader with the buffer pointers
	if (fmRadioDataHandle && pEndpoint0ReportBuffer && endpoint0ReportBufferSize && pEndpoint2ReportBuffer && endpoint2ReportBufferSize)
	{
		m_BootloadStruct.pFMRadioBootloader = new CFMRadioBootloader(fmRadioDataHandle, pEndpoint0ReportBuffer, endpoint0ReportBufferSize, pEndpoint2ReportBuffer, endpoint2ReportBufferSize);
	}
	else
	{
		m_BootloadStruct.pFMRadioBootloader = NULL;
	}

	//Set bootload complete to false, and set the hardware and software versions
	m_BootloadStruct.bootloadComplete = false;
	m_BootloadStruct.swVersion = swVersion;
	m_BootloadStruct.hwVersion = hwVersion;
	m_BootloadStruct.bootloadSuccess = true;
	m_BootloadStruct.bootloadCloseOnFail = false;
}

CBootloadDlg::~CBootloadDlg()
{
	//Delete the bootloader created in the constructor
	delete m_BootloadStruct.pFMRadioBootloader;
}

void CBootloadDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CBootloadDlg)
	DDX_Control(pDX, IDC_PROGRESS_BAR, m_ProgressBar);
	DDX_Text(pDX, IDC_STATIC_PERCENTAGE, m_Percentage);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CBootloadDlg, CDialog)
	//{{AFX_MSG_MAP(CBootloadDlg)
	ON_WM_SHOWWINDOW()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBootloadDlg message handlers

BOOL CBootloadDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	//Set the range of the progressbar to 
	m_ProgressBar.SetRange(0, MCUIMAGE_PAGES + 1);
	m_ProgressBar.SetPos(0);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

DWORD WINAPI bootloadThread(LPVOID lpParam)
{
	//This is the bootloading thread, it will bootload the MCU, and then
	//when it is done it set's bootload complete to true
	((BootloadStruct*)lpParam)->bootloadSuccess = ((BootloadStruct*)lpParam)->pFMRadioBootloader->BootloadMCU(((BootloadStruct*)lpParam)->swVersion, ((BootloadStruct*)lpParam)->hwVersion, &((BootloadStruct*)lpParam)->bootloadCloseOnFail);
	((BootloadStruct*)lpParam)->bootloadComplete = true;

	return 1;
}

void CBootloadDlg::OnShowWindow(BOOL bShow, UINT nStatus) 
{
	CDialog::OnShowWindow(bShow, nStatus);

	//Check that the bootloader is valid, if not the exit with a cancel
	if (m_BootloadStruct.pFMRadioBootloader)
	{
		//Create a thread ID
		DWORD dwThreadID;
		
		//Create a thread off of the bootloadThread function and pass the bootload structure
		HANDLE hThread = CreateThread(NULL, 0, bootloadThread, (LPVOID)&m_BootloadStruct, 0, &dwThreadID);

		//Set the timer to update the bootload progress
		SetTimer(TIMER_BOOTLOAD_PROGRESS, TIMER_BOOTLOAD_PROGRESS_TIME, NULL);
	}
	else
	{
		CDialog::OnCancel();
	}
}


void CBootloadDlg::OnTimer(UINT nIDEvent) 
{
	//Check the timer trigger for our event
	if (nIDEvent == TIMER_BOOTLOAD_PROGRESS)
	{
		//Kill the timer
		KillTimer(TIMER_BOOTLOAD_PROGRESS);

		//Check if bootloading was complete, if not update the percentage, but if it is
		//complete, then close the dialog
		if (!m_BootloadStruct.bootloadComplete)
		{
			//If the bootload is still going, set the progress percentage to the value in the bootloader
			//and update the percentage text
			m_ProgressBar.SetPos(m_BootloadStruct.pFMRadioBootloader->m_ProgressPercentage);
			m_Percentage.Format("%d%%", (int)(((double)m_BootloadStruct.pFMRadioBootloader->m_ProgressPercentage / (double)(0x0F + 1)) * (double)100));
			UpdateData(FALSE);

			//Reset the timer
			SetTimer(TIMER_BOOTLOAD_PROGRESS, TIMER_BOOTLOAD_PROGRESS_TIME, NULL);
		}
		else
		{
			if (!m_BootloadStruct.bootloadSuccess && m_BootloadStruct.bootloadCloseOnFail)
			{
				CDialog::OnCancel();
			}
			else
			{
				CDialog::OnOK();
			}
		}
	}
	
	CDialog::OnTimer(nIDEvent);
}


