#ifndef __FAR_PLUGIN_FTP_FTP
#define __FAR_PLUGIN_FTP_FTP

#define FTP_COL_MODE 0
#define FTP_COL_LINK 1

#define FTP_COL_MAX  2

#define FTP_MAXBACKUPS 10

struct FTPUrl
{
	FTPHost       Host;
	String        SrcPath;
	String        DestPath;
	String        Error;
	FAR_FIND_DATA FileName;
	BOOL          Download;
	FTPUrl*       Next;
};

struct FTPCopyInfo
{
	BOOL      asciiMode;
	BOOL      ShowProcessList;
	BOOL      AddToQueque;
	overCode  MsgCode;
	String    DestPath;
	String    SrcPath;   //Used only on queue processing
	BOOL      Download;
	BOOL      UploadLowCase;
	BOOL      FTPRename;

	FTPCopyInfo(void);
};

struct QueueExecOptions
{
	BOOL      RestoreState;
	BOOL      RemoveCompleted;
};

class FTP
{
		friend class FTPCmdBlock;
		String      SelectFile;
		BOOL        ResetCache;
		int         ShowHosts;
		int         SwitchingToFTP;
		char        HostsPath[1024];
		int         StartViewMode;
		int         RereadRequired;
		FTPCurrentStates CurrentState;
		char        IncludeMask[MAX_PATH];
		char        ExcludeMask[MAX_PATH];
		BOOL        PluginColumnModeSet;
		int         ActiveColumnMode;
		BOOL        NeedToSetActiveMode;
		FTPUrl*     UrlsList, *UrlsTail;
		int         QuequeSize;
		overCode    LastMsgCode,
		       OverrideMsgCode;
	public:
		FTPHost     Host;
		char        PanelTitle[512];
		HANDLE      LongBeep;
		HANDLE      KeepAlivePeriod;
		Connection *hConnect;
		int         CallLevel;
	private:
		int       Connect();
		void      CopyNamesToClipboard(void);
		int       DeleteFilesINT(PluginPanelItem *PanelItem,int ItemsNumber,int OpMode);
		int       GetFreeKeyNumber();
		void      GetFullFileName(char *FullName,char *Name);
		void      GetFullKey(char *FullKeyName,LPCSTR Name);
		int       GetHostFiles(struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,String& DestPath,int OpMode);
		void      GetNewKeyName(char *FullKeyName);
		int       HexToNum(int Hex);
		void      HexToPassword(char *HexStr,char *Password);
		void      MakeKeyName(char *FullKeyName,int Number);
		void      PasswordToHex(char *Password,char *HexStr);
		int       PutHostsFiles(struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,int OpMode);
		void      SaveURL();
		void      SelectFileTable(char *TableName);
		WORD      SelectServerType(WORD Type);
		void      SelectTable();
		void      SetAttributes();
		int       TableNameToValue(char *TableName);
	private:
		BOOL      EditDirectory(String& Name,char *Desc,BOOL newDir);
		void      FTP_FixPaths(LPCSTR base,PluginPanelItem *p,int cn,BOOL FromPlugin);
		void      FTP_FreeFindData(PluginPanelItem *PanelItem,int ItemsNumber,BOOL FromPlugin);
		BOOL      FTP_GetFindData(PluginPanelItem **PanelItem,int *ItemsNumber,BOOL FromPlugin);
		BOOL      FTP_SetDirectory(LPCSTR dir,BOOL FromPlugin);
		int       GetFilesInterface(struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,String& DestPath,int OpMode);
		BOOL      GetHost(int title,FTPHost* p,BOOL ToDescription);
		BOOL      Reread(void);
		int       PutFilesINT(struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,int OpMode);
		void      SaveUsedDirNFile(void);
		BOOL      ExecCmdLine(LPCSTR str, BOOL Prefix);
		BOOL      ExecCmdLineFTP(LPCSTR str, BOOL Prefix);
		BOOL      ExecCmdLineANY(LPCSTR str, BOOL Prefix);
		BOOL      ExecCmdLineHOST(LPCSTR str, BOOL Prefix);
		BOOL      DoCommand(LPCSTR str, int type, DWORD flags);
		BOOL      DoFtpConnect(int blocked);
	private:
		int       ExpandListINT(struct PluginPanelItem *PanelItem,int ItemsNumber,FP_SizeItemList* il,BOOL FromPlugin,ExpandListCB cb = NULL,LPVOID Param = NULL);
		int       ExpandList(struct PluginPanelItem *PanelItem,int ItemsNumber,FP_SizeItemList* il,BOOL FromPlugin,ExpandListCB cb = NULL,LPVOID Param = NULL);
		BOOL      CopyAskDialog(BOOL Move, BOOL Download,FTPCopyInfo* ci);
		BOOL      ShowFilesList(FP_SizeItemList* il);
		overCode  AskOverwrite(int title,BOOL Download,FAR_FIND_DATA* dest,FAR_FIND_DATA* src,overCode last,bool haveTimes);
		void      BackToHosts(void);
		BOOL      FullConnect();
		void      SaveList(FP_SizeItemList* il);
		BOOL      SetDirectoryStepped(LPCSTR Dir, BOOL update);
		void      InsertToQueue(void);
		LPCSTR  InsertCurrentToQueue(void);
		LPCSTR  InsertAnotherToQueue(void);
		BOOL      CheckDotsBack(const String& OldDir,const String& CmdDir);
		BOOL      FTPCreateDirectory(LPCSTR dir,int OpMode);

