/*
 * Unit test of the SHBrowseForFolder function.
 *
 * Copyright 2009-2010 Michael Mc Donnell
 * Copyright 2011 André Hentschel
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define COBJMACROS

#include <windows.h>
#include <shlobj.h>
#include <shobjidl.h>
#include <string.h>
#include "shellapi.h"

#include "wine/test.h"
#define IDD_MAKENEWFOLDER 0x3746 /* From "../shresdef.h" */
#define TIMER_WAIT_MS 50 /* Should be long enough for slow systems */

static const char new_folder_name[] = "foo";
static LPITEMIDLIST selected_folder_pidl;

/*
 * Returns the number of folders in a folder.
 */
static int get_number_of_folders(LPCSTR path)
{
    int number_of_folders = 0;
    char path_search_string[MAX_PATH];
    WIN32_FIND_DATAA find_data;
    HANDLE find_handle;

    lstrcpynA(path_search_string, path, MAX_PATH);
    strncat(path_search_string, "*", 1);

    find_handle = FindFirstFileA(path_search_string, &find_data);
    if (find_handle == INVALID_HANDLE_VALUE)
        return -1;

    do
    {
        if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
            strcmp(find_data.cFileName, ".") != 0 &&
            strcmp(find_data.cFileName, "..") != 0)
        {
            number_of_folders++;
        }
    }
    while (FindNextFileA(find_handle, &find_data) != 0);

    FindClose(find_handle);
    return number_of_folders;
}

static BOOL does_folder_or_file_exist(LPCSTR folder_path)
{
    DWORD file_attributes = GetFileAttributesA(folder_path);
    return !(file_attributes == INVALID_FILE_ATTRIBUTES);
}

/*
 * Timer callback used by test_click_make_new_folder_button. It simulates a user
 * making a new folder and calling it "foo".
 */
static void CALLBACK make_new_folder_timer_callback(HWND hwnd, UINT uMsg,
                                                    UINT_PTR idEvent, DWORD dwTime)
{
    static int step = 0;

    switch (step++)
    {
    case 0:
        /* Click "Make New Folder" button */
        PostMessageA(hwnd, WM_COMMAND, IDD_MAKENEWFOLDER, 0);
        break;
    case 1:
        /* Set the new folder name to foo by replacing text in edit control */
        SendMessageA(GetFocus(), EM_REPLACESEL, 0, (LPARAM) new_folder_name);
        SetFocus(hwnd);
        break;
    case 2:
        /*
         * The test does not trigger the correct state on Windows. This results
         * in the new folder pidl not being returned. The result is as
         * expected if the same steps are done manually.
         * Sending the down key selects the new folder again which sets the
         * correct state. This ensures that the correct pidl is returned.
         */
        keybd_event(VK_DOWN, 0, 0, 0);
        break;
    case 3:
        keybd_event(VK_DOWN, 0, KEYEVENTF_KEYUP, 0);
        break;
    case 4:
        KillTimer(hwnd, idEvent);
        /* Close dialog box */
        SendMessageA(hwnd, WM_COMMAND, IDOK, 0);
        break;
    default:
        break;
    }
}

/*
 * Callback used by test_click_make_new_folder_button. It sets up a timer to
 * simulate user input.
 */
static int CALLBACK create_new_folder_callback(HWND hwnd, UINT uMsg,
                                               LPARAM lParam, LPARAM lpData)
{
    switch (uMsg)
    {
    case BFFM_INITIALIZED:
        /* User input is simulated in timer callback */
        SetTimer(hwnd, 0, TIMER_WAIT_MS, make_new_folder_timer_callback);
        return TRUE;
    default:
        return FALSE;
    }
}

/*
 * Tests if clicking the "Make New Folder" button in a SHBrowseForFolder
 * dialog box creates a new folder. (Bug 17986).
 *
 * Here follows a description of what happens on W2K,Vista, W2K8, W7:
 * When the "Make New Folder" button is clicked a new folder is created and
 * inserted into the tree. The folder is given a default name that depends on
 * the locale (e.g. "New Folder"). The folder name is selected and the dialog
 * waits for the user to type in a new name. The folder is renamed when the user
 * types in a name and presses enter.
 *
 * Note that XP and W2K3 do not select the folder name or wait for the user
 * to type in a new folder name. This behavior is considered broken as most
 * users would like to give the folder a name after creating it. The fact that
 * it originally waited for the user to type in a new folder name(W2K), and then
 * again was changed back wait for the new folder name(Vista, W2K8, W7),
 * indicates that MS also believes that it was broken in XP and W2K3.
 */
