/*
 * GUI support
 *
 * Copyright 2004 Ferenc Wagner
 *
 * 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 <commctrl.h>

#include "resource.h"
#include "winetest.h"

/* Event object to signal successful window creation to main thread.
 */
static HANDLE initEvent;

/* Dialog handle
 */
static HWND dialog;

/* Progress data for the text* functions and for scaling.
 */
static unsigned int progressMax, progressCurr;
static double progressScale;

/* Progress group counter for the gui* functions.
 */
static int progressGroup;

static WNDPROC DefEditProc;

static int
MBdefault (int uType)
{
    static const int matrix[][4] = {{IDOK,    0,        0,        0},
                                    {IDOK,    IDCANCEL, 0,        0},
                                    {IDABORT, IDRETRY,  IDIGNORE, 0},
                                    {IDYES,   IDNO,     IDCANCEL, 0},
                                    {IDYES,   IDNO,     0,        0},
                                    {IDRETRY, IDCANCEL, 0,        0}};
    int type = uType & MB_TYPEMASK;
    int def  = (uType & MB_DEFMASK) / MB_DEFBUTTON2;

    return matrix[type][def];
}

/* report (R_STATUS, fmt, ...) */
static int
textStatus (va_list ap)
{
    char *str = vstrmake (NULL, ap);

    fputs (str, stderr);
    fputc ('\n', stderr);
    heap_free (str);
    return 0;
}

static int
guiStatus (va_list ap)
{
    size_t len;
    char *str = vstrmake (&len, ap);

    if (len > 128) str[129] = 0;
    SetDlgItemText (dialog, IDC_SB, str);
    heap_free (str);
    return 0;
}

/* report (R_PROGRESS, barnum, steps) */
static int
textProgress (va_list ap)
{
    progressGroup = va_arg (ap, int);
    progressMax = va_arg (ap, int);
    progressCurr = 0;
    return 0;
}

static int
guiProgress (va_list ap)
{
    unsigned int max;
    HWND pb;

    progressGroup = va_arg (ap, int);
    progressMax = max = va_arg (ap, int);
    progressCurr = 0;
    if (max > 0xffff) {
        progressScale = (double)0xffff / max;
        max = 0xffff;
    }
    else progressScale = 1;
    pb = GetDlgItem (dialog, IDC_PB0 + progressGroup * 2);
    SendMessage (pb, PBM_SETRANGE, 0, MAKELPARAM (0, max));
    SendMessage (pb, PBM_SETSTEP, 1, 0);
    return 0;
}

/* report (R_STEP, fmt, ...) */
static int
textStep (va_list ap)
{
    char *str = vstrmake (NULL, ap);

    progressCurr++;
    fputs (str, stderr);
    fprintf (stderr, " (%d of %d)\n", progressCurr, progressMax);
    heap_free (str);
    return 0;
}

static int
guiStep (va_list ap)
{
    const int pgID = IDC_ST0 + progressGroup * 2;
    char *str = vstrmake (NULL, ap);
    
    progressCurr++;
    SetDlgItemText (dialog, pgID, str);
    SendDlgItemMessage (dialog, pgID+1, PBM_SETPOS,
                        progressScale * progressCurr, 0);
    heap_free (str);
    return 0;
}

/* report (R_DELTA, inc, fmt, ...) */
static int
textDelta (va_list ap)
{
    const int inc = va_arg (ap, int);
    char *str = vstrmake (NULL, ap);

    progressCurr += inc;
    fputs (str, stderr);
    fprintf (stderr, " (%d of %d)\n", progressCurr, progressMax);
    heap_free (str);
    return 0;
}

static int
guiDelta (va_list ap)
{
    const int inc = va_arg (ap, int);
    const int pgID = IDC_ST0 + progressGroup * 2;
    char *str = vstrmake (NULL, ap);

    progressCurr += inc;
    SetDlgItemText (dialog, pgID, str);
    SendDlgItemMessage (dialog, pgID+1, PBM_SETPOS,
                        progressScale * progressCurr, 0);
    heap_free (str);
    return 0;
}

/* report (R_TAG) */
static int
textTag (va_list ap)
{
    fputs ("Tag: ", stderr);
    fputs (tag, stderr);
    fputc ('\n', stderr);
    return 0;
}

static int
guiTag (va_list ap)
{
    SetDlgItemText (dialog, IDC_TAG, tag);
    return 0;
}

