/*
 *	Progress dialog
 *
 *	Copyright 2007	Mikolaj Zalewski
 *
 * 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 "config.h"

#include <stdarg.h>

#define COBJMACROS

#include "wine/debug.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winuser.h"
#include "shlwapi.h"
#include "winerror.h"
#include "objbase.h"

#include "shlguid.h"
#include "shlobj.h"

#include "wine/unicode.h"

#include "browseui.h"
#include "resids.h"

WINE_DEFAULT_DEBUG_CHANNEL(browseui);

#define CANCEL_MSG_LINE 2

/* Note: to avoid a deadlock we don't want to send messages to the dialog
 * with the critical section held. Instead we only mark what fields should be
 * updated and the dialog proc does the update */
#define UPDATE_PROGRESS         0x1
#define UPDATE_TITLE            0x2
#define UPDATE_LINE1            0x4
#define UPDATE_LINE2            (UPDATE_LINE1<<1)
#define UPDATE_LINE3            (UPDATE_LINE2<<2)


#define WM_DLG_UPDATE   (WM_APP+1)  /* set to the dialog when it should update */
#define WM_DLG_DESTROY  (WM_APP+2)  /* DestroyWindow must be called from the owning thread */

typedef struct tagProgressDialog {
    IProgressDialog IProgressDialog_iface;
    IOleWindow IOleWindow_iface;
    LONG refCount;
    CRITICAL_SECTION cs;
    HWND hwnd;
    DWORD dwFlags;
    DWORD dwUpdate;
    LPWSTR lines[3];
    LPWSTR cancelMsg;
    LPWSTR title;
    BOOL isCancelled;
    ULONGLONG ullCompleted;
    ULONGLONG ullTotal;
    HWND hwndDisabledParent;    /* For modal dialog: the parent that need to be re-enabled when the dialog ends */
} ProgressDialog;

static inline ProgressDialog *impl_from_IProgressDialog(IProgressDialog *iface)
{
    return CONTAINING_RECORD(iface, ProgressDialog, IProgressDialog_iface);
}

static inline ProgressDialog *impl_from_IOleWindow(IOleWindow *iface)
{
    return CONTAINING_RECORD(iface, ProgressDialog, IOleWindow_iface);
}

static void set_buffer(LPWSTR *buffer, LPCWSTR string)
{
    static const WCHAR empty_string[] = {0};
    IMalloc *malloc;
    ULONG cb;

    if (string == NULL)
        string = empty_string;
    CoGetMalloc(1, &malloc);

    cb = (strlenW(string) + 1)*sizeof(WCHAR);
    if (*buffer == NULL || cb > IMalloc_GetSize(malloc, *buffer))
        *buffer = IMalloc_Realloc(malloc, *buffer, cb);
    memcpy(*buffer, string, cb);
}

struct create_params
{
    ProgressDialog *This;
    HANDLE hEvent;
    HWND hwndParent;
};

static LPWSTR load_string(HINSTANCE hInstance, UINT uiResourceId)
{
    WCHAR string[256];
    LPWSTR ret;

    LoadStringW(hInstance, uiResourceId, string, sizeof(string)/sizeof(string[0]));
    ret = HeapAlloc(GetProcessHeap(), 0, (strlenW(string) + 1) * sizeof(WCHAR));
    strcpyW(ret, string);
    return ret;
}

static void set_progress_marquee(ProgressDialog *This)
{
    HWND hProgress = GetDlgItem(This->hwnd, IDC_PROGRESS_BAR);
    SetWindowLongW(hProgress, GWL_STYLE,
        GetWindowLongW(hProgress, GWL_STYLE)|PBS_MARQUEE);
}