static void test_click_make_new_folder_button(void)
{
    HRESULT resCoInit, hr;
    BROWSEINFOA bi;
    LPITEMIDLIST pidl = NULL;
    LPITEMIDLIST test_folder_pidl;
    IShellFolder *test_folder_object;
    char test_folder_path[MAX_PATH];
    WCHAR test_folder_pathW[MAX_PATH];
    CHAR new_folder_path[MAX_PATH];
    CHAR new_folder_pidl_path[MAX_PATH];
    char selected_folder[MAX_PATH];
    const CHAR title[] = "test_click_make_new_folder_button";
    int number_of_folders = -1;
    SHFILEOPSTRUCTA shfileop;

    if (does_folder_or_file_exist(title))
    {
        skip("The test folder already exists.\n");
        return;
    }

    /* Must initialize COM if using the NEWDIAlOGSTYLE according to MSDN. */
    resCoInit = CoInitialize(NULL);
    if(!(resCoInit == S_OK || resCoInit == S_FALSE))
    {
        skip("COM could not be initialized %u\n", GetLastError());
        return;
    }

    /* Leave room for concatenating title, two backslashes, and an extra NULL. */
    if (!GetCurrentDirectoryA(MAX_PATH-strlen(title)-3, test_folder_path))
    {
        skip("GetCurrentDirectoryA failed %u\n", GetLastError());
    }
    strncat(test_folder_path, "\\", 1);
    strncat(test_folder_path, title, MAX_PATH-1);
    strncat(test_folder_path, "\\", 1);

    /* Avoid conflicts by creating a test folder. */
    if (!CreateDirectoryA(title, NULL))
    {
        skip("CreateDirectoryA failed %u\n", GetLastError());
        return;
    }

    /* Initialize browse info struct for SHBrowseForFolder */
    bi.hwndOwner = NULL;
    bi.pszDisplayName = selected_folder;
    bi.lpszTitle = title;
    bi.ulFlags = BIF_NEWDIALOGSTYLE;
    bi.lpfn = create_new_folder_callback;
    /* Use test folder as the root folder for dialog box */
    MultiByteToWideChar(CP_UTF8, 0, test_folder_path, -1,
        test_folder_pathW, MAX_PATH);
    hr = SHGetDesktopFolder(&test_folder_object);
    ok (SUCCEEDED(hr), "SHGetDesktopFolder failed with hr 0x%08x\n", hr);
    if (FAILED(hr)) {
        skip("SHGetDesktopFolder failed - skipping\n");
        return;
    }
    test_folder_object->lpVtbl->ParseDisplayName(test_folder_object, NULL, NULL,
        test_folder_pathW, 0UL, &test_folder_pidl, 0UL);
    bi.pidlRoot = test_folder_pidl;

    /* Display dialog box and let callback click the buttons */
    pidl = SHBrowseForFolderA(&bi);

    number_of_folders = get_number_of_folders(test_folder_path);
    ok(number_of_folders == 1 || broken(number_of_folders == 0) /* W95, W98 */,
        "Clicking \"Make New Folder\" button did not result in a new folder.\n");

    /* There should be a new folder foo inside the test folder */
    strcpy(new_folder_path, test_folder_path);
    strcat(new_folder_path, new_folder_name);
    ok(does_folder_or_file_exist(new_folder_path)
        || broken(!does_folder_or_file_exist(new_folder_path)) /* W95, W98, XP, W2K3 */,
        "The new folder did not get the name %s\n", new_folder_name);

    /* Dialog should return a pidl pointing to the new folder */
    ok(SHGetPathFromIDListA(pidl, new_folder_pidl_path),
        "SHGetPathFromIDList failed for new folder.\n");
    ok(strcmp(new_folder_path, new_folder_pidl_path) == 0
        || broken(strcmp(new_folder_path, new_folder_pidl_path) != 0) /* earlier than Vista */,
        "SHBrowseForFolder did not return the pidl for the new folder. "
        "Expected '%s' got '%s'\n", new_folder_path, new_folder_pidl_path);

    /* Remove test folder and any subfolders created in this test */
    shfileop.hwnd = NULL;
    shfileop.wFunc = FO_DELETE;
    /* Path must be double NULL terminated */
    test_folder_path[strlen(test_folder_path)+1] = '\0';
    shfileop.pFrom = test_folder_path;
    shfileop.pTo = NULL;
    shfileop.fFlags = FOF_NOCONFIRMATION|FOF_NOERRORUI|FOF_SILENT;
    SHFileOperationA(&shfileop);

    CoTaskMemFree(pidl);
    CoTaskMemFree(test_folder_pidl);
    test_folder_object->lpVtbl->Release(test_folder_object);

    CoUninitialize();
}


