//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 "BarShader.h"
#include "StatisticFile.h"
#include "AbstractFile.h"
#include "Neo/FilePreferences.h" // NEO: FCFG - [FileConfiguration] <-- Xanatos --
#include <list>

class CxImage;
class CUpDownClient;
class CSafeMemFile; // NEO: IPS - [InteligentPartSharing] <-- Xanatos --
class Packet;
class CFileDataIO;
class CAICHHashTree;
class CAICHHashSet;
class CCollection;
class CSafeMemFile;
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface] -- Xanatos -->
class CVoodooSocket;
class CMasterDatas;
#endif // VOODOO // NEO: VOODOO END <-- Xanatos --
class CClientFileStatus; // NEO: SCFS - [SmartClientFileStatus] <-- Xanatos --
struct ExportInfo; // NEO: PIX - [PartImportExport] <-- Xanatos --
enum EPartStatus; // NEO: SCFS - [SmartClientFileStatus] <-- Xanatos --

typedef CTypedPtrList<CPtrList, CUpDownClient*> CUpDownClientPtrList;
enum EFileType;

// NEO: IPS - [InteligentPartSharing] -- Xanatos -->
#pragma pack(1)
struct TPartOL{
	UINT	Part;
	double	OL;
};
#pragma pack()
// NEO: IPS END <-- Xanatos --

// NEO: RBT - [ReadBlockThread] -- Xanatos -->
struct ReadBlockOrder
{
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface]
	ReadBlockOrder(uint64 startOffset, uint32 toread, CObject* client, void* request, bool voodoo = false)
#else
	ReadBlockOrder(uint64 startOffset, uint32 toread, CObject* client, void* request)
#endif // VOODOO // NEO: VOODOO END
	{
		StartOffset = startOffset;
		togo = toread;
		m_client = client;
		m_request = request;
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface]
		m_voodoo = voodoo;
#endif // VOODOO // NEO: VOODOO END
	}
	uint64			StartOffset;
	uint32			togo;
	CObject*		m_client;
	void*			m_request;
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface]
	bool			m_voodoo;
#endif // VOODOO // NEO: VOODOO END
};

#define _RBT_ACTIVE_	-2
#define RBT_ACTIVE		(byte*)_RBT_ACTIVE_
#define _RBT_ERROR_		-1
#define RBT_ERROR		(byte*)_RBT_ERROR_

class CReadBlockFromFileThread : public CWinThread
{
	DECLARE_DYNCREATE(CReadBlockFromFileThread)
protected:
	CReadBlockFromFileThread()	{}

	friend class CKnownFile;
	CFile file;
public:
	virtual	BOOL	InitInstance() {return true;}
	virtual int		Run();
	void			SetKnownFile(CKnownFile* pOwner);
private:
	CKnownFile*		m_pOwner;
	CString			fullname;
};
// NEO: RBT END <-- Xanatos --

class CKnownFile : public CAbstractFile
{
	DECLARE_DYNAMIC(CKnownFile)

public:
	friend class CReadBlockFromFileThread; // NEO: RBT - [ReadBlockThread] <-- Xanatos --

	CKnownFile();
	virtual ~CKnownFile();

	CString GetFileName(bool forceReal = false) const; // NEO: PP - [PasswordProtection] <-- Xanatos --
	virtual void SetFileName(LPCTSTR pszFileName, bool bReplaceInvalidFileSystemChars = false); // 'bReplaceInvalidFileSystemChars' is set to 'false' for backward compatibility!

	CString GetPath(bool returnVirtual = false) const; // NEO: VSF - [VirtualSharedFiles] <-- Xanatos --
	//const CString& GetPath() const { return m_strDirectory; }
	void SetPath(LPCTSTR path);

	const CString& GetFilePath() const { return m_strFilePath; }
	void SetFilePath(LPCTSTR pszFilePath);

