// FileManager.cpp - Obsahuje definice funkcí sloužících pro práci se soubory
// Autor:   Jan Benda
// Datum:   17.12.2020

#include "FileManager.h"

namespace FileManager
    {

    void OpenDialog(std::vector<std::string>& iFilenames, bool iMultiselect, bool iFolder, std::string iDefaultExtension)
        {
        IFileOpenDialog* pfd = NULL; // Need IFileOpenDialog to allow for multiple selections

        if(!SUCCEEDED(CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd))))
            {
            return;
            }
        if(!iFolder)
            {
            if(iMultiselect)
                {
                if(!SUCCEEDED(pfd->SetOptions(FOS_FORCEFILESYSTEM | FOS_STRICTFILETYPES | FOS_OVERWRITEPROMPT | FOS_NOCHANGEDIR | FOS_ALLOWMULTISELECT)))
                    {
                    pfd->Release();
                    return;
                    }
                }
            else if(!SUCCEEDED(pfd->SetOptions(FOS_FORCEFILESYSTEM | FOS_STRICTFILETYPES | FOS_OVERWRITEPROMPT | FOS_NOCHANGEDIR)))
                {
                pfd->Release();
                return;
                }
            }
        else
            if(!SUCCEEDED(pfd->SetOptions(FOS_FORCEFILESYSTEM | FOS_NOCHANGEDIR | FOS_FILEMUSTEXIST | FOS_PICKFOLDERS)))
                {
                pfd->Release();
                return;
                }

        if(!iFolder)
            if(!SUCCEEDED(pfd->SetDefaultExtension((LPCWSTR) Controls::s2ws(iDefaultExtension).c_str())))
                {
                pfd->ClearClientData();
                pfd->Release();
                return;
                }

        if(!SUCCEEDED(pfd->Show(NULL)))
            {
            pfd->ClearClientData();
            pfd->Release();
            return;
            }

        IShellItemArray* psiaResult;
        if(!SUCCEEDED(pfd->GetResults(&psiaResult)))
            {
            pfd->Release();
            return;
            }


        PWSTR pszFilePath = NULL;

        DWORD dwNumItems = 0;

        if(!SUCCEEDED(psiaResult->GetCount(&dwNumItems)))
            {
            psiaResult->Release();
            pfd->Release();
            return;
            }

        for(DWORD i = 0; i < dwNumItems; i++)
            {
            IShellItem* psi = NULL;
            if(!SUCCEEDED(psiaResult->GetItemAt(i, &psi)))
                {
                psiaResult->Release();
                pfd->Release();
                return;
                }

            if(!SUCCEEDED(psi->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath)))
                {
                psi->Release();
                psiaResult->Release();
                pfd->Release();
                return;
                }

            std::wstring strSelected;
            strSelected += pszFilePath;
            if(!iFolder)
                {
                iFilenames.push_back(Controls::ws2s(strSelected));
                }
            else
                {
                std::string path = Controls::ws2s(strSelected);
                for(const auto& entry : std::filesystem::directory_iterator(path))
                    iFilenames.push_back(Controls::ws2s(entry.path()));
                }

            CoTaskMemFree(pszFilePath);
            psi->Release();
            }

        psiaResult->Release();
        pfd->Release();
        }

    BOOL DirectoryExists(const std::string& szPath)
        {
        DWORD ftyp = GetFileAttributesA(szPath.c_str());
        if(ftyp == INVALID_FILE_ATTRIBUTES)
            return false;  //something is wrong with your path!

        if(ftyp & FILE_ATTRIBUTE_DIRECTORY)
            return true;   // this is a directory!

        return false;    // this is not a directory!
        }
    }