//this file is part of eMule
//Copyright (C)2002 Merkur ( devs@emule-project.net / http://www.emule-project.net )
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 2 of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#pragma once
#ifndef __AFXWIN_H__
	#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource.h"
#include "Neo\ReadWriteLock.h"	// SLUGFILLER: SafeHash // NEO: SSH - [SlugFillerSafeHash] <-- Xanatos --

//#define	DEFAULT_NICK		thePrefs.GetHomepageBaseURL()
#define	DEFAULT_NICK		_T("http://neomule.sourceforge.net") // NEO: MOD <-- Xanatos --
#define	DEFAULT_TCP_PORT	4662
#define	DEFAULT_UDP_PORT	(DEFAULT_TCP_PORT+10)

#define PORTTESTURL			_T("http://porttest.emule-project.net/connectiontest.php?tcpport=%i&udpport=%i&lang=%i")

class CSearchList;
class CUploadQueue;
class CListenSocket;
class CDownloadQueue;
class CScheduler;
//#ifdef NEO_UBT // NEO: NUBT - [NeoUploadBandwidthThrottler] -- Xanatos -->
class UploadBandwidthThrottler;
//#endif // NEO_UBT // NEO: NUBT END <-- Xanatos --
#ifdef NEO_DBT // NEO: NDBT - [NeoDownloadBandwidthThrottler] -- Xanatos -->
class DownloadBandwidthThrottler;
#endif // NEO_DBT // NEO: NDBT END <-- Xanatos --
#ifdef NEO_BC // NEO: NBC - [NeoBandwidthControl] -- Xanatos -->
class CBandwidthControl;
#else
class LastCommonRouteFinder;
#endif // NEO_BC // NEO: NBC END <-- Xanatos --
#ifdef LANCAST // NEO: NLC - [NeoLanCast] -- Xanatos -->
class CLanCast;
#endif //LANCAST // NEO: NLC END <-- Xanatos --
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface] -- Xanatos -->
class CVoodoo;
#endif // VOODOO // NEO: VOODOO END <-- Xanatos --
class CemuleDlg;
class CClientList;
class CKnownFileList;
class CServerConnect;
class CServerList;
class CSharedFileList;
class CClientCreditsList;
class CFriendList;
class CClientUDPSocket;
class CIPFilter;
class CWebServer;
class CMMServer;
class CAbstractFile;
class CUpDownClient;
class CPeerCacheFinder;
class CFirewallOpener;
class CSplashScreenEx; // NEO: SS - [SplashScreen] <-- Xanatos --
class CEMBackup; // NEO: NB - [NeoBackup] <-- Xanatos --
class CEdt; // NEO: EDT - [EstimatedDownloadTime] <-- Xanatos --
class CSystemInfo; // NEO: SI - [SysInfo] <-- Xanatos --
class CMiniMule; // NEO: MM - [NeoMiniMule] <-- Xanatos --
#ifdef NEO_CD // NEO: NCD - [NeoClientDatabase] -- Xanatos -->
class CSourceList;
#endif // NEO_CD // NEO: NCD END <-- Xanatos --
#ifdef ARGOS // NEO: NA - [NeoArgos] -- Xanatos -->
class CArgos;
#endif // ARGOS // NEO: NA END <-- Xanatos --
#ifdef IP2COUNTRY // NEO: IP2C - [IPtoCountry] -- Xanatos -->
class CIP2Country;
#endif // IP2COUNTRY // NEO: IP2C END <-- Xanatos --
class CFakecheck; // NEO: FC - [FakeCheck] <-- Xanatos --
#include "Neo/UPnP.h" // NEO: UPNP - [UPnPNat] <-- Xanatos --

struct SLogItem;

enum AppState{
	APP_STATE_RUNNING=0,
   	APP_STATE_SHUTINGDOWN,
	APP_STATE_DONE
};

// NEO: SO - [StandAlone] -- Xanatos -->
enum WorkAction{
	WRK_NULL = 0,
	WRK_SEARCHING,
	WRK_REQUESTING,
	WRK_ASKING,
	WRK_ACCEPTING,
	WRK_STANDALONE
};
// NEO: SO END <-- Xanatos --

