// DownloaderDlg.cpp : implementation file
//

#include "stdafx.h"
#include "denagent.h"
#include "DownloaderDlg.h"

#include "BindStatusCallback.h"

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

/////////////////////////////////////////////////////////////////////////////
// cDownloaderDlg dialog


cDownloaderDlg::cDownloaderDlg(CWnd* pParent /*=NULL*/)
	: CDialog(cDownloaderDlg::IDD, pParent), m_bDownloadSucceeded(false)
{
	//{{AFX_DATA_INIT(cDownloaderDlg)
	//}}AFX_DATA_INIT
}


void cDownloaderDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(cDownloaderDlg)
	DDX_Control(pDX, IDC_STATUSTOTAL, m_stStatusTotal);
	DDX_Control(pDX, IDC_STOPDOWNLOAD, m_wndStop);
	DDX_Control(pDX, IDC_PROGRESS, m_wndProgress);
	DDX_Control(pDX, IDC_PROGRESSTOTAL, m_wndProgressTotal);
	DDX_Control(pDX, IDC_STATUSTEXT, m_stIEMsg);
	DDX_Control(pDX, IDC_CUSTOMSTATUS, m_stCustomMsg);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(cDownloaderDlg, CDialog)
	//{{AFX_MSG_MAP(cDownloaderDlg)
	ON_BN_CLICKED(IDC_STOPDOWNLOAD, OnStopdownload)
	ON_WM_DESTROY()
	ON_WM_CLOSE()
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_USER+1, OnEndDownload)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// cDownloaderDlg message handlers

void cDownloaderDlg::OnStopdownload() 
{
	if(!m_bThreadDone)
		InterlockedExchange ( &g_fAbortDownload, 1 );
	else
		EndDialog(IDOK);
}

UINT gThreadProc ( void* pv )
{
	cDownloaderDlg* cDDlg = (cDownloaderDlg*)pv;

    cDDlg->WorkerThreadProc();

	return 0;
}

//FILELIST g_FileList[] = { { "messages.xml", "messages.dlc" }, { "memlocs.xml", "messages.dlc" }, { "decalplugins.xml", "messages.dlc" } };

void cDownloaderDlg::addFile(std::string remoteFile, std::string localFile) {
	FILELIST tmpFile;

	tmpFile.strFile = const_cast<char *>(remoteFile.c_str());
	tmpFile.strLFile = const_cast<char *>(localFile.c_str());

	m_FileList.push_back(tmpFile);
}

void cDownloaderDlg::WorkerThreadProc()
{
	//srand((unsigned int) time( NULL ) );

	OLECHAR olestr[1024];

	GUID pGuid;
	CoCreateGuid(&pGuid);

	StringFromGUID2(pGuid, olestr, 1024);

	HRESULT hr;
	CString strFile;

	//TCHAR lpFileName[MAX_PATH];

	int fileListSize = m_FileList.size();

	for(int i=0; i < fileListSize; i++)
	{
		CString st;
		st.Format("Downloading File %d of %d.", i + 1, fileListSize);

		m_stStatusTotal.SetWindowText(st);

		CCallback callback;
		callback.m_pDlg = this;

		CString strFullURL = m_FileList[i].strFile;
		m_stIEMsg.SetWindowText ( strFullURL );
		
		hr = URLDownloadToFile( NULL, strFullURL + CString("?") + CString(olestr), m_FileList[i].strLFile, 0, &callback );
		
		if ( FAILED(hr) )
		{
			if(!g_fAbortDownload )
			{
				LPTSTR lpszErrorMessage;
				CString sMsg;

				if(FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, MAKELANGID ( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPTSTR) &lpszErrorMessage, 0, NULL ))
				{
					sMsg.Format ( _T("Download failed. \n\n%s"), lpszErrorMessage );
					LocalFree ( lpszErrorMessage );
				}
				else
					sMsg.Format ( _T("Download failed."), (DWORD) hr );

				m_bDownloadSucceeded = false;

				AfxMessageBox ( sMsg );
				PostMessage(WM_USER+1, 1, NULL);
			}
			else
			{
				m_bDownloadSucceeded = false;

				PostMessage(WM_USER+1, IDCANCEL, NULL);
				AfxEndThread(0);
			}
		} else {
			m_bDownloadSucceeded = true;

			OFSTRUCT targetFile;
			OFSTRUCT sourceFile;

			// Make sure we really got a source file
			if (OpenFile(m_FileList[i].strLFile, &sourceFile, OF_EXIST) != HFILE_ERROR)
			{
				if (OpenFile(m_FileList[i].strFile, &targetFile, OF_EXIST) != HFILE_ERROR)
					DeleteFile(m_FileList[i].strFile);

				MoveFile(m_FileList[i].strLFile, m_FileList[i].strFile);
			}
		}

		if(g_fAbortDownload)
		{
			m_bDownloadSucceeded = false;
			PostMessage(WM_USER+1, IDCANCEL, NULL);
			AfxEndThread(0);
		}
	}
	
	PostMessage(WM_USER+1, 0, NULL);
	
	AfxEndThread(0);
}

void cDownloaderDlg::OnDestroy() 
{
	if(m_bThreadDone)
		CDialog::OnDestroy();
	else
		InterlockedExchange ( &g_fAbortDownload, 1 );
}

BOOL cDownloaderDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here

	m_bThreadDone = false;
	g_fAbortDownload = 0;
	SetWindowText("Updating Decal Components");
	m_pWorkerThread = AfxBeginThread ( gThreadProc, this, THREAD_PRIORITY_NORMAL, 0, 0 );

	m_wndProgressTotal.SetRange(0, m_FileList.size() * 100);

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void cDownloaderDlg::ProgressUpdate ( LPCTSTR szIEMsg, LPCTSTR szCustomMsg, const int nPercentDone )
{
    ASSERT ( AfxIsValidString ( szIEMsg ));
    ASSERT ( AfxIsValidString ( szCustomMsg ));
    ASSERT ( nPercentDone >= 0  &&  nPercentDone <= 100 );

	static int nPercentOld = nPercentDone;

	if(nPercentOld > nPercentDone)
		nPercentOld = nPercentDone;

    //m_stIEMsg.SetWindowText ( szIEMsg );
    m_stCustomMsg.SetWindowText ( szCustomMsg );
    m_wndProgress.SetPos ( nPercentDone );
	
	m_wndProgressTotal.SetPos( m_wndProgressTotal.GetPos() + (nPercentDone-nPercentOld));
	
	nPercentOld = nPercentDone;

	static TCHAR szMsg [256];
	StrFormatByteSize ( m_ulTotalData, szMsg, 256 );
}

void cDownloaderDlg::OnClose() 
{
	// TODO: Add your message handler code here and/or call default
	if(m_bThreadDone)
		CDialog::OnClose();
	else
		InterlockedExchange ( &g_fAbortDownload, 1 );
}

LRESULT cDownloaderDlg::OnEndDownload(WPARAM nID, LPARAM uMsg)
{
	m_bThreadDone = true;
	if((nID!=0) && (nID!=1))
	EndDialog(nID);
	else
	{
		CDialog::OnOK();
	}
	return 0;
}

cDownloaderDlg::DownloadStatus cDownloaderDlg::GetDownloadStatus()
{
	if (m_bDownloadSucceeded)
		return DownloadStatus::DOWNLOAD_SUCCEEDED;
	else
		return DownloadStatus::DOWNLOAD_FAILED;

}