	bool	CreateFromFile(LPCTSTR directory, LPCTSTR filename, LPVOID pvProgressParam); // create date, hashset and tags from a file
	bool	LoadFromFile(CFileDataIO* file);	//load date, hashset and tags from a .met file
	bool	WriteToFile(CFileDataIO* file);
	// NEO: PIX - [PartImportExport] -- Xanatos -->
	bool	ExportParts(const CList<uint16>* PartList);
	BOOL	PerformExportParts(ExportInfo* Instructions); 
	// NEO: PIX END <-- Xanatos --
	bool	CreateAICHHashSetOnly();

	EFileType GetVerifiedFileType() { return m_verifiedFileType; }
	void	  SetVerifiedFileType(EFileType in) { m_verifiedFileType=in; }

	// last file modification time in (DST corrected, if NTFS) real UTC format
	// NOTE: this value can *not* be compared with NT's version of the UTC time
	CTime	GetUtcCFileDate() const { return CTime(m_tUtcLastModified); }
	uint32	GetUtcFileDate() const { return m_tUtcLastModified; }

	virtual void SetFileSize(EMFileSize nFileSize);

	// local available part hashs
	UINT	GetHashCount() const { return hashlist.GetCount(); }
	uchar*	GetPartHash(UINT part) const;
	const CArray<uchar*, uchar*>& GetHashset() const { return hashlist; }
	bool	SetHashset(const CArray<uchar*, uchar*>& aHashset);

	// nr. of part hashs according the file size wrt ED2K protocol
	uint16	GetED2KPartHashCount() const { return m_iED2KPartHashCount; }

	// nr. of 9MB parts (file data)
	__inline uint16 GetPartCount() const { return m_iPartCount; }

	// nr. of 9MB parts according the file size wrt ED2K protocol (OP_FILESTATUS)
	__inline uint16 GetED2KPartCount() const { return m_iED2KPartCount; }

	// size of part, all are 9 MB but the last part may be smaller
	uint32	GetPartSize(UINT part) const; // NEO: MOD <-- Xanatos --

	// file upload priority
	uint8	GetUpPriority(void) const { return m_iUpPriority; }
	void	SetUpPriority(uint8 iNewUpPriority, bool bSave = true);
	bool	IsAutoUpPriority(void) const { return m_bAutoUpPriority; }
	void	SetAutoUpPriority(bool NewAutoUpPriority) { m_bAutoUpPriority = NewAutoUpPriority; }
	void	UpdateAutoUpPriority();
	// NEO: RT - [ReleaseTweaks] -- Xanatos -->
	float	GetReleaseModifyer(void);
	void	SetReleaseModifyer(float fModifyer) { if(fModifyer<1) m_fReleaseModifyer = 1; else m_fReleaseModifyer = fModifyer; }
	bool	IsReleasePriority(bool bCat = false);
	bool	GetReleasePriority();
	bool	GetPowerShared();
	void	SetReleasePriority(bool bReleasePriority, bool bSave = true);
	void	CalcRelease(bool bFlag = false);
	// NEO: RT END <-- Xanatos --

	// NEO: USC - [UnShareCommand] -- Xanatos -->
	void	SetUnshared(uint8 uSet)			{ m_uUnshared = uSet; }
	bool	IsUnshared(bool b = false)		{ return (m_uUnshared != 0 && !b) || m_uUnshared == 1; }
	// NEO: USC END <-- Xanatos --
	virtual bool Publishable()				{ return /*true*/ IsUnshared() == false; } // NEO: SEF - [ShareAlsoEmptyFiles] <-- Xanatos --

#ifndef A4AF_CATS // NEO: MAC - [MorphA4AFCategories] -- Xanatos -->
	uint8	GetUpPriorityEx(void) const; // NEO: NRT - [NeoReleaserTweaks]
#endif // A4AF_CATS // NEO: MAC END <-- Xanatos --

	// This has lost it's meaning here.. This is the total clients we know that want this file..
	// Right now this number is used for auto priorities..
	// This may be replaced with total complete source known in the network..
	uint32	GetQueuedCount() { return m_ClientUploadList.GetCount();}

	// NEO: IPS - [InteligentPartSharing] -- Xanatos -->
	uint8	GetPartState(UINT part) const;
	bool	WritePartSelection(CSafeMemFile* file, CClientFileStatus* status); // NEO: SCFS - [SmartClientFileStatus]
	void	WriteRealPartStatus(CSafeMemFile* file, uint8 type) const; // NEO: RPS - [RealPartStatus]
	bool	HaveRealInfo(uint8 type); // NEO: RPS - [RealPartStatus]

