/*
 * Task dialog control
 *
 * Copyright 2017 Fabian Maurer
 *
 * 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 <stdarg.h>
#include <stdlib.h>
#include <string.h>

#define NONAMELESSUNION

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "commctrl.h"
#include "winerror.h"
#include "comctl32.h"

#include "wine/debug.h"
#include "wine/list.h"
#include "wine/unicode.h"

WINE_DEFAULT_DEBUG_CHANNEL(taskdialog);

#define ALIGNED_LENGTH(_Len, _Align) (((_Len)+(_Align))&~(_Align))
#define ALIGNED_POINTER(_Ptr, _Align) ((LPVOID)ALIGNED_LENGTH((ULONG_PTR)(_Ptr), _Align))
#define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
#define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)

static const UINT DIALOG_MIN_WIDTH = 240;
static const UINT DIALOG_SPACING = 5;
static const UINT DIALOG_BUTTON_WIDTH = 50;
static const UINT DIALOG_BUTTON_HEIGHT = 14;

static const UINT ID_MAIN_INSTRUCTION = 0xf000;
static const UINT ID_CONTENT          = 0xf001;

struct taskdialog_control
{
    struct list entry;
    DLGITEMTEMPLATE *template;
    unsigned int template_size;
};

struct taskdialog_template_desc
{
    const TASKDIALOGCONFIG *taskconfig;
    unsigned int dialog_height;
    unsigned int dialog_width;
    struct list controls;
    WORD control_count;
    LONG x_baseunit;
    LONG y_baseunit;
    HFONT font;
};

struct taskdialog_button_desc
{
    int id;
    const WCHAR *text;
    unsigned int width;
    unsigned int line;
    HINSTANCE hinst;
};

struct taskdialog_info
{
    HWND hwnd;
    PFTASKDIALOGCALLBACK callback;
    LONG_PTR callback_data;
};

static void pixels_to_dialogunits(const struct taskdialog_template_desc *desc, LONG *width, LONG *height)
{
    if (width)
        *width = MulDiv(*width, 4, desc->x_baseunit);
    if (height)
        *height = MulDiv(*height, 8, desc->y_baseunit);
}

static void dialogunits_to_pixels(const struct taskdialog_template_desc *desc, LONG *width, LONG *height)
{
    if (width)
        *width = MulDiv(*width, desc->x_baseunit, 4);
    if (height)
        *height = MulDiv(*height, desc->y_baseunit, 8);
}

static void template_write_data(char **ptr, const void *src, unsigned int size)
{
    memcpy(*ptr, src, size);
    *ptr += size;
}

/* used to calculate size for the controls */
static void taskdialog_get_text_extent(const struct taskdialog_template_desc *desc, const WCHAR *text,
        BOOL user_resource, SIZE *sz)
{
    RECT rect = { 0, 0, desc->dialog_width - DIALOG_SPACING * 2, 0}; /* padding left and right of the control */
    const WCHAR *textW = NULL;
    static const WCHAR nulW;
    unsigned int length;
    HFONT oldfont;
    HDC hdc;

    if (IS_INTRESOURCE(text))
    {
        if (!(length = LoadStringW(user_resource ? desc->taskconfig->hInstance : COMCTL32_hModule,
                (UINT_PTR)text, (WCHAR *)&textW, 0)))
        {
            WARN("Failed to load text\n");
            textW = &nulW;
            length = 0;
        }
    }
    else
    {
        textW = text;
        length = strlenW(textW);
    }

    hdc = GetDC(0);
    oldfont = SelectObject(hdc, desc->font);

    dialogunits_to_pixels(desc, &rect.right, NULL);
    DrawTextW(hdc, textW, length, &rect, DT_LEFT | DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK);
    pixels_to_dialogunits(desc, &rect.right, &rect.bottom);

    SelectObject(hdc, oldfont);
    ReleaseDC(0, hdc);

    sz->cx = rect.right - rect.left;
    sz->cy = rect.bottom - rect.top;
}

