#pragma once

#include "util.h"
#include "http_client.h"

CLASS_DECLSPEC void SetMaxDownloadThread(int thread);

class CLASS_DECLSPEC BitcasaAPI
{
private:
	HttpsClient bitcasa;
	std::string cookie;
	std::string referrer;
public:
	std::wstring access_token;

	BitcasaAPI();
	~BitcasaAPI();
	bool prepare();

	////////////////////////////////////////
	int authenticate();
	int authenticate_Web();
	int Grant_token(std::string auth_code);

	pjson GetUserProfile();

	///////////////////////////////////////
	pjson ListFolder(std::string encoded_path = "/", bool deep = false);
	inline pjson ListFolder(std::wstring encoded_path){
		return ListFolder(WideChartoUTF8(encoded_path));
	}
	bool AddFolder(std::string encoded_path, std::wstring newfoldername);
	inline bool AddFolder(const std::wstring &encoded_path, const std::wstring &newfoldername){
		return AddFolder(WideChartoUTF8(encoded_path), newfoldername);
	}
	bool DeleteFolder(std::string encoded_path);
	inline bool DeleteFolder(const std::wstring &encoded_path){
		return DeleteFolder(WideChartoUTF8(encoded_path));
	}
	bool RenameFolder(std::string encoded_path_old, std::wstring newfoldername);
	inline bool RenameFolder(const std::wstring &encoded_path_old, const std::wstring &newfoldername){
		return RenameFolder(WideChartoUTF8(encoded_path_old), newfoldername);
	}
	typedef enum { copy, move } copymode;
	bool CopyMoveFolder(std::string encoded_path_old, std::string encoded_path_new, std::wstring newfoldername, copymode mode);
	inline bool CopyMoveFolder(const std::wstring &encoded_path_old, const std::wstring &encoded_path_new, const std::wstring &newfoldername, copymode mode){
		return CopyMoveFolder(WideChartoUTF8(encoded_path_old), WideChartoUTF8(encoded_path_new), newfoldername, mode);
	}

	///////////////////////////////////////
	bool UploadFile(std::string encoded_path, std::wstring infilename, void(CALLBACK *callback)(INT64) = NULL);
	inline bool UploadFile(std::wstring encoded_path, std::wstring infilename){
		return UploadFile(WideChartoUTF8(encoded_path), infilename);
	}
	bool DownloadFile(std::string encoded_file_path, std::ostream& out, INT64 wantSize = -1, void(CALLBACK *callback)(INT64 trans) = NULL);
	bool DownloadFile(std::string encoded_file_path, std::wstring filename, INT64 wantSize = -1, void(CALLBACK *callback)(INT64 trans) = NULL);
	inline bool DownloadFile(const std::wstring &encoded_file_path, const std::wstring &filename, INT64 wantSize = -1){
		return DownloadFile(WideChartoUTF8(encoded_file_path), filename, wantSize);
	}
	bool _DeleteFile(std::string encoded_path);
	inline bool _DeleteFile(const std::wstring &encoded_path){
		return _DeleteFile(WideChartoUTF8(encoded_path));
	}
	bool RenameFile(std::string encoded_path_old, std::wstring newfilename);
	inline bool RenameFile(const std::wstring &encoded_path_old, const std::wstring &newfilename){
		return RenameFile(WideChartoUTF8(encoded_path_old), newfilename);
	}
	bool CopyMoveFile(std::string encoded_path_old, std::string encoded_path_new, std::wstring newfilename, copymode mode);
	inline bool CopyMoveFile(const std::wstring &encoded_path_old, const std::wstring &encoded_path_new, const std::wstring &newfilename, copymode mode){
		return CopyMoveFile(WideChartoUTF8(encoded_path_old), WideChartoUTF8(encoded_path_new), newfilename, mode);
	}
};