	uint8	GetIPSPartStatus(UINT part) const;
	void	SetIPSPartStatus(UINT part, uint8 state) { m_IPSPartStatus[part] = state; } 

	void	ResetIPSList();
	void	GetHideMap(CClientFileStatus* status, CMap<UINT, UINT, BOOL, BOOL> &GetHideMap); // NEO: SCFS - [SmartClientFileStatus]
	void	ReCalculateIPS();
	void	CalculateIPS();

	double	GetPartSharedEx(uint16 part);
	uint16	GetPartAvailibilityEx(uint16 i);
	// NEO: IPS END <-- Xanatos --

	// NEO: SSP - [ShowSharePermissions] -- Xanatos -->
	uint8	GetPermissions(void) const	{ return m_iPermissions; };
	void	SetPermissions(uint8 iNewPermissions) {m_iPermissions = iNewPermissions;};
	// NEO: SSP END <-- Xanatos --

	bool	LoadHashsetFromFile(CFileDataIO* file, bool checkhash);

	void	AddUploadingClient(CUpDownClient* client);
	void	RemoveUploadingClient(CUpDownClient* client);
	virtual void	UpdatePartsInfo(bool bFlag = false); // NEO: IPS - [InteligentPartSharing] <-- Xanatos --
	virtual void	UpdatePartsInfoEx(EPartStatus type); // NEO: SCFS - [SmartClientFileStatus] <-- Xanatos --
	virtual	void	DrawShareStatusBar(CDC* dc, LPCRECT rect, bool onlygreyrect, bool bFlat) const;
	virtual	void	DrawShareStatusBarNew(CDC* dc, LPCRECT rect, bool onlygreyrect, bool bFlat) const; // NEO: MOD <-- Xanatos --

	virtual uint16	GetPartAvailibility(uint16 i) const			{return (m_AvailPartFrequency.IsEmpty()			? 0 : m_AvailPartFrequency[i]);			} // NEO: NPT - [NeoPartTraffic]  <-- Xanatos --
	virtual uint16	GetIncPartAvailibility(uint16 i) const		{return (m_AvailIncPartFrequency.IsEmpty()		? 0 : m_AvailIncPartFrequency[i]);		} // NEO: ICS - [InteligentChunkSelection]  <-- Xanatos --
	virtual uint16	GetHidenPartAvailibility(uint16 i) const	{return (m_AvailHidenPartFrequency.IsEmpty()	? 0 : m_AvailHidenPartFrequency[i]);	} // NEO: RPS - [RealPartStatus]  <-- Xanatos --
	virtual uint16	GetBlockedPartAvailibility(uint16 i) const	{return (m_AvailBlockedPartFrequency.IsEmpty()	? 0 : m_AvailBlockedPartFrequency[i]);	} // NEO: RPS - [RealPartStatus]  <-- Xanatos --
	virtual uint16	GetSeenPartAvailibility(uint16 i) const		{return (m_AvailSeenPartFrequency.IsEmpty()		? 0 : m_AvailSeenPartFrequency[i]);		} // NEO: AHOS - [AntiHideOS]  <-- Xanatos --

	// NEO: NSC - [NeoSharedCategories] -- Xanatos -->
	int		GetCategory() const;
	void	SetCategory(int cat);
	// NEO: NSC END <-- Xanatos --

	// comment
	void	SetFileComment(LPCTSTR pszComment);

	void	SetFileRating(UINT uRating);

	bool	GetPublishedED2K() const { return m_PublishedED2K; }
	void	SetPublishedED2K(bool val);

	// NEO: KII - [KadInterfaceImprovement] -- Xanatos --
	//uint32	GetKadFileSearchID() const { return kadFileSearchID; }
	//void	SetKadFileSearchID(uint32 id) { kadFileSearchID = id; } //Don't use this unless you know what your are DOING!! (Hopefully I do.. :)

	const Kademlia::WordList& GetKadKeywords() const { return wordlist; }