static unsigned int taskdialog_add_control(struct taskdialog_template_desc *desc, WORD id, const WCHAR *class,
        HINSTANCE hInstance, const WCHAR *text, short x, short y, short cx, short cy)
{
    struct taskdialog_control *control = Alloc(sizeof(*control));
    unsigned int size, class_size, text_size;
    DLGITEMTEMPLATE *template;
    static const WCHAR nulW;
    const WCHAR *textW;
    char *ptr;

    class_size = (strlenW(class) + 1) * sizeof(WCHAR);

    if (IS_INTRESOURCE(text))
        text_size = LoadStringW(hInstance, (UINT_PTR)text, (WCHAR *)&textW, 0) * sizeof(WCHAR);
    else
    {
        textW = text;
        text_size = strlenW(textW) * sizeof(WCHAR);
    }

    size = sizeof(DLGITEMTEMPLATE);
    size += class_size;
    size += text_size + sizeof(WCHAR);
    size += sizeof(WORD); /* creation data */

    control->template = template = Alloc(size);
    control->template_size = size;

    template->style = WS_VISIBLE;
    template->dwExtendedStyle = 0;
    template->x = x;
    template->y = y;
    template->cx = cx;
    template->cy = cy;
    template->id = id;
    ptr = (char *)(template + 1);
    template_write_data(&ptr, class, class_size);
    template_write_data(&ptr, textW, text_size);
    template_write_data(&ptr, &nulW, sizeof(nulW));

    list_add_tail(&desc->controls, &control->entry);
    desc->control_count++;
    return ALIGNED_LENGTH(size, 3);
}

static unsigned int taskdialog_add_static_label(struct taskdialog_template_desc *desc, WORD id, const WCHAR *str)
{
    unsigned int size;
    SIZE sz;

    if (!str)
        return 0;

    taskdialog_get_text_extent(desc, str, TRUE, &sz);

    desc->dialog_height += DIALOG_SPACING;
    size = taskdialog_add_control(desc, id, WC_STATICW, desc->taskconfig->hInstance, str, DIALOG_SPACING,
            desc->dialog_height, sz.cx, sz.cy);
    desc->dialog_height += sz.cy + DIALOG_SPACING;
    return size;
}

static unsigned int taskdialog_add_main_instruction(struct taskdialog_template_desc *desc)
{
    return taskdialog_add_static_label(desc, ID_MAIN_INSTRUCTION, desc->taskconfig->pszMainInstruction);
}

static unsigned int taskdialog_add_content(struct taskdialog_template_desc *desc)
{
    return taskdialog_add_static_label(desc, ID_CONTENT, desc->taskconfig->pszContent);
}

static void taskdialog_init_button(struct taskdialog_button_desc *button, struct taskdialog_template_desc *desc,
        int id, const WCHAR *text, BOOL custom_button)
{
    SIZE sz;

    taskdialog_get_text_extent(desc, text, custom_button, &sz);

    button->id = id;
    button->text = text;
    button->width = max(DIALOG_BUTTON_WIDTH, sz.cx + DIALOG_SPACING * 2);
    button->line = 0;
    button->hinst = custom_button ? desc->taskconfig->hInstance : COMCTL32_hModule;
}