/*
 * Callback used by test_selection.
 */
static int CALLBACK selection_callback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
    DWORD ret;

    switch (uMsg)
    {
    case BFFM_INITIALIZED:
        /* test with zero values */
        ret = SendMessageA(hwnd, BFFM_SETSELECTIONA, 0, 0);
        ok(!ret, "SendMessage returned: %u\n", ret);
        ret = SendMessageA(hwnd, BFFM_SETSELECTIONW, 0, 0);
        ok(!ret, "SendMessage returned: %u\n", ret);

        ret = SendMessageA(hwnd, BFFM_SETSELECTIONA, 1, 0);
        ok(!ret, "SendMessage returned: %u\n", ret);

        if(0)
        {
            /* Crashes on NT4 */
            ret = SendMessageA(hwnd, BFFM_SETSELECTIONW, 1, 0);
            ok(!ret, "SendMessage returned: %u\n", ret);
        }

        ret = SendMessageA(hwnd, BFFM_SETSELECTIONA, 0, (LPARAM)selected_folder_pidl);
        ok(!ret, "SendMessage returned: %u\n", ret);
        ret = SendMessageW(hwnd, BFFM_SETSELECTIONW, 0, (LPARAM)selected_folder_pidl);
        ok(!ret, "SendMessage returned: %u\n", ret);

        ret = SendMessageA(hwnd, BFFM_SETSELECTIONA, 1, (LPARAM)selected_folder_pidl);
        ok(!ret, "SendMessage returned: %u\n", ret);
        ret = SendMessageW(hwnd, BFFM_SETSELECTIONW, 1, (LPARAM)selected_folder_pidl);
        ok(!ret, "SendMessage returned: %u\n", ret);

        ret = SendMessageA(hwnd, BFFM_SETSELECTIONA, 1, (LPARAM)new_folder_name);
        ok(!ret, "SendMessage returned: %u\n", ret);
        ret = SendMessageW(hwnd, BFFM_SETSELECTIONW, 1, (LPARAM)new_folder_name);
        ok(!ret, "SendMessage returned: %u\n", ret);

        SendMessageA(hwnd, WM_COMMAND, IDOK, 0);
        return 1;
    default:
        return 0;
    }
}

static void test_selection(void)
{
    HRESULT resCoInit, hr;
    BROWSEINFOA bi;
    LPITEMIDLIST pidl = NULL;
    IShellFolder *desktop_object;
    WCHAR selected_folderW[MAX_PATH];
    const CHAR title[] = "test_selection";

    resCoInit = CoInitialize(NULL);
    if(!(resCoInit == S_OK || resCoInit == S_FALSE))
    {
        skip("COM could not be initialized %u\n", GetLastError());
        return;
    }

    if (!GetCurrentDirectoryW(MAX_PATH, selected_folderW))
    {
        skip("GetCurrentDirectoryW failed %u\n", GetLastError());
    }

    /* Initialize browse info struct for SHBrowseForFolder */
    bi.hwndOwner = NULL;
    bi.pszDisplayName = NULL;
    bi.lpszTitle = title;
    bi.lpfn = selection_callback;

    hr = SHGetDesktopFolder(&desktop_object);
    ok (SUCCEEDED(hr), "SHGetDesktopFolder failed with hr 0x%08x\n", hr);
    if (FAILED(hr)) {
        skip("SHGetDesktopFolder failed - skipping\n");
        return;
    }
    desktop_object->lpVtbl->ParseDisplayName(desktop_object, NULL, NULL,
        selected_folderW, 0UL, &selected_folder_pidl, 0UL);
    bi.pidlRoot = selected_folder_pidl;

    /* test without flags */
    bi.ulFlags = 0;
    pidl = SHBrowseForFolderA(&bi);
    CoTaskMemFree(pidl);

    /* test with flag */
    bi.ulFlags = BIF_NEWDIALOGSTYLE;
    pidl = SHBrowseForFolderA(&bi);
    CoTaskMemFree(pidl);

    IShellFolder_Release(desktop_object);

    CoUninitialize();
}

START_TEST(brsfolder)
{
    test_click_make_new_folder_button();
    test_selection();
}