	uint32	GetLastPublishTimeKadSrc() const { return m_lastPublishTimeKadSrc; }
	void	SetLastPublishTimeKadSrc(uint32 time, uint32 buddyip) { m_lastPublishTimeKadSrc = time; m_lastBuddyIP = buddyip;}
	uint32	GetLastPublishBuddy() const { return m_lastBuddyIP; }
	void	SetLastPublishTimeKadNotes(uint32 time) {m_lastPublishTimeKadNotes = time;}
	uint32	GetLastPublishTimeKadNotes() const { return m_lastPublishTimeKadNotes; }

	// NEO: ASP - [ActiveSpreading] -- Xanatos -->
	void	SetActiveSpread() { m_lastActiveSpreadTime = ::GetTickCount(); m_iXSAnswerCount = 0; }
	uint32	GetLastActiveSpreadTime() const	{ return m_lastActiveSpreadTime; }
	void	AddXSAnswerCount() { m_iXSAnswerCount++; }
	bool	CanCheckXSSources(CUpDownClient* pClient);

	// NEO: ASP - [ActiveSpreading] -- Xanatos -->
	void	ActiveSpread(CSafeMemFile* sources, uint32 serverip, uint16 serverport, bool bWithObfuscationAndHash);
	void	ActiveSpread(CSafeMemFile* sources, uint8 uClientSXVersion, const CUpDownClient* pClient);
	// NEO: ASP END <-- Xanatos --

	bool	PublishSrc();
	bool	PublishNotes();

	// file sharing
	virtual Packet* CreateSrcInfoPacket(const CUpDownClient* forClient) const;
	UINT	GetMetaDataVer() const { return m_uMetaDataVer; }
	void	UpdateMetaDataTags();
	void	RemoveMetaDataTags();

	// preview
	bool	IsMovie() const;
	virtual bool GrabImage(uint8 nFramesToGrab, double dStartTime, bool bReduceColor, uint16 nMaxWidth, void* pSender);
	virtual void GrabbingFinished(CxImage** imgResults, uint8 nFramesGrabbed, void* pSender);

	// aich
	CAICHHashSet*	GetAICHHashset() const							{return m_pAICHHashSet;}
	void			SetAICHHashset(CAICHHashSet* val)				{m_pAICHHashSet = val;}

	bool	CreateHash(const uchar* pucData, uint32 uSize, uchar* pucHash, CAICHHashTree* pShaHashOut = NULL) const; // NEO: PIX - [PartImportExport] <-- Xanatos --


	// last file modification time in (DST corrected, if NTFS) real UTC format
	// NOTE: this value can *not* be compared with NT's version of the UTC time
	uint32	m_tUtcLastModified;

	CStatisticFile statistic;
	time_t m_nCompleteSourcesTime;
	uint32 m_nCompleteSourcesSize; // NEO: MOD - [RelativeChunkDisplay] <-- Xanatos --
	uint16 m_nCompleteSourcesCount;
	uint16 m_nCompleteSourcesCountLo;
	uint16 m_nCompleteSourcesCountHi;
	CUpDownClientPtrList m_ClientUploadList;
	CArray<uint16, uint16> m_AvailPartFrequency;
	CArray<uint16, uint16> m_AvailIncPartFrequency; // NEO: ICS - [InteligentChunkSelection] <-- Xanatos --
	CArray<uint16, uint16> m_AvailHidenPartFrequency; // NEO: RPS - [RealPartStatus] <-- Xanatos --
	CArray<uint16, uint16> m_AvailBlockedPartFrequency; // NEO: RPS - [RealPartStatus] <-- Xanatos --
	CArray<uint16, uint16> m_AvailSeenPartFrequency; // NEO: AHOS - [AntiHideOS] <-- Xanatos --
	CCollection* m_pCollection;

	int		m_category; // NEO: NSC - [NeoSharedCategories] <-- Xanatos --

	// NEO: XC - [ExtendedComments] -- Xanatos -->
	bool	LoadComments(CFileDataIO* file);
	bool	SaveComments(CFileDataIO* file);
	bool	HasComments()	{ return !m_CommentList.IsEmpty(); }
	// NEO: XC END <-- Xanatos --

