#if !defined(_ALFFDOWNLOAD_H)
#define _ALFFDOWNLOAD_H
/*  Project Biblio-Tec

	 SUBSYSTEM:    TEC30r.dll Library (TecLib)
	 FILE:         alffdwld.h
	 AUTHOR:       Alcindo Ferreira Filho

	 OVERVIEW:
	 Source file for definition of ALFFDownloadFile
    (WinAPI wrapper for ::URLDownloadCachedFile or ::URLDownloadFile),
    and its callback status class ALFFStatusCallback.

    COPYRIGHT:    © 2005
                  Alcindo Ferreira Filho
                  <alcindo@inttec.com.br>

    LICENSE:      Biblio-Tec license (BiblTec.txt)
*/
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


// BC502
#include <cstring.h>
#include <urlmon.h>

// OWL
#include <owl/owlall.h>

// ALFFLib
#include "alffdlg.h"

// Download Timeout for ending status dialog
#define     DOWNLOADTIMEOUT          60000

// User Messages
#define	   WM_USER_INVALIDURL		 (WM_USER + 5440)
#define	   WM_USER_CREATEFAILED		 (WM_USER + 5441)
#define     WM_USER_STARTDOWNLOAD    (WM_USER + 5442)
#define	   WM_USER_ENDDOWNLOAD		 (WM_USER + 5443)
#define     WM_USER_DISPLAYSTATUS    (WM_USER + 5444)

struct DOWNLOADPARAM
 {
 	HWND hWnd; 				// - IN - the window handle to display status
   HANDLE hEventStop; 	// - IN - the event object to signal to stop
   HANDLE m_hThread;    // - IN - the handle of this download thread
   bool  isCachedFile;  // - IN - Download or not cached file
   char* szURL; 		   // - IN - the URL of the file to be downloaded
   char* szFileName; 	// - OUT	- the filename of the downloaded file
 };

struct DOWNLOADSTATUS
 {
 	ULONG ulProgress;
 	ULONG ulProgressMax;
 	ULONG ulStatusCode;
 	LPCWSTR szStatusText;
 };

//////////////////////////////////////////////////////////////////////
// ALFFStatusCallback.
//
class ALFFStatusCallback : public IBindStatusCallback
{
public:
	ALFFStatusCallback(HWND hWnd, HANDLE hEventStop);
	// IUnknown methods
	STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject);
	STDMETHOD_(ULONG, AddRef)();
	STDMETHOD_(ULONG, Release)();

	// IBindStatusCallback methods
	STDMETHOD(OnStartBinding)(DWORD, IBinding *);
	STDMETHOD(GetPriority)(LONG *);
	STDMETHOD(OnLowResource)(DWORD);
	STDMETHOD(OnProgress)(ULONG ulProgress,
						  ULONG ulProgressMax,
						  ULONG ulStatusCode,
						  LPCWSTR szStatusText);
	STDMETHOD(OnStopBinding)(HRESULT, LPCWSTR);
	STDMETHOD(GetBindInfo)(DWORD *, BINDINFO *);
	STDMETHOD(OnDataAvailable)(DWORD, DWORD, FORMATETC *, STGMEDIUM *);
	STDMETHOD(OnObjectAvailable)(REFIID, IUnknown *);

protected:
	ULONG m_ulObjRefCount;
private:
	HWND m_hWnd;
   HANDLE m_hEventStop;
	string m_strURL;
};

//////////////////////////////////////////////////////////////////////
// ALFFDownloadFile
//
class ALFFDownloadFileCtrl
{
 public:
	ALFFDownloadFileCtrl(bool cachedFile = true);
	virtual ~ALFFDownloadFileCtrl();
   void    BeginDownload (HWND hWnd,const char* szURL, const char* fileName);
   void    ReleaseAll ();
   char*   GetCachedFileName() { return m_DownloadParam->szFileName; }
   DOWNLOADPARAM* m_DownloadParam;

 protected:
   DWORD  hThreadId;
	DWORD  Timeout;
	//char*  m_szURL;
	HWND   m_hWnd;
	int	 m_nLastError;

 private:
	void EndDownload ();
	static int Download (LPVOID pParam);
};

//////////////////////////////////////////////////////////////////////
// ALFFDownloadFile
//
class _TECLIBCLASS ALFFDownloadFile : public ALFFDialog
{
 // Construction/Destruction
 public:
	ALFFDownloadFile(TWindow* pParent,
                         char* dlgTitle,
                         const char* fromURL,
                         char* toFile,
                         bool  cachedFile = true,
                         bool  silent = false);
   ~ALFFDownloadFile();
   bool    IsDownloadEnded() { return (down->m_DownloadParam->m_hThread == NULL); }
   void    Close();
   int     GetDownloadError()     { return lastDwldError; }
   long    GetDownloadFilesize()  { return lastDwldFileSize; }
   long    GetDownloadTotaltime() { return lastDwldTotalTime; }
   float   GetDownloadSpeedRate() { return lastDwldSpeed; }  // Kb/s

 // Implementation
 protected:
   // Our Parent
   TWindow* myParent;
	HICON    m_hIcon;

   //
	void    SetupWindow();
   void    EvClose();
   void    CmCancel();
	void    EvSysCommand(UINT nID, TPoint& lParam);
	void    EvPaint();
	HANDLE  EvQueryDragIcon();
	LRESULT EvDownloaded (WPARAM,LPARAM);
   LRESULT EvDisplayStatus(WPARAM, LPARAM lParam);
   LRESULT EvInvalidUrl(WPARAM, LPARAM lParam);
   LRESULT EvDownloadFail(WPARAM, LPARAM lParam);
   LRESULT ExecuteDownload(WPARAM,LPARAM);

   // Download File Controls
  	ALFFDownloadFileCtrl* down;
	TButton*	m_btnExit;
	TStatic*	m_editURL;
	TStatic*	m_editFileName;   
	TGauge*	m_gaugeProgress;
  	TStatic*	m_editMsg;
  	TStatic*	m_editSize;
  	TStatic*	m_editSpeed;   
   //
   bool     isCachedFile;
   bool     silentMode;
   //
   char*    downloadFromURL;
   char*    toFilePath;
   char*    dialogTitle;
   
   // Statistics & Error Controls
   int      lastDwldError;
   long     lastDwldFileSize;
   long     lastDwldTotalTime;
   float    lastDwldSpeed;
   
  DECLARE_RESPONSE_TABLE(ALFFDownloadFile);
};

#endif // !defined(_ALFFDOWNLOAD_H)