static void update_dialog(ProgressDialog *This, DWORD dwUpdate)
{
    WCHAR empty[] = {0};

    if (dwUpdate & UPDATE_TITLE)
        SetWindowTextW(This->hwnd, This->title);

    if (dwUpdate & UPDATE_LINE1)
        SetDlgItemTextW(This->hwnd, IDC_TEXT_LINE, (This->isCancelled ? empty : This->lines[0]));
    if (dwUpdate & UPDATE_LINE2)
        SetDlgItemTextW(This->hwnd, IDC_TEXT_LINE+1, (This->isCancelled ? empty : This->lines[1]));
    if (dwUpdate & UPDATE_LINE3)
        SetDlgItemTextW(This->hwnd, IDC_TEXT_LINE+2, (This->isCancelled ? This->cancelMsg : This->lines[2]));

    if (dwUpdate & UPDATE_PROGRESS)
    {
        ULONGLONG ullTotal = This->ullTotal;
        ULONGLONG ullCompleted = This->ullCompleted;

        /* progress bar requires 32-bit coordinates */
        while (ullTotal >> 32)
        {
            ullTotal >>= 1;
            ullCompleted >>= 1;
        }

        SendDlgItemMessageW(This->hwnd, IDC_PROGRESS_BAR, PBM_SETRANGE32, 0, (DWORD)ullTotal);
        SendDlgItemMessageW(This->hwnd, IDC_PROGRESS_BAR, PBM_SETPOS, (DWORD)ullCompleted, 0);
    }
}

static void end_dialog(ProgressDialog *This)
{
    SendMessageW(This->hwnd, WM_DLG_DESTROY, 0, 0);
    /* native doesn't re-enable the window? */
    if (This->hwndDisabledParent)
        EnableWindow(This->hwndDisabledParent, TRUE);
    This->hwnd = NULL;
}

static INT_PTR CALLBACK dialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    ProgressDialog *This = (ProgressDialog *)GetWindowLongPtrW(hwnd, DWLP_USER);

    switch (msg)
    {
        case WM_INITDIALOG:
        {
            struct create_params *params = (struct create_params *)lParam;

            /* Note: until we set the hEvent, the object is protected by
             * the critical section held by StartProgress */
            SetWindowLongPtrW(hwnd, DWLP_USER, (LONG_PTR)params->This);
            This = params->This;
            This->hwnd = hwnd;

            if (This->dwFlags & PROGDLG_NOPROGRESSBAR)
                ShowWindow(GetDlgItem(hwnd, IDC_PROGRESS_BAR), SW_HIDE);
            if (This->dwFlags & PROGDLG_NOCANCEL)
                ShowWindow(GetDlgItem(hwnd, IDCANCEL), SW_HIDE);
            if (This->dwFlags & PROGDLG_MARQUEEPROGRESS)
                set_progress_marquee(This);
            if (This->dwFlags & PROGDLG_NOMINIMIZE)
                SetWindowLongW(hwnd, GWL_STYLE, GetWindowLongW(hwnd, GWL_STYLE) & (~WS_MINIMIZEBOX));

            update_dialog(This, 0xffffffff);
            This->dwUpdate = 0;
            This->isCancelled = FALSE;
            SetEvent(params->hEvent);
            return TRUE;
        }

        case WM_DLG_UPDATE:
            EnterCriticalSection(&This->cs);
            update_dialog(This, This->dwUpdate);
            This->dwUpdate = 0;
            LeaveCriticalSection(&This->cs);
            return TRUE;

        case WM_DLG_DESTROY:
            DestroyWindow(hwnd);
            PostThreadMessageW(GetCurrentThreadId(), WM_NULL, 0, 0); /* wake up the GetMessage */
            return TRUE;

        case WM_CLOSE:
        case WM_COMMAND:
            if (msg == WM_CLOSE || wParam == IDCANCEL)
            {
                EnterCriticalSection(&This->cs);
                This->isCancelled = TRUE;

                if (!This->cancelMsg)
                    This->cancelMsg = load_string(BROWSEUI_hinstance, IDS_CANCELLING);

                set_progress_marquee(This);
                EnableWindow(GetDlgItem(This->hwnd, IDCANCEL), FALSE);
                update_dialog(This, UPDATE_LINE1|UPDATE_LINE2|UPDATE_LINE3);
                LeaveCriticalSection(&This->cs);
            }
            return TRUE;
    }
    return FALSE;
}