class CemuleApp : public CWinApp
{
public:
	CemuleApp(LPCTSTR lpszAppName = NULL);

//#ifdef NEO_UBT // NEO: NUBT - [NeoUploadBandwidthThrottler] -- Xanatos -->
    UploadBandwidthThrottler* uploadBandwidthThrottler;
//#endif // NEO_UBT // NEO: NUBT END <-- Xanatos --
#ifdef NEO_DBT // NEO: NDBT - [NeoDownloadBandwidthThrottler] -- Xanatos -->
	DownloadBandwidthThrottler* downloadBandwidthThrottler;
#endif // NEO_DBT // NEO: NDBT END <-- Xanatos --

#ifndef NEO_BC // NEO: NBC -- Xanatos -->
	// ZZ:UploadSpeedSense -->
    LastCommonRouteFinder* lastCommonRouteFinder;
	// ZZ:UploadSpeedSense <--
#endif // NEO_BC // NEO: NBC END <-- Xanatos --
	CemuleDlg*			emuledlg;
	CClientList*		clientlist;
	CKnownFileList*		knownfiles;
	CServerConnect*		serverconnect;
	CServerList*		serverlist;	
	CSharedFileList*	sharedfiles;
	CSearchList*		searchlist;
	CListenSocket*		listensocket;
	CUploadQueue*		uploadqueue;
	CDownloadQueue*		downloadqueue;
	CClientCreditsList*	clientcredits;
	CFriendList*		friendlist;
	CClientUDPSocket*	clientudp;
	CClientUDPSocket*	clientkad; // NEO: KAX - [KadAuxPort] <-- Xanatos --
#ifdef LANCAST // NEO: NLC - [NeoLanCast] -- Xanatos -->
	CLanCast*			lancast;
#endif //LANCAST // NEO: NLC END <-- Xanatos --
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface] -- Xanatos -->
	CVoodoo*				voodoo;
#endif // VOODOO // NEO: VOODOO END <-- Xanatos --
	CIPFilter*			ipfilter;
#ifdef IP2COUNTRY // NEO: IP2C - [IPtoCountry] -- Xanatos -->
	CIP2Country*		ip2country;
#endif // IP2COUNTRY // NEO: IP2C END <-- Xanatos --
	CWebServer*			webserver;
	CScheduler*			scheduler;
	CMMServer*			mmserver;
	CPeerCacheFinder*	m_pPeerCache;
	CFirewallOpener*	m_pFirewallOpener;
	CSplashScreenEx*	m_pSplashWnd; // NEO: SS - [SplashScreen] <-- Xanatos --
	CEMBackup*			BackupEngine; // NEO: NB - [NeoBackup] <-- Xanatos --
	CEdt*				edt; // NEO: EDT - [EstimatedDownloadTime] <-- Xanatos --
	CSystemInfo*		sysinfo; // NEO: SI - [SysInfo] <-- Xanatos --
	CMiniMule*			minimule; // NEO: MM - [NeoMiniMule] <-- Xanatos --
#ifdef NEO_CD // NEO: NCD - [NeoClientDatabase] -- Xanatos -->
	CSourceList*		sourcelist;
#endif // NEO_CD // NEO: NCD END <-- Xanatos --
#ifdef ARGOS // NEO: NA - [NeoArgos] -- Xanatos -->
	CArgos*				argos;
#endif // ARGOS // NEO: NA END <-- Xanatos --
#ifdef NEO_BC // NEO: NBC - [NeoBandwidthControl] -- Xanatos -->
	CBandwidthControl*	bandwidthControl;
#endif // NEO_BC // NEO: NBC END <-- Xanatos --
	CFakecheck*			FakeCheck; // NEO: FC - [FakeCheck] <-- Xanatos --
	MyUPnP*				m_UPnPNat;	// NEO: UPNP - [UPnPNat] <-- Xanatos --

	HANDLE				m_hMutexOneInstance;
	int					m_iDfltImageListColorFlags;
	CFont				m_fontHyperText;
	CFont				m_fontDefaultBold;
	CFont				m_fontSymbol;
	CFont				m_fontLog;
	CBrush				m_brushBackwardDiagonal;
	static const UINT	m_nVersionMjr;
	static const UINT	m_nVersionMin;
	static const UINT	m_nVersionUpd;
	static const UINT	m_nVersionBld;
	DWORD				m_dwProductVersionMS;
	DWORD				m_dwProductVersionLS;
	CString				m_strCurVersionLong;
	CString				m_strCurVersionLongDbg;
	CString				m_strNeoVersionLong; // NEO: NV - [NeoVersion] <-- Xanatos --
	UINT				m_uCurVersionShort;
	UINT				m_uCurVersionCheck;
	ULONGLONG			m_ullComCtrlVer;
	AppState			m_app_state; // defines application state for shutdown 
	BOOL				m_reset_app; // NEO: MOD <-- Xanatos --
	BOOL				m_app_ready; // NEO: MOD <-- Xanatos --
	CMutex				hashing_mut;
	CReadWriteLock		m_threadlock;	// SLUGFILLER: SafeHash - This will ensure eMule goes last // NEO: SSH - [SlugFillerSafeHash] <-- Xanatos --
	CString*			pstrPendingLink;
	COPYDATASTRUCT		sendstruct;
	CString				m_LocalBindAddress; // NEO: MOD - [BindToAdapter] <-- Xanatos --

