/*
 * The dialog that displays after a crash
 *
 * Copyright 2008 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 "debugger.h"
#include "wingdi.h"
#include "winuser.h"
#include "commctrl.h"
#include "commdlg.h"
#include "shellapi.h"
#include "psapi.h"

#include "wine/unicode.h"

#include "resource.h"

#define MAX_PROGRAM_NAME_LENGTH 80

static char *crash_log;

int msgbox_res_id(HWND hwnd, UINT textId, UINT captionId, UINT uType)
{
    WCHAR caption[256];
    WCHAR text[256];
    LoadStringW(GetModuleHandleW(NULL), captionId, caption, sizeof(caption)/sizeof(caption[0]));
    LoadStringW(GetModuleHandleW(NULL), textId, text, sizeof(text)/sizeof(text[0]));
    return MessageBoxW(hwnd, text, caption, uType);
}

static WCHAR *get_program_name(HANDLE hProcess)
{
    WCHAR image_name[MAX_PATH];
    WCHAR *programname;
    WCHAR *output;

    /* GetProcessImageFileNameW gives no way to query the correct buffer size,
     * but programs with a path longer than MAX_PATH can't be started by the
     * shell, so we expect they don't happen often */
    if (!GetProcessImageFileNameW(hProcess, image_name, MAX_PATH))
    {
        static WCHAR unidentified[MAX_PROGRAM_NAME_LENGTH];
        LoadStringW(GetModuleHandleW(NULL), IDS_UNIDENTIFIED,
                unidentified, MAX_PROGRAM_NAME_LENGTH);
        return unidentified;
    }

    programname = strrchrW(image_name, '\\');
    if (programname != NULL)
        programname++;
    else
        programname = image_name;

    /* TODO: if the image has a VERSIONINFO, we could try to find there a more
     * user-friendly program name */

    /* don't display a too long string to the user */
    if (strlenW(programname) >= MAX_PROGRAM_NAME_LENGTH)
    {
        programname[MAX_PROGRAM_NAME_LENGTH - 4] = '.';
        programname[MAX_PROGRAM_NAME_LENGTH - 3] = '.';
        programname[MAX_PROGRAM_NAME_LENGTH - 2] = '.';
        programname[MAX_PROGRAM_NAME_LENGTH - 1] = 0;
    }

    output = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(lstrlenW(programname) + 1));
    lstrcpyW(output, programname);

    return output;
}

static LPWSTR g_ProgramName;
static HFONT g_hBoldFont;
static HMENU g_hDebugMenu = NULL;

static void set_bold_font(HWND hDlg)
{
    HFONT hNormalFont = (HFONT)SendDlgItemMessageW(hDlg, IDC_STATIC_TXT1,
            WM_GETFONT, 0, 0);
    LOGFONTW font;
    GetObjectW(hNormalFont, sizeof(LOGFONTW), &font);
    font.lfWeight = FW_BOLD;
    g_hBoldFont = CreateFontIndirectW(&font);
    SendDlgItemMessageW(hDlg, IDC_STATIC_TXT1, WM_SETFONT, (WPARAM)g_hBoldFont, TRUE);
}

static void set_fixed_font( HWND dlg, UINT id )
{
    HFONT hfont = (HFONT)SendDlgItemMessageW( dlg, id, WM_GETFONT, 0, 0);
    LOGFONTW font;

    GetObjectW(hfont, sizeof(LOGFONTW), &font);
    font.lfPitchAndFamily = FIXED_PITCH;
    font.lfFaceName[0] = 0;
    hfont = CreateFontIndirectW(&font);
    SendDlgItemMessageW( dlg, id, WM_SETFONT, (WPARAM)hfont, TRUE );
}

static void set_message_with_filename(HWND hDlg)
{
    WCHAR originalText[1000];
    WCHAR newText[1000 + MAX_PROGRAM_NAME_LENGTH];

    GetDlgItemTextW(hDlg, IDC_STATIC_TXT1, originalText,
            sizeof(originalText)/sizeof(originalText[0]));
    wsprintfW(newText, originalText, g_ProgramName);
    SetDlgItemTextW(hDlg, IDC_STATIC_TXT1, newText);
}

static void load_crash_log( HANDLE file )
{
    DWORD len, pos = 0, size = 65536;

    crash_log = HeapAlloc( GetProcessHeap(), 0, size );
    SetFilePointer( file, 0, NULL, FILE_BEGIN );
    while (ReadFile( file, crash_log + pos, size - pos - 1, &len, NULL ) && len)
    {
        pos += len;
        if (pos == size - 1) crash_log = HeapReAlloc( GetProcessHeap(), 0, crash_log, size *= 2 );
    }
    crash_log[pos] = 0;
}