/* report (R_DIR, fmt, ...) */
static int
textDir (va_list ap)
{
    char *str = vstrmake (NULL, ap);

    fputs ("Temporary directory: ", stderr);
    fputs (str, stderr);
    fputc ('\n', stderr);
    heap_free (str);
    return 0;
}

static int
guiDir (va_list ap)
{
    char *str = vstrmake (NULL, ap);

    SetDlgItemText (dialog, IDC_DIR, str);
    heap_free (str);
    return 0;
}

/* report (R_OUT, fmt, ...) */
static int
textOut (va_list ap)
{
    char *str = vstrmake (NULL, ap);

    fputs ("Log file: ", stderr);
    fputs (str, stderr);
    fputc ('\n', stderr);
    heap_free (str);
    return 0;
}

static int
guiOut (va_list ap)
{
    char *str = vstrmake (NULL, ap);

    SetDlgItemText (dialog, IDC_OUT, str);
    heap_free (str);
    return 0;
}

/* report (R_WARNING, fmt, ...) */
static int
textWarning (va_list ap)
{
    fputs ("Warning: ", stderr);
    textStatus (ap);
    return 0;
}

static int
guiWarning (va_list ap)
{
    char *str = vstrmake (NULL, ap);

    MessageBox (dialog, str, "Warning", MB_ICONWARNING | MB_OK);
    heap_free (str);
    return 0;
}

/* report (R_ERROR, fmt, ...) */
static int
textError (va_list ap)
{
    fputs ("Error: ", stderr);
    textStatus (ap);
    return 0;
}

static int
guiError (va_list ap)
{
    char *str = vstrmake (NULL, ap);

    MessageBox (dialog, str, "Error", MB_ICONERROR | MB_OK);
    heap_free (str);
    return 0;
}

/* report (R_FATAL, fmt, ...) */
static int
textFatal (va_list ap)
{
    textError (ap);
    exit (1);
}

static int
guiFatal (va_list ap)
{
    guiError (ap);
    exit (1);
}

/* report (R_ASK, type, fmt, ...) */
static int
textAsk (va_list ap)
{
    int uType = va_arg (ap, int);
    int ret = MBdefault (uType);
    char *str = vstrmake (NULL, ap);

    fprintf (stderr, "Question of type %d: %s\n"
             "Returning default: %d\n", uType, str, ret);
    heap_free (str);
    return ret;
}

static int
guiAsk (va_list ap)
{
    int uType = va_arg (ap, int);
    char *str = vstrmake (NULL, ap);
    int ret = MessageBox (dialog, str, "Question",
                          MB_ICONQUESTION | uType);

    heap_free (str);
    return ret;
}

static BOOL CALLBACK
EditTagProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg) {
    case WM_CHAR:
        if (wParam == 8) break; /* backspace is OK */
        if (GetWindowTextLengthA (hwnd) == MAXTAGLEN ||
            !goodtagchar (wParam)) return TRUE;
        break;
    }
    return CallWindowProcA (DefEditProc, hwnd, msg, wParam, lParam);
}

static INT_PTR CALLBACK
AskTagProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    int len;

    switch (msg) {
    case WM_INITDIALOG:
        DefEditProc = (WNDPROC)SetWindowLongPtr
            (GetDlgItem (hwnd, IDC_TAG), GWLP_WNDPROC, (LONG_PTR)EditTagProc);
        return TRUE;
    case WM_COMMAND:
        switch (LOWORD (wParam)) {
        case IDOK:
            len = GetWindowTextLengthA (GetDlgItem (hwnd, IDC_TAG));
	    if(!len) {
               report (R_WARNING, "You must enter a tag to continue");
               return FALSE;
            }
            tag = heap_alloc (len+1);
            GetDlgItemTextA (hwnd, IDC_TAG, tag, len+1);
            EndDialog (hwnd, IDOK);
            return TRUE;
        case IDABORT:
            EndDialog (hwnd, IDABORT);
            return TRUE;
        }
    }
    return FALSE;
}

int
guiAskTag (void)
{
    return DialogBox (GetModuleHandle (NULL),
                      MAKEINTRESOURCE (IDD_TAG),
                      dialog, AskTagProc);
}

/* Quiet functions */
static int
qNoOp (va_list ap)
{
    return 0;
}

static int
qFatal (va_list ap)
{
    exit (1);
}

static int
qAsk (va_list ap)
{
    return MBdefault (va_arg (ap, int));
}

