// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Types/BaseTypes.h"
#include "Engine/Platform/Types.h"
///
/// Specifies whether to search the current directory, or the current directory and all subdirectories.
///
enum class DirectorySearchOption
{
///
/// Includes the current directory and all its subdirectories in a search operation.This option includes reparse points such as mounted drives and symbolic links in the search.
///
AllDirectories,
///
/// Includes only the current directory in a search operation.
///
TopDirectoryOnly,
};
///
/// Special system folder types.
///
enum class SpecialFolder
{
Desktop,
Documents,
Pictures,
AppData,
LocalAppData,
ProgramData,
Temporary,
};
API_INJECT_CODE(cpp, "#include \"Engine/Platform/FileSystem.h\"");
///
/// Platform implementation of filesystem service.
///
API_CLASS(Static, Name="FileSystem", Tag="NativeInvokeUseName")
class FLAXENGINE_API FileSystemBase
{
DECLARE_SCRIPTING_TYPE_MINIMAL(FileSystemBase);
///
/// Creates a new directory.
///
/// Directory path
/// True if failed to create directory, otherwise false.
static bool CreateDirectory(const StringView& path) = delete;
///
/// Deletes an existing directory.
///
/// Directory path
/// True if delete all subdirectories and files, otherwise false.
/// True if failed to delete directory, otherwise false.
static bool DeleteDirectory(const String& path, bool deleteContents = true) = delete;
///
/// Checks if directory exists.
///
/// Directory path.
/// True if directory exists, otherwise false.
static bool DirectoryExists(const StringView& path) = delete;
///
/// Finds the paths of files that match the specified search pattern in the specified directory, using a value to determine whether to search subdirectories.
///
/// Output list with all found file paths. Items are appended without clearing the list first.
/// Path of the directory to search in it.
/// Custom search pattern to use during that operation Use asterisk character (*) for name-based filtering (eg. `*.txt` to find all files with `.txt` extension)..
/// Additional search options that define rules.
/// True if an error occurred, otherwise false.
static bool DirectoryGetFiles(Array& results, const String& path, const Char* searchPattern = TEXT("*"), DirectorySearchOption option = DirectorySearchOption::AllDirectories) = delete;
///
/// Finds the paths of directories that are inside the specified directory.
///
/// Output list with all found directory paths. Items are appended without clearing the list first.
/// Path of the directory to search in it.
/// True if an error occurred, otherwise false.
static bool GetChildDirectories(Array& results, const String& path) = delete;
///
/// Copies the directory.
///
/// Destination path.
/// Source directory path.
/// True if copy subdirectories of the source folder, otherwise only top-level files will be cloned.
/// True if failed, otherwise false.
static bool CopyDirectory(const String& dst, const String& src, bool withSubDirectories = true);
///
/// Gets the size of the directory (in bytes) defined by size of all files contained by it.
///
/// Directory path.
/// Amount of bytes in directory, or 0 if failed.
static uint64 GetDirectorySize(const StringView& path);
public:
///
/// Checks if a given file exists.
///
/// File path to check.
/// True if file exists, otherwise false.
static bool FileExists(const StringView& path) = delete;
///
/// Deletes an existing file.
///
/// File path
/// True if operation failed, otherwise false.
static bool DeleteFile(const StringView& path) = delete;
///
/// Gets the size of the file (in bytes).
///
/// File path
/// Amount of bytes in file, or 0 if failed.
static uint64 GetFileSize(const StringView& path) = delete;
///
/// Checks if file is read-only.
///
/// File path.
/// True if file is read-only, otherwise false. Returns false if failed or path is invalid.
static bool IsReadOnly(const StringView& path) = delete;
///
/// Sets file read-only flag.
///
/// File path.
/// Read-only flag value to set.
/// True if operation failed, otherwise false.
static bool SetReadOnly(const StringView& path, bool isReadOnly) = delete;
///
/// Moves the file.
///
/// Destination path.
/// Source file path.
/// True if allow overriding destination file if it already exists, otherwise action will fail.
/// True if failed, otherwise false.
static bool MoveFile(const StringView& dst, const StringView& src, bool overwrite = false) = delete;
///
/// Copies the file.
///
/// Destination path.
/// Source file path.
/// True if failed, otherwise false.
static bool CopyFile(const StringView& dst, const StringView& src);
///
/// Gets last time when file has been modified (in UTC).
///
/// The file path to check.
/// The last write time or DateTime::MinValue() if cannot get data.
static DateTime GetFileLastEditTime(const StringView& path) = delete;
///
/// Gets the special folder path.
///
/// The folder type.
/// The result full path.
static void GetSpecialFolderPath(const SpecialFolder type, String& result) = delete;
public:
///
/// Displays a standard dialog box that prompts the user to open a file(s).
///
/// The parent window or null.
/// The initial directory.
/// The file filter string as null-terminated pairs of name and list of extensions. Multiple file extensions must be separated with semicolon.
/// True if allow multiple files to be selected, otherwise use single-file mode.
/// The dialog title.
/// The output names of the files picked by the user.
/// True if failed, otherwise false.
///
/// Example file filters:
/// "All Files\0*.*"
/// "All Files\0*.*\0Image Files\0*.png;*.jpg"
///
API_FUNCTION() static bool ShowOpenFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, API_PARAM(Out) Array& filenames);
///
/// Displays a standard dialog box that prompts the user to save a file(s).
///
/// The parent window.
/// The initial directory.
/// The file filter string as null-terminated pairs of name and list of extensions. Multiple file extensions must be separated with semicolon.
/// True if allow multiple files to be selected, otherwise use single-file mode.
/// The title.
/// The output names of the files picked by the user.
/// True if failed, otherwise false.
///
/// Example file filters:
/// "All Files\0*.*"
/// "All Files\0*.*\0Image Files\0*.png;*.jpg"
///
API_FUNCTION() static bool ShowSaveFileDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& filter, bool multiSelect, const StringView& title, API_PARAM(Out) Array& filenames);
///
/// Displays a standard dialog box that prompts the user to select a folder.
///
/// The parent window.
/// The initial directory.
/// The dialog title.
/// The output path.
/// True if failed, otherwise false.
API_FUNCTION() static bool ShowBrowseFolderDialog(Window* parentWindow, const StringView& initialDirectory, const StringView& title, API_PARAM(Out) String& path);
///
/// Opens a standard file explorer application and navigates to the given directory.
///
/// The path.
/// True if failed, otherwise false.
API_FUNCTION() static bool ShowFileExplorer(const StringView& path);
public:
static void SaveBitmapToFile(byte* data, uint32 width, uint32 height, uint32 bitsPerPixel, const uint32 padding, const String& path);
public:
static bool AreFilePathsEqual(const StringView& path1, const StringView& path2);
///
/// Normalizes input path for valid path name for current platform file system.
///
/// Path to normalize
static void NormalizePath(String& path);
///
/// Checks if path type is relative.
///
/// Input path to check
/// True if input path is relative one, otherwise false
static bool IsRelative(const StringView& path);
///
/// Retrieves file extension (without a dot).
///
/// Input path to process
/// File extension
static String GetExtension(const StringView& path);
///
/// Gets the file path to the temporary file that can be created and used.
///
/// The temporary path.
static void GetTempFilePath(String& tmpPath);
public:
///
/// Converts path relative to the engine startup folder into absolute path.
///
/// Path relative to the engine directory
/// Absolute path
static String ConvertRelativePathToAbsolute(const String& path);
///
/// Converts path relative to basePath into absolute path.
///
/// Base path
/// Path relative to basePath
/// Absolute path
static String ConvertRelativePathToAbsolute(const String& basePath, const String& path);
///
/// Converts absolute path into relative path to engine startup folder.
///
/// Absolute path
/// Relative path
static String ConvertAbsolutePathToRelative(const String& path);
///
/// Converts absolute path into relative path to basePath.
///
/// Base path
/// Absolute path
/// Relative path
static String ConvertAbsolutePathToRelative(const String& basePath, const String& path);
private:
static bool DirectoryCopyHelper(const String& dst, const String& src, bool withSubDirectories);
};