static DWORD WINAPI dialog_thread(LPVOID lpParameter)
{
    /* Note: until we set the hEvent in WM_INITDIALOG, the ProgressDialog object
     * is protected by the critical section held by StartProgress */
    struct create_params *params = lpParameter;
    HWND hwnd;
    MSG msg;

    hwnd = CreateDialogParamW(BROWSEUI_hinstance, MAKEINTRESOURCEW(IDD_PROGRESS_DLG),
        params->hwndParent, dialog_proc, (LPARAM)params);

    while (GetMessageW(&msg, NULL, 0, 0) > 0)
    {
        if (!IsWindow(hwnd))
            break;
        if(!IsDialogMessageW(hwnd, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessageW(&msg);
        }
    }

    return 0;
}

static void ProgressDialog_Destructor(ProgressDialog *This)
{
    TRACE("destroying %p\n", This);
    if (This->hwnd)
        end_dialog(This);
    heap_free(This->lines[0]);
    heap_free(This->lines[1]);
    heap_free(This->lines[2]);
    heap_free(This->cancelMsg);
    heap_free(This->title);
    heap_free(This);
    This->cs.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection(&This->cs);
    BROWSEUI_refCount--;
}

static HRESULT WINAPI ProgressDialog_QueryInterface(IProgressDialog *iface, REFIID iid, LPVOID *ppvOut)
{
    ProgressDialog *This = impl_from_IProgressDialog(iface);

    TRACE("(%p, %s, %p)\n", iface, debugstr_guid(iid), ppvOut);
    if (!ppvOut)
        return E_POINTER;

    *ppvOut = NULL;
    if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IProgressDialog))
    {
        *ppvOut = iface;
    }
    else if (IsEqualIID(iid, &IID_IOleWindow))
    {
        *ppvOut = &This->IOleWindow_iface;
    }

    if (*ppvOut)
    {
        IUnknown_AddRef(iface);
        return S_OK;
    }

    WARN("unsupported interface: %s\n", debugstr_guid(iid));
    return E_NOINTERFACE;
}

static ULONG WINAPI ProgressDialog_AddRef(IProgressDialog *iface)
{
    ProgressDialog *This = impl_from_IProgressDialog(iface);
    return InterlockedIncrement(&This->refCount);
}

static ULONG WINAPI ProgressDialog_Release(IProgressDialog *iface)
{
    ProgressDialog *This = impl_from_IProgressDialog(iface);
    ULONG ret;

    ret = InterlockedDecrement(&This->refCount);
    if (ret == 0)
        ProgressDialog_Destructor(This);
    return ret;
}

static HRESULT WINAPI ProgressDialog_StartProgressDialog(IProgressDialog *iface, HWND hwndParent, IUnknown *punkEnableModeless, DWORD dwFlags, LPCVOID reserved)
{
    static const INITCOMMONCONTROLSEX init = { sizeof(init), ICC_ANIMATE_CLASS };
    ProgressDialog *This = impl_from_IProgressDialog(iface);
    struct create_params params;
    HANDLE hThread;

    TRACE("(%p, %p, %x, %p)\n", iface, punkEnableModeless, dwFlags, reserved);
    if (punkEnableModeless || reserved)
        FIXME("Reserved parameters not null (%p, %p)\n", punkEnableModeless, reserved);
    if (dwFlags & PROGDLG_AUTOTIME)
        FIXME("Flags PROGDLG_AUTOTIME not supported\n");
    if (dwFlags & PROGDLG_NOTIME)
        FIXME("Flags PROGDLG_NOTIME not supported\n");

    InitCommonControlsEx( &init );

    EnterCriticalSection(&This->cs);

    if (This->hwnd)
    {
        LeaveCriticalSection(&This->cs);
        return S_OK;  /* as on XP */
    }
    This->dwFlags = dwFlags;
    params.This = This;
    params.hwndParent = hwndParent;
    params.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);

    hThread = CreateThread(NULL, 0, dialog_thread, &params, 0, NULL);
    WaitForSingleObject(params.hEvent, INFINITE);
    CloseHandle(params.hEvent);
    CloseHandle(hThread);

    This->hwndDisabledParent = NULL;
    if (hwndParent && (dwFlags & PROGDLG_MODAL))
    {
        HWND hwndDisable = GetAncestor(hwndParent, GA_ROOT);
        if (EnableWindow(hwndDisable, FALSE))
            This->hwndDisabledParent = hwndDisable;
    }

    LeaveCriticalSection(&This->cs);

    return S_OK;
}