static INT_PTR CALLBACK
AboutProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg) {
    case WM_COMMAND:
        switch (LOWORD (wParam)) {
        case IDCANCEL:
            EndDialog (hwnd, IDCANCEL);
            return TRUE;
        }
    }
    return FALSE;
}

static INT_PTR CALLBACK
DlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg) {
    case WM_INITDIALOG:
        SendMessage (hwnd, WM_SETICON, ICON_SMALL,
                     (LPARAM)LoadIcon (GetModuleHandle (NULL),
                                       MAKEINTRESOURCE (IDI_WINE)));
        SendMessage (hwnd, WM_SETICON, ICON_BIG,
                     (LPARAM)LoadIcon (GetModuleHandle (NULL),
                                       MAKEINTRESOURCE (IDI_WINE)));
        dialog = hwnd;
        if (!SetEvent (initEvent)) {
            report (R_STATUS, "Can't signal main thread: %d",
                    GetLastError ());
            EndDialog (hwnd, 2);
        }
        return TRUE;
    case WM_CLOSE:
        EndDialog (hwnd, 3);
        return TRUE;
    case WM_COMMAND:
        switch (LOWORD (wParam)) {
        case IDHELP:
            DialogBox (GetModuleHandle (NULL),
                       MAKEINTRESOURCE (IDD_ABOUT), hwnd, AboutProc);
            return TRUE;
        case IDABORT:
            report (R_WARNING, "Not implemented");
            return TRUE;
        }
    }
    return FALSE;
}

static DWORD WINAPI
DlgThreadProc (LPVOID param)
{
    int ret;

    InitCommonControls ();
    ret = DialogBox (GetModuleHandle (NULL),
                     MAKEINTRESOURCE (IDD_STATUS),
                     NULL, DlgProc);
    switch (ret) {
    case 0:
        report (R_WARNING, "Invalid parent handle");
        break;
    case 1:
        report (R_WARNING, "DialogBox failed: %d",
                GetLastError ());
        break;
    case 3:
        exit (0);
    default:
        report (R_STATUS, "Dialog exited: %d", ret);
    }
    return 0;
}

int
report (enum report_type t, ...)
{
    typedef int r_fun_t (va_list);

    va_list ap;
    int ret = 0;
    static r_fun_t * const text_funcs[] =
        {textStatus, textProgress, textStep, textDelta,
         textTag, textDir, textOut,
         textWarning, textError, textFatal, textAsk};
    static r_fun_t * const GUI_funcs[] =
        {guiStatus, guiProgress, guiStep, guiDelta,
         guiTag, guiDir, guiOut,
         guiWarning, guiError, guiFatal, guiAsk};
    static r_fun_t * const quiet_funcs[] =
        {qNoOp, qNoOp, qNoOp, qNoOp,
         qNoOp, qNoOp, qNoOp,
         qNoOp, qNoOp, qFatal, qAsk};
    static r_fun_t * const * funcs = NULL;

    switch (t) {
    case R_TEXTMODE:
        funcs = text_funcs;
        return 0;
    case R_QUIET:
        funcs = quiet_funcs;
        return 0;
    default:
        break;
    }

    if (!funcs) {
        HANDLE DlgThread;
        DWORD DlgThreadID;

        funcs = text_funcs;
        initEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
        if (!initEvent)
            report (R_STATUS, "Can't create event object: %d",
                    GetLastError ());
        else {
            DlgThread = CreateThread (NULL, 0, DlgThreadProc,
                                      NULL, 0, &DlgThreadID);
            if (!DlgThread)
                report (R_STATUS, "Can't create GUI thread: %d",
                        GetLastError ());
            else {
                DWORD ret = WaitForSingleObject (initEvent, INFINITE);
                switch (ret) {
                case WAIT_OBJECT_0:
                    funcs = GUI_funcs;
                    break;
                case WAIT_TIMEOUT:
                    report (R_STATUS, "GUI creation timed out");
                    break;
                case WAIT_FAILED:
                    report (R_STATUS, "Wait for GUI failed: %d",
                            GetLastError ());
                    break;
                default:
                    report (R_STATUS, "Wait returned %d",
                            ret);
                    break;
                }
            }
        }
    }
        
    va_start (ap, t);
    if (t < sizeof text_funcs / sizeof text_funcs[0] &&
        t < sizeof GUI_funcs / sizeof GUI_funcs[0]) ret = funcs[t](ap);
    else report (R_WARNING, "unimplemented report type: %d", t);
    va_end (ap);
    return ret;
}