// Implementierung
	virtual BOOL InitInstance();
	virtual int ExitInstance();

	// ed2k link functions
	void		AddEd2kLinksToDownload(CString strLinks, int cat);
	void		SearchClipboard();
	void		IgnoreClipboardLinks(CString strLinks) {m_strLastClipboardContents = strLinks;}
	void		PasteClipboard(int cat = 0);
	bool		IsEd2kFileLinkInClipboard();
	bool		IsEd2kServerLinkInClipboard();
	bool		IsEd2kFriendLinkInClipboard(); // NEO: TFL - [TetraFriendLinks] <-- Xanatos --
	bool		IsEd2kLinkInClipboard(LPCSTR pszLinkType, int iLinkTypeLen);
	LPCTSTR		GetProfileFile()		{ return m_pszProfileName; }

	CString		CreateED2kSourceLink(const CAbstractFile* f);
//	CString		CreateED2kHostnameSourceLink(const CAbstractFile* f);
	CString		CreateKadSourceLink(const CAbstractFile* f);

	// clipboard (text)
	bool		CopyTextToClipboard(CString strText);
	CString		CopyTextFromClipboard();

	void		OnlineSig();
	void		UpdateReceivedBytes(uint32 bytesToAdd, bool recivedFromFriend = false, bool recivedFromRelease = false); // NEO: PTM - [PrivatTransferManagement] // NEO: BM - [BandwidthModeration] <-- Xanatos --
	void		UpdateSentBytes(uint32 bytesToAdd, bool sentToFriend = false, bool sentToRelease = false); // NEO: BM - [BandwidthModeration] <-- Xanatos --
	int			GetFileTypeSystemImageIdx(LPCTSTR pszFilePath, int iLength = -1);
	HIMAGELIST	GetSystemImageList() { return m_hSystemImageList; }
	CSize		GetSmallSytemIconSize() { return m_sizSmallSystemIcon; }
	void		CreateBackwardDiagonalBrush();
	void		CreateAllFonts();
	bool		IsPortchangeAllowed();
	bool		IsConnected();
	bool		IsWorkingAllowed(WorkAction Action = WRK_NULL, bool bStatsOnly = false); // NEO: SO - [StandAlone] <-- Xanatos --
	bool		IsFirewalled();
	bool		DoCallback( CUpDownClient *client );
	void		SetHighTimer(bool bHigh); // NEO: MOD <-- Xanatos --
	uint32		GetID();
	uint32		GetPublicIP() const;	// return current (valid) public IP or 0 if unknown
	void		SetPublicIP(const uint32 dwIP);
#ifdef NEO_BC // NEO: NAFC - [NetworkAdapterFeatbackControl] -- Xanatos -->
	void		CheckIDChange(const uint32 dwIP, bool bFromNAFC = false); // NEO: RIC - [ReaskOnIDChange]
#else
	void		CheckIDChange(const uint32 dwIP); // NEO: RIC - [ReaskOnIDChange]