static HRESULT WINAPI ProgressDialog_StopProgressDialog(IProgressDialog *iface)
{
    ProgressDialog *This = impl_from_IProgressDialog(iface);

    EnterCriticalSection(&This->cs);
    if (This->hwnd)
        end_dialog(This);
    LeaveCriticalSection(&This->cs);

    return S_OK;
}

static HRESULT WINAPI ProgressDialog_SetTitle(IProgressDialog *iface, LPCWSTR pwzTitle)
{
    ProgressDialog *This = impl_from_IProgressDialog(iface);
    HWND hwnd;

    TRACE("(%p, %s)\n", This, wine_dbgstr_w(pwzTitle));

    EnterCriticalSection(&This->cs);
    set_buffer(&This->title, pwzTitle);
    This->dwUpdate |= UPDATE_TITLE;
    hwnd = This->hwnd;
    LeaveCriticalSection(&This->cs);

    if (hwnd)
        SendMessageW(hwnd, WM_DLG_UPDATE, 0, 0);

    return S_OK;
}

static HRESULT WINAPI ProgressDialog_SetAnimation(IProgressDialog *iface, HINSTANCE hInstance, UINT uiResourceId)
{
    FIXME("(%p, %p, %d) - stub\n", iface, hInstance, uiResourceId);
    return S_OK;
}

static BOOL WINAPI ProgressDialog_HasUserCancelled(IProgressDialog *iface)
{
    ProgressDialog *This = impl_from_IProgressDialog(iface);
    return This->isCancelled;
}

static HRESULT WINAPI ProgressDialog_SetProgress64(IProgressDialog *iface, ULONGLONG ullCompleted, ULONGLONG ullTotal)
{
    ProgressDialog *This = impl_from_IProgressDialog(iface);
    HWND hwnd;

    TRACE("(%p, 0x%s, 0x%s)\n", This, wine_dbgstr_longlong(ullCompleted), wine_dbgstr_longlong(ullTotal));

    EnterCriticalSection(&This->cs);
    This->ullTotal = ullTotal;
    This->ullCompleted = ullCompleted;
    This->dwUpdate |= UPDATE_PROGRESS;
    hwnd = This->hwnd;
    LeaveCriticalSection(&This->cs);

    if (hwnd)
        SendMessageW(hwnd, WM_DLG_UPDATE, 0, 0);

    return S_OK;  /* Windows sometimes returns S_FALSE */
}

static HRESULT WINAPI ProgressDialog_SetProgress(IProgressDialog *iface, DWORD dwCompleted, DWORD dwTotal)
{
    return IProgressDialog_SetProgress64(iface, dwCompleted, dwTotal);
}

static HRESULT WINAPI ProgressDialog_SetLine(IProgressDialog *iface, DWORD dwLineNum, LPCWSTR pwzLine, BOOL bPath, LPCVOID reserved)
{
    ProgressDialog *This = impl_from_IProgressDialog(iface);
    HWND hwnd;

    TRACE("(%p, %d, %s, %d)\n", This, dwLineNum, wine_dbgstr_w(pwzLine), bPath);

    if (reserved)
        FIXME("reserved pointer not null (%p)\n", reserved);

    dwLineNum--;
    if (dwLineNum >= 3)  /* Windows seems to do something like that */
        dwLineNum = 0;

    EnterCriticalSection(&This->cs);
    set_buffer(&This->lines[dwLineNum], pwzLine);
    This->dwUpdate |= UPDATE_LINE1 << dwLineNum;
    hwnd = (This->isCancelled ? NULL : This->hwnd); /* no sense to send the message if window cancelled */
    LeaveCriticalSection(&This->cs);

    if (hwnd)
        SendMessageW(hwnd, WM_DLG_UPDATE, 0, 0);

    return S_OK;
}

