//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
#include "MapKey.h"

class CKnownFileList;
class CServerConnect;
class CPartFile;
class CKnownFile;
class CPublishKeywordList;
class CSafeMemFile;
class CServer;
class CLocalFilesDialog; // NEO: XSF - [ExtendedSharedFiles] <-- Xanatos --

struct UnknownFile_Struct{
	CString strName;
	CString strDirectory;
};

// NEO: ASP - [ActiveSpreading] -- Xanatos -->
namespace Kademlia 
{
	class CUInt128;
};
// NEO: ASP END <-- Xanatos --

class CSharedFileList
{
	friend class CSharedFilesCtrl;
	friend class CClientReqSocket;

public:
	CSharedFileList(CServerConnect* in_server);
	~CSharedFileList();

	void	SendListToServer();
	void	Reload();
	bool	SafeAddKFile(CKnownFile* toadd, bool bOnlyAdd = false);
	void	RepublishFile(CKnownFile* pFile);
	void	SetOutputCtrl(CSharedFilesCtrl* in_ctrl);
	bool	RemoveFile(CKnownFile* toremove);
	CKnownFile* GetFileByID(const uchar* filehash) const;
	CKnownFile*	GetFileByIndex(int index);
	CKnownFile* GetFileByKadFileSearchID(uint32 id) const; // NEO: ASP - [ActiveSpreading] <-- Xanatos --
	bool	IsFilePtrInList(const CKnownFile* file) const;
	void	PublishNextTurn()	{ m_lastPublishED2KFlag=true;	}
	void	CreateOfferedFilePacket(CKnownFile* cur_file, CSafeMemFile* files, CServer* pServer, CUpDownClient* pClient = NULL);
	uint64	GetDatasize(uint64 &pbytesLargest) const;
	int		GetCount()	{return m_Files_map.GetCount(); }
	int		GetHashingCount()	{return waitingforhash_list.GetCount()+currentlyhashing_list.GetCount(); }	// SLUGFILLER SafeHash
	void	UpdateFile(CKnownFile* toupdate);
	void	AddFilesFromDirectory(const CString& rstrDirectory, bool bWithSubdir = false); // NEO: SSD - [ShareSubDirectories] <-- Xanatos --
	void	AddFileToShare(CFileFind &ff, CString realDirName, const CString rstrDirectory); // NEO: SSF - [ShareSingleFiles] <-- Xanatos --
	void	AddFileFromNewlyCreatedCollection(const CString& path, const CString& fileName);
	void	HashFailed(UnknownFile_Struct* hashed);		// SLUGFILLER: SafeHash
	void	FileHashingFinished(CKnownFile* file);
	void	ClearED2KPublishInfo();
	void	ClearKadSourcePublishInfo();
	void	Process();
	void	Publish();
	void	AddKeywords(CKnownFile* pFile);
	void	RemoveKeywords(CKnownFile* pFile);
	void	DeletePartFileInstances() const;
	bool	IsUnsharedFile(const uchar* auFileHash) const;
	void	CopySharedFileMap(CMap<CCKey,const CCKey&,CKnownFile*,CKnownFile*> &Files_Map);
	// NEO: XSF - [ExtendedSharedFiles] -- Xanatos -->
	void	ShowLocalFilesDialog(bool reloadOnly = false);
	void	LocalFilesDialogClosed();
	// NEO: XSF END <-- Xanatos --
	CMap<CCKey,const CCKey&,CKnownFile*,CKnownFile*>* GetFileMap() {return &m_Files_map;} // NEO: MOD <-- Xanatos --
	// NEO: NCAP - [NeoCustomAutoPriority] -- Xanatos -->
	uint32  GetGlobalSourceCount()	{return m_uGlobalSourceCount;} 
	uint32  GetTopSourceCount()		{return m_uTopSourceCount;} 
	uint32  GetBotomSourceCount()	{return m_uBotomSourceCount;} 
	// NEO: NCAP END <-- Xanatos --
	// NEO: XCk - [ExtendedKnownComments] -- Xanatos -->
	uint32  GetLastPublishKadNotes()				{return m_lastPublishKadNotes;} 
	void	SetLastPublishKadNotes(uint32 tNext)	{m_lastPublishKadNotes = tNext;} 
	// NEO: XCk END <-- Xanatos --
	void	KademliaSearchFile(CKnownFile* temp, const Kademlia::CUInt128* pcontactID, const Kademlia::CUInt128* pkadID, uint8 type, uint32 ip, uint16 tcp, uint16 udp, uint32 serverip, uint16 serverport, uint8 byCryptOptions); // NEO: ASP - [ActiveSpreading] <-- Xanatos --

	CMutex	m_mutWriteList;
private:
	bool	AddFile(CKnownFile* pFile);
	void	FindSharedFiles();
	void	HashNextFile();
	// SLUGFILLER: SafeHash
	bool	IsHashing(const CString& rstrDirectory, const CString& rstrName);
	void	RemoveFromHashing(CKnownFile* hashed);
	// SLUGFILLER: SafeHash

	CMap<CCKey,const CCKey&,CKnownFile*,CKnownFile*> m_Files_map;
	CMap<CSKey,const CSKey&, bool, bool>			 m_UnsharedFiles_map;
	CPublishKeywordList* m_keywords;
	CTypedPtrList<CPtrList, UnknownFile_Struct*> waitingforhash_list;
	CTypedPtrList<CPtrList, UnknownFile_Struct*> currentlyhashing_list;	// SLUGFILLER: SafeHash
	CServerConnect*		server;
	CSharedFilesCtrl*	output;
	CLocalFilesDialog*	m_dialog; // NEO: XSF - [ExtendedSharedFiles] <-- Xanatos --

	uint32 m_lastPublishED2K;
	bool	 m_lastPublishED2KFlag;
	int m_currFileSrc;
	int m_currFileNotes;
	int m_currFileKey;
	uint32 m_lastPublishKadSrc;
	uint32 m_lastPublishKadNotes;
	uint32 m_lastReload; // NEO: SSD - [ShareSubDirectories] <-- Xanatos --

	// NEO: NCAP - [NeoCustomAutoPriority] -- Xanatos -->
	uint32 m_uGlobalSourceCount;
	uint32 m_uTopSourceCount;
	uint32 m_uBotomSourceCount; 
	// NEO: NCAP END <-- Xanatos --
};

class CAddFileThread : public CWinThread
{
	DECLARE_DYNCREATE(CAddFileThread)
protected:
	CAddFileThread();
public:
	virtual BOOL InitInstance();
	virtual int	Run();
	void	SetValues(CSharedFileList* pOwner, LPCTSTR directory, LPCTSTR filename, CPartFile* partfile = NULL);

private:
	CSharedFileList* m_pOwner;
	CString			 m_strDirectory;
	CString			 m_strFilename;
	CPartFile*		 m_partfile;
};