static void taskdialog_init_common_buttons(struct taskdialog_template_desc *desc, struct taskdialog_button_desc *buttons,
    unsigned int *button_count)
{
    DWORD flags = desc->taskconfig->dwCommonButtons;

#define TASKDIALOG_INIT_COMMON_BUTTON(id) \
    do { \
        taskdialog_init_button(&buttons[(*button_count)++], desc, ID##id, MAKEINTRESOURCEW(IDS_BUTTON_##id), FALSE); \
    } while(0)

    if (flags & TDCBF_OK_BUTTON)
        TASKDIALOG_INIT_COMMON_BUTTON(OK);
    if (flags & TDCBF_YES_BUTTON)
        TASKDIALOG_INIT_COMMON_BUTTON(YES);
    if (flags & TDCBF_NO_BUTTON)
        TASKDIALOG_INIT_COMMON_BUTTON(NO);
    if (flags & TDCBF_RETRY_BUTTON)
        TASKDIALOG_INIT_COMMON_BUTTON(RETRY);
    if (flags & TDCBF_CANCEL_BUTTON)
        TASKDIALOG_INIT_COMMON_BUTTON(CANCEL);
    if (flags & TDCBF_CLOSE_BUTTON)
        TASKDIALOG_INIT_COMMON_BUTTON(CLOSE);

#undef TASKDIALOG_INIT_COMMON_BUTTON
}

static unsigned int taskdialog_add_buttons(struct taskdialog_template_desc *desc)
{
    unsigned int count = 0, buttons_size, i, line_count, size = 0;
    unsigned int location_x, *line_widths, alignment = ~0u;
    const TASKDIALOGCONFIG *taskconfig = desc->taskconfig;
    struct taskdialog_button_desc *buttons;

    /* Allocate enough memory for the custom and the default buttons. Maximum 6 default buttons possible. */
    buttons_size = 6;
    if (taskconfig->cButtons && taskconfig->pButtons)
        buttons_size += taskconfig->cButtons;

    if (!(buttons = Alloc(buttons_size * sizeof(*buttons))))
        return 0;

    /* Custom buttons */
    if (taskconfig->cButtons && taskconfig->pButtons)
        for (i = 0; i < taskconfig->cButtons; i++)
            taskdialog_init_button(&buttons[count++], desc, taskconfig->pButtons[i].nButtonID,
                    taskconfig->pButtons[i].pszButtonText, TRUE);

    /* Common buttons */
    taskdialog_init_common_buttons(desc, buttons, &count);

    /* There must be at least one button */
    if (count == 0)
        taskdialog_init_button(&buttons[count++], desc, IDOK, MAKEINTRESOURCEW(IDS_BUTTON_OK), FALSE);

    /* For easy handling just allocate as many lines as buttons, the worst case. */
    line_widths = Alloc(count * sizeof(*line_widths));

    /* Separate buttons into lines */
    location_x = DIALOG_SPACING;
    for (i = 0, line_count = 0; i < count; i++)
    {
        if (location_x + buttons[i].width + DIALOG_SPACING > desc->dialog_width)
        {
            location_x = DIALOG_SPACING;
            line_count++;
        }

        buttons[i].line = line_count;

        location_x += buttons[i].width + DIALOG_SPACING;
        line_widths[line_count] += buttons[i].width + DIALOG_SPACING;
    }
    line_count++;

    /* Try to balance lines so they are about the same size */
    for (i = 1; i < line_count - 1; i++)
    {
        int diff_now = abs(line_widths[i] - line_widths[i - 1]);
        unsigned int j, last_button = 0;
        int diff_changed;

        for (j = 0; j < count; j++)
            if (buttons[j].line == i - 1)
                last_button = j;

        /* Difference in length of both lines if we wrapped the last button from the last line into this one */
        diff_changed = abs(2 * buttons[last_button].width + line_widths[i] - line_widths[i - 1]);

        if (diff_changed < diff_now)
        {
            buttons[last_button].line = i;
            line_widths[i] += buttons[last_button].width;
            line_widths[i - 1] -= buttons[last_button].width;
        }
    }

    /* Calculate left alignment so all lines are as far right as possible. */
    for (i = 0; i < line_count; i++)
    {
        int new_alignment = desc->dialog_width - line_widths[i];
        if (new_alignment < alignment)
            alignment = new_alignment;
    }

    /* Now that we got them all positioned, create all buttons */
    location_x = alignment;
    for (i = 0; i < count; i++)
    {
        if (i > 0 && buttons[i].line != buttons[i - 1].line) /* New line */
        {
            location_x = alignment;
            desc->dialog_height += DIALOG_BUTTON_HEIGHT + DIALOG_SPACING;
        }

        size += taskdialog_add_control(desc, buttons[i].id, WC_BUTTONW, buttons[i].hinst, buttons[i].text, location_x,
                desc->dialog_height, buttons[i].width, DIALOG_BUTTON_HEIGHT);

        location_x += buttons[i].width + DIALOG_SPACING;
    }

    /* Add height for last row and spacing */
    desc->dialog_height += DIALOG_BUTTON_HEIGHT + DIALOG_SPACING;

    Free(line_widths);
    Free(buttons);

    return size;
}

static void taskdialog_clear_controls(struct list *controls)
{
    struct taskdialog_control *control, *control2;

    LIST_FOR_EACH_ENTRY_SAFE(control, control2, controls, struct taskdialog_control, entry)
    {
        list_remove(&control->entry);
        Free(control->template);
        Free(control);
    }
}

static unsigned int taskdialog_get_reference_rect(const struct taskdialog_template_desc *desc, RECT *ret)
{
    HMONITOR monitor = MonitorFromWindow(desc->taskconfig->hwndParent ? desc->taskconfig->hwndParent : GetActiveWindow(),
            MONITOR_DEFAULTTOPRIMARY);
    MONITORINFO info;

    info.cbSize = sizeof(info);
    GetMonitorInfoW(monitor, &info);

    if (desc->taskconfig->dwFlags & TDF_POSITION_RELATIVE_TO_WINDOW && desc->taskconfig->hwndParent)
        GetWindowRect(desc->taskconfig->hwndParent, ret);
    else
        *ret = info.rcWork;

    pixels_to_dialogunits(desc, &ret->left, &ret->top);
    pixels_to_dialogunits(desc, &ret->right, &ret->bottom);

    pixels_to_dialogunits(desc, &info.rcWork.left, &info.rcWork.top);
    pixels_to_dialogunits(desc, &info.rcWork.right, &info.rcWork.bottom);
    return info.rcWork.right - info.rcWork.left;
}

static WCHAR *taskdialog_get_exe_name(const TASKDIALOGCONFIG *taskconfig, WCHAR *name, DWORD length)
{
    DWORD len = GetModuleFileNameW(NULL, name, length);
    if (len && len < length)
    {
        WCHAR *p;
        if ((p = strrchrW(name, '/'))) name = p + 1;
        if ((p = strrchrW(name, '\\'))) name = p + 1;
        return name;
    }
    else
        return NULL;
}

static DLGTEMPLATE *create_taskdialog_template(const TASKDIALOGCONFIG *taskconfig)
{
    struct taskdialog_control *control, *control2;
    unsigned int size, title_size, screen_width;
    struct taskdialog_template_desc desc;
    static const WORD fontsize = 0x7fff;
    static const WCHAR emptyW[] = { 0 };
    const WCHAR *titleW = NULL;
    DLGTEMPLATE *template;
    NONCLIENTMETRICSW ncm;
    WCHAR pathW[MAX_PATH];
    RECT ref_rect;
    char *ptr;
    HDC hdc;

    /* Window title */
    if (!taskconfig->pszWindowTitle)
        titleW = taskdialog_get_exe_name(taskconfig, pathW, sizeof(pathW)/sizeof(pathW[0]));
    else if (IS_INTRESOURCE(taskconfig->pszWindowTitle))
    {
        if (!LoadStringW(taskconfig->hInstance, LOWORD(taskconfig->pszWindowTitle), (WCHAR *)&titleW, 0))
            titleW = taskdialog_get_exe_name(taskconfig, pathW, sizeof(pathW)/sizeof(pathW[0]));
    }
    else
        titleW = taskconfig->pszWindowTitle;
    if (!titleW)
        titleW = emptyW;
    title_size = (strlenW(titleW) + 1) * sizeof(WCHAR);

    size = sizeof(DLGTEMPLATE) + 2 * sizeof(WORD);
    size += title_size;
    size += 2; /* font size */

    list_init(&desc.controls);
    desc.taskconfig = taskconfig;
    desc.control_count = 0;

    ncm.cbSize = sizeof(ncm);
    SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, ncm.cbSize, &ncm, 0);
    desc.font = CreateFontIndirectW(&ncm.lfMessageFont);

    hdc = GetDC(0);
    SelectObject(hdc, desc.font);
    desc.x_baseunit = GdiGetCharDimensions(hdc, NULL, &desc.y_baseunit);
    ReleaseDC(0, hdc);

    screen_width = taskdialog_get_reference_rect(&desc, &ref_rect);

    desc.dialog_height = 0;
    desc.dialog_width = max(taskconfig->cxWidth, DIALOG_MIN_WIDTH);
    desc.dialog_width = min(desc.dialog_width, screen_width);

    size += taskdialog_add_main_instruction(&desc);
    size += taskdialog_add_content(&desc);
    size += taskdialog_add_buttons(&desc);

    template = Alloc(size);
    if (!template)
    {
        taskdialog_clear_controls(&desc.controls);
        DeleteObject(desc.font);
        return NULL;
    }

    template->style = DS_MODALFRAME | DS_SETFONT | WS_CAPTION | WS_VISIBLE | WS_SYSMENU;
    template->cdit = desc.control_count;
    template->x = (ref_rect.left + ref_rect.right + desc.dialog_width) / 2;
    template->y = (ref_rect.top + ref_rect.bottom + desc.dialog_height) / 2;
    template->cx = desc.dialog_width;
    template->cy = desc.dialog_height;

    ptr = (char *)(template + 1);
    ptr += 2; /* menu */
    ptr += 2; /* class */
    template_write_data(&ptr, titleW, title_size);
    template_write_data(&ptr, &fontsize, sizeof(fontsize));

    /* write control entries */
    LIST_FOR_EACH_ENTRY_SAFE(control, control2, &desc.controls, struct taskdialog_control, entry)
    {
        ALIGN_POINTER(ptr, 3);

        template_write_data(&ptr, control->template, control->template_size);

        /* list item won't be needed later */
        list_remove(&control->entry);
        Free(control->template);
        Free(control);
    }

    DeleteObject(desc.font);
    return template;
}

