/*
 * Unit test suite for comdlg32 API functions: find/replace dialogs
 *
 * Copyright 2010 by Dylan Smith
 *
 * 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
 *
 */

#include "windows.h"
#include "commdlg.h"
#include "wine/test.h"

static UINT ID_FINDMSGSTRING;

static LRESULT handle_findmsg(FINDREPLACEA *fr)
{
    return 0;
}

static LRESULT CALLBACK OwnerWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if(msg == ID_FINDMSGSTRING) {
        return handle_findmsg((FINDREPLACEA*)lParam);
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

static void test_param_check(void)
{
    char findbuffer[64];
    char replacebuffer[64];
    FINDREPLACEA fr, *pFr;
    WNDCLASSA wc;

    ZeroMemory(&wc, sizeof(wc));
    wc.lpfnWndProc = OwnerWndProc;
    wc.lpszClassName = "test_param_check";
    RegisterClassA(&wc);

#define CHECK_FIND_OR_REPLACE(FUNC, FAIL, ERR_CODE) \
    do { \
       HWND hwnd = FUNC(pFr); \
       BOOL is_ok = !!hwnd == !FAIL; \
       ok(is_ok, "%s should%s fail\n", #FUNC, FAIL ? "" : "n't"); \
       if (FAIL && is_ok) { \
          DWORD ext_err = CommDlgExtendedError(); \
          ok(ext_err == ERR_CODE, "expected err %x got %x\n", \
             ERR_CODE, ext_err); \
       } else { \
          DestroyWindow(hwnd); \
       } \
    } while (0)

#define CHECK_FIND_FAIL(ERR_CODE) \
    CHECK_FIND_OR_REPLACE(FindTextA, TRUE, ERR_CODE)

#define CHECK_FIND_SUCCEED() \
    CHECK_FIND_OR_REPLACE(FindTextA, FALSE, 0)

#define CHECK_REPLACE_FAIL(ERR_CODE) \
    CHECK_FIND_OR_REPLACE(ReplaceTextA, TRUE, ERR_CODE)

#define CHECK_REPLACE_SUCCEED() \
    CHECK_FIND_OR_REPLACE(ReplaceTextA, FALSE, 0)

#define CHECK_FINDREPLACE_FAIL(ERR_CODE) \
    do { \
       CHECK_FIND_FAIL(ERR_CODE); \
       CHECK_REPLACE_FAIL(ERR_CODE); \
    } while (0)

    pFr = NULL;
    CHECK_FINDREPLACE_FAIL(CDERR_INITIALIZATION);
    pFr = &fr;

    ZeroMemory(&fr, sizeof(fr));
    /* invalid lStructSize (0) */
    CHECK_FINDREPLACE_FAIL(CDERR_STRUCTSIZE);
    fr.lStructSize = sizeof(fr);

    /* invalid hwndOwner (NULL) */
    CHECK_FINDREPLACE_FAIL(CDERR_DIALOGFAILURE);
    fr.hwndOwner = CreateWindowA(wc.lpszClassName, NULL, WS_VISIBLE, 0, 0, 200, 100,
                                 NULL, NULL, GetModuleHandleA(NULL), NULL);

    /* invalid wFindWhatLen (0) */
    CHECK_FINDREPLACE_FAIL(FRERR_BUFFERLENGTHZERO);
    fr.wFindWhatLen = sizeof(findbuffer);

    /* invalid lpstrFindWhat (NULL) */
    CHECK_FINDREPLACE_FAIL(FRERR_BUFFERLENGTHZERO);
    fr.lpstrFindWhat = findbuffer;
    strcpy(findbuffer, "abc");

    /* invalid lpstrReplaceWith (NULL) for ReplaceText */
    CHECK_FIND_SUCCEED();
    CHECK_REPLACE_FAIL(FRERR_BUFFERLENGTHZERO);
    fr.lpstrReplaceWith = replacebuffer;
    strcpy(replacebuffer, "def");

    /* wReplaceWithLen may be 0, even for ReplaceText */
    CHECK_FIND_SUCCEED();
    CHECK_REPLACE_SUCCEED();
    fr.wReplaceWithLen = sizeof(replacebuffer);

    /* invalid lpfnHook (NULL) when Flags has FR_ENABLEHOOK */
    fr.Flags = FR_ENABLEHOOK;
    CHECK_FINDREPLACE_FAIL(CDERR_NOHOOK);

    /* invalid hInstance (NULL)
     * when Flags has FR_ENABLETEMPLATE or FR_ENABLETEMPLATEHANDLE */
    fr.Flags = FR_ENABLETEMPLATE;
    CHECK_FINDREPLACE_FAIL(CDERR_FINDRESFAILURE);
    fr.Flags = FR_ENABLETEMPLATEHANDLE;
    CHECK_FINDREPLACE_FAIL(CDERR_NOHINSTANCE);
    fr.hInstance = GetModuleHandle(NULL);

    /* invalid lpTemplateName (NULL) when Flags has FR_ENABLETEMPLATE */
    fr.Flags = FR_ENABLETEMPLATE;
    CHECK_FINDREPLACE_FAIL(CDERR_FINDRESFAILURE);
    fr.Flags = 0;

    CHECK_FIND_SUCCEED();
    CHECK_REPLACE_SUCCEED();

    DestroyWindow(fr.hwndOwner);
}

START_TEST(finddlg)
{
    ID_FINDMSGSTRING = RegisterWindowMessageA(FINDMSGSTRINGA);

    test_param_check();
}