	// NEO: RBT - [ReadBlockThread] -- Xanatos -->
#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface]
	bool	SetReadBlockFromFile(uint64 startOffset, uint32 toread, CObject* client, void* request, bool voodoo = false); 
#else
	bool	SetReadBlockFromFile(uint64 startOffset, uint32 toread, CObject* client, void* request);
#endif // VOODOO // NEO: VOODOO END
	// NEO: RBT END <-- Xanatos --

	// NEO: MKN - [MergeKnown] -- Xanatos -->
	void	SetLastSeen()	{ m_dwLastSeen = time(NULL); }
	uint32	GetLastSeen()	{ return m_dwLastSeen; }
	// NEO: MKN END <-- Xanatos --

	// NEO: MQ - [MultiQueue] -- Xanatos -->
	uint32	GetStartUploadTime() const {return m_startUploadTime;}
	void	UpdateStartUploadTime() {m_startUploadTime = GetTickCount();}
	// NEO: MQ END <-- Xanatos --

	// NEO: PP - [PasswordProtection] -- Xanatos -->
	void	LoadProtection();
	CString	GetPWProt()						{ if (!m_bProtectionLoaded) LoadProtection(); return m_pwProt; }
	void	SetPWProt( CString iNewPW );
	bool	IsPWProt() const;
	void	SetPWProtShow(bool in)			{ m_isPWProtShow=in; }
	bool	IsPWProtHidden() const			{ return IsPWProt() && !m_isPWProtShow; }
	// NEO: PP END <-- Xanatos --

#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface] -- Xanatos -->
	virtual bool IsVoodooFile() const {return (!m_MasterMap.IsEmpty());}
	virtual void AddMaster(CVoodooSocket* Master);
	virtual void RemoveMaster(CVoodooSocket* Master);
	CMasterDatas* GetMasterDatas(CVoodooSocket* Master);
	CVoodooSocket* GetAnyMaster();
	bool	IsRealFile() const;
#endif // VOODOO // NEO: VOODOO END <-- Xanatos --

	// NEO: CRC - [MorphCRCTag] -- Xanatos -->
	bool	IsCRCOk() const;
	bool    IsCRC32Calculated() 		{return m_CRC32[0] || m_CRC32[1] || m_CRC32[2] || m_CRC32[3];}
	BYTE*	GetCalculatedCRC32() 		{return m_CRC32;}
	//void    SetLastCalculatedCRC32 (const BYTE* CRC32) {memcpy(&m_CRC32,CRC32,sizeof(BYTE)*4);}
	// NEO: CRC END <-- Xanatos --

	virtual void GetTooltipFileInfo(CString &info); // NEO: NTT - [NewToolTips] <-- Xanatos --

#ifdef WEBCACHE // NEO: WC - [WebCache] -- Xanatos -->
	uint32 GetNumberOfClientsRequestingThisFileUsingThisWebcache(CString webcachename, uint32 maxCount); //JP webcache release
	void SetReleaseViaWebCache(bool WCRelease) {ReleaseViaWebCache=WCRelease;} //JP webcache release
	bool GetReleaseViaWebCache() {return ReleaseViaWebCache;} //JP webcache release
#endif // NEO: WC END <-- Xanatos --

	CKnownPreferences KnownPrefs; // NEO: FCFG - [FileConfiguration] <-- Xanatos --

#ifdef _DEBUG
	// Diagnostic Support
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:
	//preview
	bool	GrabImage(CString strFileName, uint8 nFramesToGrab, double dStartTime, bool bReduceColor, uint16 nMaxWidth, void* pSender);
	bool	LoadTagsFromFile(CFileDataIO* file);
	bool	LoadDateFromFile(CFileDataIO* file);
	void	CreateHash(CFile* pFile, uint64 uSize, uchar* pucHash, CAICHHashTree* pShaHashOut = NULL, bool bLock = true) const; // NEO: SSH - [SlugFillerSafeHash] <-- Xanatos --
	bool	CreateHash(FILE* fp, uint64 uSize, uchar* pucHash, CAICHHashTree* pShaHashOut = NULL) const;
	//bool	CreateHash(const uchar* pucData, uint32 uSize, uchar* pucHash, CAICHHashTree* pShaHashOut = NULL) const; // NEO: PIX - [PartImportExport] <-- Xanatos --
	virtual void	UpdateFileRatingCommentAvail(bool bForceUpdate = false);