static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notification, WPARAM wparam, LPARAM lparam)
{
    return dialog_info->callback ? dialog_info->callback(dialog_info->hwnd, notification, wparam, lparam,
            dialog_info->callback_data) : S_OK;
}

static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, WORD command_id)
{
    if (taskdialog_notify(dialog_info, TDN_BUTTON_CLICKED, command_id, 0) == S_OK)
        EndDialog(dialog_info->hwnd, command_id);
}

static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static const WCHAR taskdialog_info_propnameW[] = {'T','a','s','k','D','i','a','l','o','g','I','n','f','o',0};
    struct taskdialog_info *dialog_info;

    TRACE("hwnd=%p msg=0x%04x wparam=%lx lparam=%lx\n", hwnd, msg, wParam, lParam);

    if (msg != WM_INITDIALOG)
        dialog_info = GetPropW(hwnd, taskdialog_info_propnameW);

    switch (msg)
    {
        case TDM_CLICK_BUTTON:
            taskdialog_on_button_click(dialog_info, LOWORD(wParam));
            break;
        case WM_INITDIALOG:
            dialog_info = (struct taskdialog_info *)lParam;
            dialog_info->hwnd = hwnd;
            SetPropW(hwnd, taskdialog_info_propnameW, dialog_info);

            taskdialog_notify(dialog_info, TDN_DIALOG_CONSTRUCTED, 0, 0);
            break;
        case WM_SHOWWINDOW:
            taskdialog_notify(dialog_info, TDN_CREATED, 0, 0);
            break;
        case WM_COMMAND:
            if (HIWORD(wParam) == BN_CLICKED)
            {
                taskdialog_on_button_click(dialog_info, LOWORD(wParam));
                return TRUE;
            }
            break;
        case WM_DESTROY:
            taskdialog_notify(dialog_info, TDN_DESTROYED, 0, 0);
            RemovePropW(hwnd, taskdialog_info_propnameW);
            break;
    }
    return FALSE;
}

