#ifndef __FTP_PLUGINS_HOLDERS
#define __FTP_PLUGINS_HOLDERS

//------------------------------------------------------------------------
/* Number in array of interfaces [Plugin.cpp]
*/
#define PLUGIN_PROGRESS  0
#define PLUGIN_DIRLIST   1
#define PLUGIN_NOTIFY    2

//------------------------------------------------------------------------
struct FTPPluginHolder
{
	FTPPluginInterface* Interface;

	virtual BOOL Assign(FTPPluginInterface* Interface);
	virtual void Destroy(void);
	virtual ~FTPPluginHolder() = default;
};

extern BOOL             InitPlugins(void);
extern void             FreePlugins(void);
extern FTPPluginHolder* GetPluginHolder(WORD Number);
extern BOOL             PluginAvailable(WORD Number);

//------------------------------------------------------------------------
template <class Cl, WORD Index> struct FTPPlugin
{
	FTPPluginHolder* Holder;

	FTPPlugin(void)
	{
		Holder = GetPluginHolder(Index);
	}
	virtual ~FTPPlugin()
	{
		Holder = NULL;
	}

	Cl Interface(void)
	{
		Assert(Holder);
		Assert(Holder->Interface);
		return (Cl)Holder->Interface;
	}
};
//------------------------------------------------------------------------
struct FTPProgress : public FTPPlugin<ProgressInterface*,PLUGIN_PROGRESS>
{
	HANDLE Object;

	FTPProgress(void)
	{
		Object = NULL;
	}
	~FTPProgress()
	{
		if(Object)
		{
			Interface()->DestroyObject(Object);
			Object = NULL;
		}
	}

	void Resume(LPCSTR LocalFileName);
	void Resume(int64_t size);
	BOOL Callback(int Size);
	void Init(HANDLE Connection,int tMsg,int OpMode,FP_SizeItemList* il);
	void InitFile(int64_t sz, LPCSTR SrcName, LPCSTR DestName);
	void InitFile(PluginPanelItem *pi, LPCSTR SrcName, LPCSTR DestName);
	void InitFile(FAR_FIND_DATA* pi, LPCSTR SrcName, LPCSTR DestName);
	void Skip(void);
	void Waiting(time_t paused);
	void SetConnection(HANDLE Connection);
};

//------------------------------------------------------------------------
struct FTPDirList : public FTPPlugin<DirListInterface*,PLUGIN_DIRLIST>
{

	WORD     DetectStringType(FTPServerInfo* const Server,char *ListingString, int ListingLength);
	WORD     DetectDirStringType(FTPServerInfo* const Server,LPCSTR ListingString);
	WORD     GetNumberOfSupportedTypes(void);
	FTPType* GetType(WORD Index);
};

//------------------------------------------------------------------------
struct FTPNotify : public FTPPlugin<NotifyInterface*,PLUGIN_NOTIFY>
{

	void     Notify(const FTNNotify* p);
};

#endif