	private:
		int       _FtpGetFile(LPCSTR lpszRemoteFile,LPCSTR lpszNewFile,BOOL Reget,int AsciiMode);
		int       _FtpPutFile(LPCSTR lpszLocalFile,LPCSTR lpszNewRemoteFile,BOOL Reput,int AsciiMode);
	public:
		FTP();
		~FTP();
		int       DeleteFiles(struct PluginPanelItem *PanelItem,int ItemsNumber,int OpMode);
		void      FreeFindData(PluginPanelItem *PanelItem,int ItemsNumber);
		int       GetFiles(struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,String& DestPath,int OpMode);
		int       GetFindData(PluginPanelItem **pPanelItem,int *pItemsNumber,int OpMode);
		void      GetOpenPluginInfo(struct OpenPluginInfo *Info);
		int       MakeDirectory(String& Name,int OpMode);
		int       ProcessCommandLine(char *CommandLine);
		int       ProcessEvent(int Event,void *Param);
		int       ProcessKey(int Key,unsigned int ControlState);
		int       ProcessShortcutLine(char *Line);
		int       PutFiles(struct PluginPanelItem *PanelItem,int ItemsNumber,int Move,int OpMode);
		int       SetDirectory(LPCSTR Dir,int OpMode);

		int       SetDirectoryFAR(LPCSTR _Dir,int OpMode);

		void      Invalidate(void);
		void      GetCurPath(char *buff,int bsz);
		void      GetCurPath(String& buff);

		void      LongBeepEnd(BOOL DoNotBeep = FALSE);
		void      LongBeepCreate(void);
		BOOL      HostsMode(void)
		{
			return ShowHosts && !SwitchingToFTP;
		}
		BOOL      FTPMode(void)
		{
			return !HostsMode() && hConnect;
		}

		static FTP *Backups[ FTP_MAXBACKUPS ];
		static int  BackupCount;

		void      SetBackupMode(void);
		void      SetActiveMode(void);
		BOOL      isBackup(void);
		void      DeleteFromBackup(void);
		void      AddToBackup(void);

		LPCSTR  CloseQuery(void);

		FTPUrl*   UrlItem(int num, FTPUrl* *prev);
		void      UrlInit(FTPUrl* p);
		void      DeleteUrlItem(FTPUrl* p, FTPUrl* prev);
		BOOL      EditUrlItem(FTPUrl* p);

		void      AddToQueque(FAR_FIND_DATA* FileName, LPCSTR Path, BOOL Download);
		void      AddToQueque(FTPUrl* p,int pos = -1);
		void      ListToQueque(FP_SizeItemList* il,FTPCopyInfo* ci);
		void      ClearQueue(void);

		void      SetupQOpt(QueueExecOptions* op);
		BOOL      WarnExecuteQueue(QueueExecOptions* op);
		void      QuequeMenu(void);
		void      ExecuteQueue(QueueExecOptions* op);
		void      ExecuteQueueINT(QueueExecOptions* op);

		void Call(void);
		void End(int rc = -156);
};


extern void MakeCryptPassword(LPCSTR Src,BYTE Dest[FTP_PWD_LEN]);
extern void DecryptPassword(BYTE Src[FTP_PWD_LEN],char *Dest);

#endif