#endif // NEO_BC // NEO: NAFC END <-- Xanatos --
	// NEO: RIC - [ReaskOnIDChange] -- Xanatos -->
	bool		IsPublicIP() {return (m_dwPublicIP != 0);}
	uint32		GetLastIDChange() {return m_uLastChangeID;} 
	// NEO: RIC - [ReaskOnIDChange] <-- Xanatos --
	// NEO: MOD - [BindToAdapter] -- Xanatos -->
	LPCTSTR		GetBindAddress() { if (m_LocalBindAddress.IsEmpty()) { return NULL; } else { return m_LocalBindAddress; } }
	void		BindToAddress(LPCTSTR LocalBindAddress = NULL);
	// NEO: MOD END <-- Xanatos --

	// because nearly all icons we are loading are 16x16, the default size is specified as 16 and not as 32 nor LR_DEFAULTSIZE
	HICON		LoadIcon(LPCTSTR lpszResourceName, int cx = 16, int cy = 16, UINT uFlags = LR_DEFAULTCOLOR) const;
	HICON		LoadIcon(UINT nIDResource) const;
	HBITMAP		LoadImage(LPCTSTR lpszResourceName, LPCTSTR pszResourceType) const;
	HBITMAP		LoadImage(UINT nIDResource, LPCTSTR pszResourceType) const;
	bool		LoadSkinColor(LPCTSTR pszKey, COLORREF& crColor) const;
	bool		LoadSkinColorAlt(LPCTSTR pszKey, LPCTSTR pszAlternateKey, COLORREF& crColor) const;
	CString		GetSkinFileItem(LPCTSTR lpszResourceName, LPCTSTR pszResourceType) const;
	void		ApplySkin(LPCTSTR pszSkinProfile);
	void		EnableRTLWindowsLayout();
	void		DisableRTLWindowsLayout();
	void		UpdateDesktopColorDepth();

	bool		GetLangHelpFilePath(CString& strResult);
	void		SetHelpFilePath(LPCTSTR pszHelpFilePath);
	void		ShowHelp(UINT uTopic, UINT uCmd = HELP_CONTEXT);
	bool		ShowWebHelp(UINT uTopic);

    // Elandal:ThreadSafeLogging -->
    // thread safe log calls
    void			QueueDebugLogLine(bool bAddToStatusBar, LPCTSTR line,...);
    void			QueueDebugLogLineEx(UINT uFlags, LPCTSTR line,...);
    void			HandleDebugLogQueue();
    void			ClearDebugLogQueue(bool bDebugPendingMsgs = false);

	void			QueueLogLine(bool bAddToStatusBar, LPCTSTR line,...);
    void			QueueLogLineEx(UINT uFlags, LPCTSTR line,...);
    void			HandleLogQueue();
    void			ClearLogQueue(bool bDebugPendingMsgs = false);
	// NEO: ML - [ModLog] -- Xanatos -->
    void			QueueModLogLine(bool addtostatusbar, LPCTSTR line,...);
	void			QueueModLogLineEx(UINT uFlags, LPCTSTR line,...);
    void			HandleModLogQueue();
    void			ClearModLogQueue(bool bDebugPendingMsgs = false);
	// NEO: ML END <-- Xanatos --
    // Elandal:ThreadSafeLogging <--

	CString			GetAppTitle(bool bE = false); // NEO: NV - [NeoVersion] <-- Xanatos --

	// NEO: SS - [SplashScreen] -- Xanatos -->
	void			ShowSplash();
	void			UpdateSplash(LPCTSTR Text);
	void			HideSplash();
	void			TopSplash(bool bTop);
	bool			IsSplash()		{ return (m_pSplashWnd != NULL); }
	// NEO SS END <-- Xanatos --

	bool			DidWeAutoStart() { return m_bAutoStart; }

	// NEO: UPNP - [UPnPNat] -- Xanatos -->
	BOOL			AddUPnPNatPort(MyUPnP::UPNPNAT_MAPPING *mapping, bool tryRandom = false);
	BOOL			RemoveUPnPNatPort(MyUPnP::UPNPNAT_MAPPING *mapping);
	// NEO: UPNP END <-- Xanatos --

#ifdef WS2 // NEO: WS2 - [WINSOCK2] -- Xanatos -->
	bool			WinSock2() {return m_bWinSock2;}
	bool			m_bWinSock2;
	WSADATA			m_wsaData;
#endif // WS2 // NEO: WS2 END <-- Xanatos --

protected:
	bool ProcessCommandline();
	void SetTimeOnTransfer();
	static BOOL CALLBACK SearchEmuleWindow(HWND hWnd, LPARAM lParam);

	DECLARE_MESSAGE_MAP()
	afx_msg void OnHelp();

	HIMAGELIST m_hSystemImageList;
	CMapStringToPtr m_aExtToSysImgIdx;
	CSize m_sizSmallSystemIcon;

	bool		m_bGuardClipboardPrompt;
	CString		m_strLastClipboardContents;

    // Elandal:ThreadSafeLogging -->
    // thread safe log calls
    CCriticalSection m_queueLock;
    CTypedPtrList<CPtrList, SLogItem*> m_QueueDebugLog;
    CTypedPtrList<CPtrList, SLogItem*> m_QueueLog;
	CTypedPtrList<CPtrList, SLogItem*> m_QueueModLog; // NEO: ML - [ModLog] <-- Xanatos --
    // Elandal:ThreadSafeLogging <--

	uint32 m_dwPublicIP;
	// NEO: RIC - [ReaskOnIDChange] -- Xanatos -->
	uint32	m_uLastIP;
	bool	m_bLastIDLow;
	uint32	m_uLastChangeID;
	// NEO: RIC END <-- Xanatos --
	bool m_bAutoStart;

private:
    UINT     m_wTimerRes;
};

extern CemuleApp theApp;


//////////////////////////////////////////////////////////////////////////////
// CTempIconLoader

class CTempIconLoader
{
public:
	// because nearly all icons we are loading are 16x16, the default size is specified as 16 and not as 32 nor LR_DEFAULTSIZE
	CTempIconLoader(LPCTSTR pszResourceID, int cx = 16, int cy = 16, UINT uFlags = LR_DEFAULTCOLOR);
	CTempIconLoader(UINT uResourceID, int cx = 16, int cy = 16, UINT uFlags = LR_DEFAULTCOLOR);
	~CTempIconLoader();

	operator HICON() const{
		return this == NULL ? NULL : m_hIcon;
	}

protected:
	HICON m_hIcon;
};