/***********************************************************************
 * TaskDialogIndirect [COMCTL32.@]
 */
HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *taskconfig, int *button,
                                  int *radio_button, BOOL *verification_flag_checked)
{
    struct taskdialog_info dialog_info;
    DLGTEMPLATE *template;
    INT ret;

    TRACE("%p, %p, %p, %p\n", taskconfig, button, radio_button, verification_flag_checked);

    if (!taskconfig || taskconfig->cbSize != sizeof(TASKDIALOGCONFIG))
        return E_INVALIDARG;

    dialog_info.callback = taskconfig->pfCallback;
    dialog_info.callback_data = taskconfig->lpCallbackData;

    template = create_taskdialog_template(taskconfig);
    ret = DialogBoxIndirectParamW(taskconfig->hInstance, template, taskconfig->hwndParent,
            taskdialog_proc, (LPARAM)&dialog_info);
    Free(template);

    if (button) *button = ret;
    if (radio_button) *radio_button = taskconfig->nDefaultButton;
    if (verification_flag_checked) *verification_flag_checked = TRUE;

    return S_OK;
}

/***********************************************************************
 * TaskDialog [COMCTL32.@]
 */
HRESULT WINAPI TaskDialog(HWND owner, HINSTANCE hinst, const WCHAR *title, const WCHAR *main_instruction,
    const WCHAR *content, TASKDIALOG_COMMON_BUTTON_FLAGS common_buttons, const WCHAR *icon, int *button)
{
    TASKDIALOGCONFIG taskconfig;

    TRACE("%p, %p, %s, %s, %s, %#x, %s, %p\n", owner, hinst, debugstr_w(title), debugstr_w(main_instruction),
        debugstr_w(content), common_buttons, debugstr_w(icon), button);

    memset(&taskconfig, 0, sizeof(taskconfig));
    taskconfig.cbSize = sizeof(taskconfig);
    taskconfig.hwndParent = owner;
    taskconfig.hInstance = hinst;
    taskconfig.dwCommonButtons = common_buttons;
    taskconfig.pszWindowTitle = title;
    taskconfig.u.pszMainIcon = icon;
    taskconfig.pszMainInstruction = main_instruction;
    taskconfig.pszContent = content;
    return TaskDialogIndirect(&taskconfig, button, NULL, NULL);
}