static void save_crash_log( HWND hwnd )
{
    OPENFILENAMEW save;
    HANDLE handle;
    DWORD err, written;
    WCHAR *p, path[MAX_PATH], buffer[1024];
    static const WCHAR default_name[] = { 'b','a','c','k','t','r','a','c','e','.','t','x','t',0 };
    static const WCHAR default_ext[] = { 't','x','t',0 };
    static const WCHAR txt_files[] = { '*','.','t','x','t',0 };
    static const WCHAR all_files[] = { '*','.','*',0 };

    memset( &save, 0, sizeof(save) );
    lstrcpyW( path, default_name );

    LoadStringW( GetModuleHandleW(0), IDS_TEXT_FILES, buffer, sizeof(buffer)/sizeof(buffer[0]) );
    p = buffer + lstrlenW(buffer) + 1;
    lstrcpyW(p, txt_files);
    p += lstrlenW(p) + 1;
    LoadStringW( GetModuleHandleW(0), IDS_ALL_FILES, p, sizeof(buffer)/sizeof(buffer[0]) - (p - buffer) );
    p += lstrlenW(p) + 1;
    lstrcpyW(p, all_files);
    p += lstrlenW(p) + 1;
    *p = '\0';

    save.lStructSize = sizeof(OPENFILENAMEW);
    save.hwndOwner   = hwnd;
    save.hInstance   = GetModuleHandleW(0);
    save.lpstrFilter = buffer;
    save.lpstrFile   = path;
    save.nMaxFile    = MAX_PATH;
    save.Flags       = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT |
                       OFN_HIDEREADONLY | OFN_ENABLESIZING;
    save.lpstrDefExt = default_ext;

    if (!GetSaveFileNameW( &save )) return;
    handle = CreateFileW( save.lpstrFile, GENERIC_WRITE, FILE_SHARE_READ,
                        NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
    if (handle != INVALID_HANDLE_VALUE)
    {
        if (!WriteFile( handle, crash_log, strlen(crash_log), &written, NULL ))
            err = GetLastError();
        else if (written != strlen(crash_log))
            err = GetLastError();
        else
        {
            CloseHandle( handle );
            return;
        }
        CloseHandle( handle );
        DeleteFileW( save.lpstrFile );
    }
    else err = GetLastError();

    LoadStringW( GetModuleHandleW(0), IDS_SAVE_ERROR, buffer, sizeof(buffer)/sizeof(WCHAR) );
    FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                    NULL, err, 0, (LPWSTR)&p, 0, NULL);
    MessageBoxW( 0, p, buffer, MB_OK | MB_ICONERROR);
    LocalFree( p );
}

static INT_PTR WINAPI crash_dlg_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static const WCHAR openW[] = {'o','p','e','n',0};
    switch (msg)
    {
    case WM_INITDIALOG:
    {
        set_bold_font(hwnd);
        set_message_with_filename(hwnd);
        return TRUE;
    }
    case WM_CTLCOLORSTATIC:
    {
        /* WM_CTLCOLOR* don't use DWLP_MSGRESULT */
        INT_PTR id = GetDlgCtrlID((HWND)lParam);
        if (id == IDC_STATIC_BG || id == IDC_STATIC_TXT1)
            return (LONG_PTR)GetSysColorBrush(COLOR_WINDOW);

        return FALSE;
    }
    case WM_RBUTTONDOWN:
    {
        POINT mousePos;
        if (!(wParam & MK_SHIFT))
            return FALSE;
        if (g_hDebugMenu == NULL)
            g_hDebugMenu = LoadMenuW(GetModuleHandleW(NULL), MAKEINTRESOURCEW(IDM_DEBUG_POPUP));
        GetCursorPos(&mousePos);
        TrackPopupMenu(GetSubMenu(g_hDebugMenu, 0), TPM_RIGHTBUTTON, mousePos.x, mousePos.y,
                0, hwnd, NULL);
        return TRUE;
    }
    case WM_NOTIFY:
        switch (((NMHDR *)lParam)->code)
        {
        case NM_CLICK:
        case NM_RETURN:
            if (wParam == IDC_STATIC_TXT2)
                ShellExecuteW( NULL, openW, ((NMLINK *)lParam)->item.szUrl, NULL, NULL, SW_SHOW );
            break;
        }
        break;

    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
            case IDOK:
            case IDCANCEL:
            case ID_DEBUG:
            case ID_DETAILS:
                EndDialog(hwnd, LOWORD(wParam));
                return TRUE;
        }
        return TRUE;
    }
    return FALSE;
}