	CArray<uchar*, uchar*>	hashlist;
	CString					m_strDirectory;
	CString					m_strFilePath;
	CAICHHashSet*			m_pAICHHashSet;

	// NEO: RBT - [ReadBlockThread] -- Xanatos -->
	CList<ReadBlockOrder*,ReadBlockOrder*> m_BlocksToRead;
	CCriticalSection m_BlocksToReadLocker;
	CWinThread* m_ReadThread;
	// NEO: RBT END <-- Xanatos --

#ifdef VOODOO // NEO: VOODOO - [UniversalPartfileInterface] -- Xanatos -->
	CMap<CVoodooSocket*,CVoodooSocket*,CMasterDatas*,CMasterDatas*> m_MasterMap;
#endif // VOODOO // NEO: VOODOO END <-- Xanatos --

private:
	static CBarShader s_ShareStatusBar;
	uint16	m_iPartCount;
	uint16	m_iED2KPartCount;
	uint16	m_iED2KPartHashCount;
	uint8	m_iUpPriority;
	// NEO: RT - [ReleaseTweaks] -- Xanatos -->
	bool	m_bReleasePriority;
	float	m_fReleaseModifyer;
	bool	m_bReleaseHalted;
	bool	m_bPowerShared;
	// NEO: RT END - [ReleaseTweaks] <-- Xanatos --
	uint8	m_uUnshared; // NEO: USC - [UnShareCommand] <-- Xanatos --
	uint8	m_iPermissions; // NEO: SSP - [ShowSharePermissions] <-- Xanatos --
	bool	m_bAutoUpPriority;
	bool	m_PublishedED2K;
	//uint32	kadFileSearchID; // NEO: KII - [KadInterfaceImprovement] <-- Xanatos --
	uint32	m_lastPublishTimeKadSrc;
	uint32	m_lastPublishTimeKadNotes;
	uint32	m_lastBuddyIP;
	// NEO: ASP - [ActiveSpreading] -- Xanatos -->
	uint32	m_lastActiveSpreadTime;
	int		m_iXSAnswerCount;
	// NEO: ASP END <-- Xanatos --
	Kademlia::WordList wordlist;
	UINT	m_uMetaDataVer;
	EFileType m_verifiedFileType;

	// NEO: IPS - [InteligentPartSharing] -- Xanatos -->
	DWORD	m_uLastIPSCalcTime;
	uint16	m_uIPSCalcCount;
	CMap<UINT, UINT, uint8, uint8> m_IPSPartStatus;
	CArray<TPartOL,TPartOL> *m_IPSPartsInfo;
	// NEO: IPS END <-- Xanatos --

	uint32	m_uLastReleaseModifyer; // NEO: RT - [ReleaseTweaks] <-- Xanatos --

	uint32	m_dwLastSeen; // NEO: MKN - [MergeKnown] <-- Xanatos --

	uint32  m_startUploadTime; // NEO: MQ - [MultiQueue] <-- Xanatos --

	// NEO: PP - [PasswordProtection] -- Xanatos -->
	bool	m_bProtectionLoaded;
	CString	m_pwProt;
	bool	m_isPWProtShow;
	// NEO: PP END <-- Xanatos --

	BYTE    m_CRC32[4]; // NEO: CRC - [MorphCRCTag] <-- Xanatos --

#ifdef WEBCACHE // NEO: WC - [WebCache] -- Xanatos -->
	bool ReleaseViaWebCache; //JP webcache release
#endif // NEO: WC END <-- Xanatos --
};

// NEO: SSP - [ShowSharePermissions] -- Xanatos -->
#define PERM_DEFAULT	255 //-1
#define PERM_ALL		0
#define PERM_FRIENDS	1
#define PERM_NONE		2
#define PERM_COMMUNITY	3
// NEO: SSP END <-- Xanatos --