static HRESULT WINAPI ProgressDialog_SetCancelMsg(IProgressDialog *iface, LPCWSTR pwzMsg, LPCVOID reserved)
{
    ProgressDialog *This = impl_from_IProgressDialog(iface);
    HWND hwnd;

    TRACE("(%p, %s)\n", This, wine_dbgstr_w(pwzMsg));

    if (reserved)
        FIXME("reserved pointer not null (%p)\n", reserved);

    EnterCriticalSection(&This->cs);
    set_buffer(&This->cancelMsg, pwzMsg);
    This->dwUpdate |= UPDATE_LINE1 << CANCEL_MSG_LINE;
    hwnd = (This->isCancelled ? This->hwnd : NULL); /* no sense to send the message if window not cancelled */
    LeaveCriticalSection(&This->cs);

    if (hwnd)
        SendMessageW(hwnd, WM_DLG_UPDATE, 0, 0);

    return S_OK;
}

static HRESULT WINAPI ProgressDialog_Timer(IProgressDialog *iface, DWORD dwTimerAction, LPCVOID reserved)
{
    ProgressDialog *This = impl_from_IProgressDialog(iface);

    FIXME("(%p, %d, %p) - stub\n", This, dwTimerAction, reserved);

    if (reserved)
        FIXME("Reserved field not NULL but %p\n", reserved);

    return S_OK;
}

static const IProgressDialogVtbl ProgressDialogVtbl =
{
    ProgressDialog_QueryInterface,
    ProgressDialog_AddRef,
    ProgressDialog_Release,

    ProgressDialog_StartProgressDialog,
    ProgressDialog_StopProgressDialog,
    ProgressDialog_SetTitle,
    ProgressDialog_SetAnimation,
    ProgressDialog_HasUserCancelled,
    ProgressDialog_SetProgress,
    ProgressDialog_SetProgress64,
    ProgressDialog_SetLine,
    ProgressDialog_SetCancelMsg,
    ProgressDialog_Timer
};

static HRESULT WINAPI OleWindow_QueryInterface(IOleWindow *iface, REFIID iid, LPVOID *ppvOut)
{
    ProgressDialog *This = impl_from_IOleWindow(iface);
    return ProgressDialog_QueryInterface(&This->IProgressDialog_iface, iid, ppvOut);
}

static ULONG WINAPI OleWindow_AddRef(IOleWindow *iface)
{
    ProgressDialog *This = impl_from_IOleWindow(iface);
    return ProgressDialog_AddRef(&This->IProgressDialog_iface);
}

static ULONG WINAPI OleWindow_Release(IOleWindow *iface)
{
    ProgressDialog *This = impl_from_IOleWindow(iface);
    return ProgressDialog_Release(&This->IProgressDialog_iface);
}

static HRESULT WINAPI OleWindow_GetWindow(IOleWindow* iface, HWND* phwnd)
{
    ProgressDialog *This = impl_from_IOleWindow(iface);

    TRACE("(%p, %p)\n", This, phwnd);
    EnterCriticalSection(&This->cs);
    *phwnd = This->hwnd;
    LeaveCriticalSection(&This->cs);
    return S_OK;
}

static HRESULT WINAPI OleWindow_ContextSensitiveHelp(IOleWindow* iface, BOOL fEnterMode)
{
    ProgressDialog *This = impl_from_IOleWindow(iface);

    FIXME("(%p, %d): stub\n", This, fEnterMode);
    return E_NOTIMPL;
}

static const IOleWindowVtbl OleWindowVtbl =
{
    OleWindow_QueryInterface,
    OleWindow_AddRef,
    OleWindow_Release,
    OleWindow_GetWindow,
    OleWindow_ContextSensitiveHelp
};


HRESULT ProgressDialog_Constructor(IUnknown *pUnkOuter, IUnknown **ppOut)
{
    ProgressDialog *This;
    if (pUnkOuter)
        return CLASS_E_NOAGGREGATION;

    This = heap_alloc_zero(sizeof(ProgressDialog));
    if (This == NULL)
        return E_OUTOFMEMORY;

    This->IProgressDialog_iface.lpVtbl = &ProgressDialogVtbl;
    This->IOleWindow_iface.lpVtbl = &OleWindowVtbl;
    This->refCount = 1;
    InitializeCriticalSection(&This->cs);
    This->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ProgressDialog.cs");

    TRACE("returning %p\n", This);
    *ppOut = (IUnknown *)This;
    BROWSEUI_refCount++;
    return S_OK;
}