static INT_PTR WINAPI details_dlg_proc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
    static const WCHAR openW[] = {'o','p','e','n',0};
    static POINT orig_size, min_size, edit_size, text_pos, save_pos, close_pos;

    switch (msg)
    {
    case WM_INITDIALOG:
    {
        RECT rect;
        WCHAR buffer[256];

        set_fixed_font( hwnd, IDC_CRASH_TXT );
        LoadStringW( GetModuleHandleW(0), IDS_LOADING, buffer, 256 );
        SetDlgItemTextW( hwnd, IDC_CRASH_TXT, buffer );
        EnableWindow( GetDlgItem( hwnd, IDC_CRASH_TXT ), FALSE );
        EnableWindow( GetDlgItem( hwnd, ID_SAVEAS ), FALSE );

        GetClientRect( hwnd, &rect );
        orig_size.x = rect.right;
        orig_size.y = rect.bottom;

        GetWindowRect( hwnd, &rect );
        min_size.x = rect.right - rect.left;
        min_size.y = rect.bottom - rect.top;

        GetWindowRect( GetDlgItem( hwnd, IDOK ), &rect );
        MapWindowPoints( 0, hwnd, (POINT *)&rect, 2 );
        close_pos.x = rect.left;
        close_pos.y = rect.top;

        GetWindowRect( GetDlgItem( hwnd, ID_SAVEAS ), &rect );
        MapWindowPoints( 0, hwnd, (POINT *)&rect, 2 );
        save_pos.x = rect.left;
        save_pos.y = rect.top;

        GetWindowRect( GetDlgItem( hwnd, IDC_STATIC_TXT2 ), &rect );
        MapWindowPoints( 0, hwnd, (POINT *)&rect, 2 );
        text_pos.x = rect.left;
        text_pos.y = rect.top;

        GetWindowRect( GetDlgItem( hwnd, IDC_CRASH_TXT ), &rect );
        MapWindowPoints( 0, hwnd, (POINT *)&rect, 2 );
        edit_size.x = rect.right - rect.left;
        edit_size.y = rect.bottom - rect.top;
        return TRUE;
    }

    case WM_GETMINMAXINFO:
        ((MINMAXINFO *)lparam)->ptMinTrackSize = min_size;
        return TRUE;

    case WM_SIZE:
        if (wparam == SIZE_RESTORED || wparam == SIZE_MAXIMIZED)
        {
            int off_x = (short)LOWORD( lparam ) - orig_size.x;
            int off_y = (short)HIWORD( lparam ) - orig_size.y;

            SetWindowPos( GetDlgItem( hwnd, IDOK ), 0, close_pos.x + off_x,
                          close_pos.y + off_y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
            SetWindowPos( GetDlgItem( hwnd, ID_SAVEAS ), 0, save_pos.x + off_x,
                          save_pos.y + off_y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
            SetWindowPos( GetDlgItem( hwnd, IDC_STATIC_TXT2 ), 0, text_pos.x,
                          text_pos.y + off_y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
            SetWindowPos( GetDlgItem( hwnd, IDC_CRASH_TXT ), 0, 0, 0, edit_size.x + off_x,
                          edit_size.y + off_y, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
        }
        return TRUE;

    case WM_NOTIFY:
        switch (((NMHDR *)lparam)->code)
        {
        case NM_CLICK:
        case NM_RETURN:
            if (wparam == IDC_STATIC_TXT2)
                ShellExecuteW( NULL, openW, ((NMLINK *)lparam)->item.szUrl, NULL, NULL, SW_SHOW );
            break;
        }
        break;

    case WM_COMMAND:
        switch (LOWORD(wparam))
        {
        case ID_SAVEAS:
            save_crash_log( hwnd );
            break;
        case IDOK:
        case IDCANCEL:
            PostQuitMessage( 0 );
            break;
        }
        return TRUE;
    }
    return FALSE;
}

int display_crash_dialog(void)
{
    static const WCHAR winedeviceW[] = {'w','i','n','e','d','e','v','i','c','e','.','e','x','e',0};
    static const INITCOMMONCONTROLSEX init = { sizeof(init), ICC_LINK_CLASS };

    /* dbg_curr_process->handle is not set */
    HANDLE hProcess;

    if (!DBG_IVAR(ShowCrashDialog))
        return TRUE;

    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dbg_curr_pid);
    g_ProgramName = get_program_name(hProcess);
    CloseHandle(hProcess);
    if (!strcmpW( g_ProgramName, winedeviceW )) return TRUE;
    InitCommonControlsEx( &init );
    return DialogBoxW(GetModuleHandleW(NULL), MAKEINTRESOURCEW(IDD_CRASH_DLG), NULL, crash_dlg_proc);
}

static DWORD WINAPI crash_details_thread( void *event )
{
    MSG msg;
    HWND dialog;

    dialog = CreateDialogW( GetModuleHandleW(0), MAKEINTRESOURCEW(IDD_DETAILS_DLG), 0, details_dlg_proc );
    if (!dialog) return 1;

    for (;;)
    {
        if (MsgWaitForMultipleObjects( 1, &event, FALSE, INFINITE, QS_ALLINPUT ) == 0)
        {
            load_crash_log( dbg_houtput );
            SetDlgItemTextA( dialog, IDC_CRASH_TXT, crash_log );
            EnableWindow( GetDlgItem( dialog, IDC_CRASH_TXT ), TRUE );
            EnableWindow( GetDlgItem( dialog, ID_SAVEAS ), TRUE );
            break;
        }
        while (PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ))
        {
            if (msg.message == WM_QUIT) return 0;
            TranslateMessage( &msg );
            DispatchMessageW( &msg );
        }
    }

    while (GetMessageW( &msg, 0, 0, 0 ))
    {
        TranslateMessage( &msg );
        DispatchMessageW( &msg );
    }
    return 0;
}

HANDLE display_crash_details( HANDLE event )
{
    return CreateThread( NULL, 0, crash_details_thread, event, 0, NULL );
}
