/*
 *  Notepad (dialog.c)
 *
 *  Copyright 1998,99 Marcel Baur <mbaur@g26.ethz.ch>
 *  Copyright 2002 Sylvain Petreolle <spetreolle@yahoo.fr>
 *  Copyright 2002 Andriy Palamarchuk
 *  Copyright 2007 Rolf Kalbermatter
 *  Copyright 2010 Vitaly Perov
 *
 * 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 <assert.h>
#include <stdio.h>
#include <windows.h>
#include <shellapi.h>
#include <commdlg.h>
#include <shlwapi.h>
#include <winternl.h>

#include "main.h"
#include "dialog.h"

#define SPACES_IN_TAB 8
#define PRINT_LEN_MAX 500

static const WCHAR helpfileW[] = { 'n','o','t','e','p','a','d','.','h','l','p',0 };

static INT_PTR WINAPI DIALOG_PAGESETUP_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);

/* Swap bytes of WCHAR buffer (big-endian <-> little-endian). */
static inline void byteswap_wide_string(LPWSTR str, UINT num)
{
    UINT i;
    for (i = 0; i < num; i++) str[i] = RtlUshortByteSwap(str[i]);
}

static void load_encoding_name(ENCODING enc, WCHAR* buffer, int length)
{
    switch (enc)
    {
        case ENCODING_UTF16LE:
            LoadStringW(Globals.hInstance, STRING_UNICODE_LE, buffer, length);
            break;

        case ENCODING_UTF16BE:
            LoadStringW(Globals.hInstance, STRING_UNICODE_BE, buffer, length);
            break;

        case ENCODING_UTF8:
            LoadStringW(Globals.hInstance, STRING_UTF8, buffer, length);
            break;

        case ENCODING_ANSI:
        {
            CPINFOEXW cpi;
            GetCPInfoExW(CP_ACP, 0, &cpi);
            lstrcpynW(buffer, cpi.CodePageName, length);
            break;
        }

        default:
            assert(0 && "bad encoding in load_encoding_name");
            break;
    }
}

VOID ShowLastError(void)
{
    DWORD error = GetLastError();
    if (error != NO_ERROR)
    {
        LPWSTR lpMsgBuf;
        WCHAR szTitle[MAX_STRING_LEN];

        LoadStringW(Globals.hInstance, STRING_ERROR, szTitle, ARRAY_SIZE(szTitle));
        FormatMessageW(
            FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
            NULL, error, 0, (LPWSTR)&lpMsgBuf, 0, NULL);
        MessageBoxW(NULL, lpMsgBuf, szTitle, MB_OK | MB_ICONERROR);
        LocalFree(lpMsgBuf);
    }
}

/**
 * Sets the caption of the main window according to Globals.szFileTitle:
 *    Untitled - Notepad        if no file is open
 *    filename - Notepad        if a file is given
 */
void UpdateWindowCaption(void)
{
  static const WCHAR hyphenW[] = { ' ','-',' ',0 };
  WCHAR szNotepad[64];
  WCHAR szCaption[ARRAY_SIZE(Globals.szFileTitle) + ARRAY_SIZE(hyphenW) + ARRAY_SIZE(szNotepad)];

  if (Globals.szFileTitle[0] != '\0')
      lstrcpyW(szCaption, Globals.szFileTitle);
  else
      LoadStringW(Globals.hInstance, STRING_UNTITLED, szCaption, ARRAY_SIZE(szCaption));

  LoadStringW(Globals.hInstance, STRING_NOTEPAD, szNotepad, ARRAY_SIZE(szNotepad));
  lstrcatW(szCaption, hyphenW);
  lstrcatW(szCaption, szNotepad);

  SetWindowTextW(Globals.hMainWnd, szCaption);
}

int DIALOG_StringMsgBox(HWND hParent, int formatId, LPCWSTR szString, DWORD dwFlags)
{
   WCHAR szMessage[MAX_STRING_LEN];
   WCHAR szResource[MAX_STRING_LEN];

   /* Load and format szMessage */
   LoadStringW(Globals.hInstance, formatId, szResource, ARRAY_SIZE(szResource));
   wnsprintfW(szMessage, ARRAY_SIZE(szMessage), szResource, szString);

   /* Load szCaption */
   if ((dwFlags & MB_ICONMASK) == MB_ICONEXCLAMATION)
     LoadStringW(Globals.hInstance, STRING_ERROR,  szResource, ARRAY_SIZE(szResource));
   else
     LoadStringW(Globals.hInstance, STRING_NOTEPAD,  szResource, ARRAY_SIZE(szResource));

   /* Display Modal Dialog */
   if (hParent == NULL)
     hParent = Globals.hMainWnd;
   return MessageBoxW(hParent, szMessage, szResource, dwFlags);
}

static void AlertFileNotFound(LPCWSTR szFileName)
{
   DIALOG_StringMsgBox(NULL, STRING_NOTFOUND, szFileName, MB_ICONEXCLAMATION|MB_OK);
}

static int AlertFileNotSaved(LPCWSTR szFileName)
{
   WCHAR szUntitled[MAX_STRING_LEN];

   LoadStringW(Globals.hInstance, STRING_UNTITLED, szUntitled, ARRAY_SIZE(szUntitled));
   return DIALOG_StringMsgBox(NULL, STRING_NOTSAVED, szFileName[0] ? szFileName : szUntitled,
     MB_ICONQUESTION|MB_YESNOCANCEL);
}

static int AlertUnicodeCharactersLost(LPCWSTR szFileName)
{
    WCHAR szCaption[MAX_STRING_LEN];
    WCHAR szMsgFormat[MAX_STRING_LEN];
    WCHAR szEnc[MAX_STRING_LEN];
    WCHAR* szMsg;
    DWORD_PTR args[2];
    int rc;

    LoadStringW(Globals.hInstance, STRING_NOTEPAD, szCaption,
                ARRAY_SIZE(szCaption));
    LoadStringW(Globals.hInstance, STRING_LOSS_OF_UNICODE_CHARACTERS,
                szMsgFormat, ARRAY_SIZE(szMsgFormat));
    load_encoding_name(ENCODING_ANSI, szEnc, ARRAY_SIZE(szEnc));
    args[0] = (DWORD_PTR)szFileName;
    args[1] = (DWORD_PTR)szEnc;
    FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_ARGUMENT_ARRAY, szMsgFormat, 0, 0, (LPWSTR)&szMsg, 0, (__ms_va_list*)args);
    rc = MessageBoxW(Globals.hMainWnd, szMsg, szCaption,
                     MB_OKCANCEL|MB_ICONEXCLAMATION);
    LocalFree(szMsg);
    return rc;
}

/**
 * Returns:
 *   TRUE  - if file exists
 *   FALSE - if file does not exist
 */
BOOL FileExists(LPCWSTR szFilename)
{
   WIN32_FIND_DATAW entry;
   HANDLE hFile;

   hFile = FindFirstFileW(szFilename, &entry);
   FindClose(hFile);

   return (hFile != INVALID_HANDLE_VALUE);
}

static inline BOOL is_conversion_to_ansi_lossy(LPCWSTR textW, int lenW)
{
    BOOL ret = FALSE;
    WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, textW, lenW, NULL, 0,
                        NULL, &ret);
    return ret;
}

typedef enum
{
    SAVED_OK,
    SAVE_FAILED,
    SHOW_SAVEAS_DIALOG
} SAVE_STATUS;

/* szFileName is the filename to save under; enc is the encoding to use.
 *
 * If the function succeeds, it returns SAVED_OK.
 * If the function fails, it returns SAVE_FAILED.
 * If Unicode data could be lost due to conversion to a non-Unicode character
 * set, a warning is displayed. The user can continue (and the function carries
 * on), or cancel (and the function returns SHOW_SAVEAS_DIALOG).
 */
static SAVE_STATUS DoSaveFile(LPCWSTR szFileName, ENCODING enc)
{
    int lenW;
    WCHAR* textW;
    HANDLE hFile;
    DWORD dwNumWrite;
    PVOID pBytes;
    DWORD size;

    /* lenW includes the byte-order mark, but not the \0. */
    lenW = GetWindowTextLengthW(Globals.hEdit) + 1;
    textW = HeapAlloc(GetProcessHeap(), 0, (lenW+1) * sizeof(WCHAR));
    if (!textW)
    {
        ShowLastError();
        return SAVE_FAILED;
    }
    textW[0] = (WCHAR) 0xfeff;
    lenW = GetWindowTextW(Globals.hEdit, textW+1, lenW) + 1;

    switch (enc)
    {
    case ENCODING_UTF16BE:
        byteswap_wide_string(textW, lenW);
        /* fall through */

    case ENCODING_UTF16LE:
        size = lenW * sizeof(WCHAR);
        pBytes = textW;
        break;

    case ENCODING_UTF8:
        size = WideCharToMultiByte(CP_UTF8, 0, textW, lenW, NULL, 0, NULL, NULL);
        pBytes = HeapAlloc(GetProcessHeap(), 0, size);
        if (!pBytes)
        {
            ShowLastError();
            HeapFree(GetProcessHeap(), 0, textW);
            return SAVE_FAILED;
        }
        WideCharToMultiByte(CP_UTF8, 0, textW, lenW, pBytes, size, NULL, NULL);
        HeapFree(GetProcessHeap(), 0, textW);
        break;

    default:
        if (is_conversion_to_ansi_lossy(textW+1, lenW-1)
            && AlertUnicodeCharactersLost(szFileName) == IDCANCEL)
        {
            HeapFree(GetProcessHeap(), 0, textW);
            return SHOW_SAVEAS_DIALOG;
        }

        size = WideCharToMultiByte(CP_ACP, 0, textW+1, lenW-1, NULL, 0, NULL, NULL);
        pBytes = HeapAlloc(GetProcessHeap(), 0, size);
        if (!pBytes)
        {
            ShowLastError();
            HeapFree(GetProcessHeap(), 0, textW);
            return SAVE_FAILED;
        }
        WideCharToMultiByte(CP_ACP, 0, textW+1, lenW-1, pBytes, size, NULL, NULL);
        HeapFree(GetProcessHeap(), 0, textW);
        break;
    }

    hFile = CreateFileW(szFileName, GENERIC_WRITE, FILE_SHARE_WRITE,
                       NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if(hFile == INVALID_HANDLE_VALUE)
    {
        ShowLastError();
        HeapFree(GetProcessHeap(), 0, pBytes);
        return SAVE_FAILED;
    }
    if (!WriteFile(hFile, pBytes, size, &dwNumWrite, NULL))
    {
        ShowLastError();
        CloseHandle(hFile);
        HeapFree(GetProcessHeap(), 0, pBytes);
        return SAVE_FAILED;
    }
    SetEndOfFile(hFile);
    CloseHandle(hFile);
    HeapFree(GetProcessHeap(), 0, pBytes);

    SendMessageW(Globals.hEdit, EM_SETMODIFY, FALSE, 0);
    return SAVED_OK;
}

/**
 * Returns:
 *   TRUE  - User agreed to close (both save/don't save)
 *   FALSE - User cancelled close by selecting "Cancel"
 */
BOOL DoCloseFile(void)
{
    int nResult;
    static const WCHAR empty_strW[] = { 0 };

    nResult=GetWindowTextLengthW(Globals.hEdit);
    if (SendMessageW(Globals.hEdit, EM_GETMODIFY, 0, 0) &&
        (nResult || Globals.szFileName[0]))
    {
        /* prompt user to save changes */
        nResult = AlertFileNotSaved(Globals.szFileName);
        switch (nResult) {
            case IDYES:     return DIALOG_FileSave();

            case IDNO:      break;

            case IDCANCEL:  return(FALSE);

            default:        return(FALSE);
        } /* switch */
    } /* if */

    SetFileNameAndEncoding(empty_strW, ENCODING_ANSI);

    UpdateWindowCaption();
    return(TRUE);
}

static inline ENCODING detect_encoding_of_buffer(const void* buffer, int size)
{
    static const char bom_utf8[] = { 0xef, 0xbb, 0xbf };
    if (size >= sizeof(bom_utf8) && !memcmp(buffer, bom_utf8, sizeof(bom_utf8)))
        return ENCODING_UTF8;
    else
    {
        int flags = IS_TEXT_UNICODE_SIGNATURE |
                    IS_TEXT_UNICODE_REVERSE_SIGNATURE |
                    IS_TEXT_UNICODE_ODD_LENGTH;
        IsTextUnicode(buffer, size, &flags);
        if (flags & IS_TEXT_UNICODE_SIGNATURE)
            return ENCODING_UTF16LE;
        else if (flags & IS_TEXT_UNICODE_REVERSE_SIGNATURE)
            return ENCODING_UTF16BE;
        else
            return ENCODING_ANSI;
    }
}

void DoOpenFile(LPCWSTR szFileName, ENCODING enc)
{
    static const WCHAR dotlog[] = { '.','L','O','G',0 };
    HANDLE hFile;
    LPSTR pTemp;
    DWORD size;
    DWORD dwNumRead;
    int lenW;
    WCHAR* textW;
    int i;
    WCHAR log[5];

    /* Close any files and prompt to save changes */
    if (!DoCloseFile())
	return;

    hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
                        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if(hFile == INVALID_HANDLE_VALUE)
    {
	AlertFileNotFound(szFileName);
	return;
    }

    size = GetFileSize(hFile, NULL);
    if (size == INVALID_FILE_SIZE)
    {
	CloseHandle(hFile);
	ShowLastError();
	return;
    }

    /* Extra memory for (WCHAR)'\0'-termination. */
    pTemp = HeapAlloc(GetProcessHeap(), 0, size+2);
    if (!pTemp)
    {
	CloseHandle(hFile);
	ShowLastError();
	return;
    }

    if (!ReadFile(hFile, pTemp, size, &dwNumRead, NULL))
    {
	CloseHandle(hFile);
	HeapFree(GetProcessHeap(), 0, pTemp);
	ShowLastError();
	return;
    }

    CloseHandle(hFile);

    size = dwNumRead;

    if (enc == ENCODING_AUTO)
        enc = detect_encoding_of_buffer(pTemp, size);
    else if (size >= 2 && (enc==ENCODING_UTF16LE || enc==ENCODING_UTF16BE))
    {
        /* If UTF-16 (BE or LE) is selected, and there is a UTF-16 BOM,
         * override the selection (like native Notepad).
         */
        if ((BYTE)pTemp[0] == 0xff && (BYTE)pTemp[1] == 0xfe)
            enc = ENCODING_UTF16LE;
        else if ((BYTE)pTemp[0] == 0xfe && (BYTE)pTemp[1] == 0xff)
            enc = ENCODING_UTF16BE;
    }

    switch (enc)
    {
    case ENCODING_UTF16BE:
        byteswap_wide_string((WCHAR*) pTemp, size/sizeof(WCHAR));
        /* Forget whether the file is BE or LE, like native Notepad. */
        enc = ENCODING_UTF16LE;

        /* fall through */

    case ENCODING_UTF16LE:
        textW = (LPWSTR)pTemp;
        lenW  = size/sizeof(WCHAR);
        break;

    default:
        {
            int cp = (enc==ENCODING_UTF8) ? CP_UTF8 : CP_ACP;
            lenW = MultiByteToWideChar(cp, 0, pTemp, size, NULL, 0);
            textW = HeapAlloc(GetProcessHeap(), 0, (lenW+1) * sizeof(WCHAR));
            if (!textW)
            {
                ShowLastError();
                HeapFree(GetProcessHeap(), 0, pTemp);
                return;
            }
            MultiByteToWideChar(cp, 0, pTemp, size, textW, lenW);
            HeapFree(GetProcessHeap(), 0, pTemp);
            break;
        }
    }

    /* Replace '\0's with spaces. Other than creating a custom control that
     * can deal with '\0' characters, it's the best that can be done.
     */
    for (i = 0; i < lenW; i++)
        if (textW[i] == '\0')
            textW[i] = ' ';
    textW[lenW] = '\0';

    if (lenW >= 1 && textW[0] == 0xfeff)
        SetWindowTextW(Globals.hEdit, textW+1);
    else
        SetWindowTextW(Globals.hEdit, textW);

    HeapFree(GetProcessHeap(), 0, textW);

    SendMessageW(Globals.hEdit, EM_SETMODIFY, FALSE, 0);
    SendMessageW(Globals.hEdit, EM_EMPTYUNDOBUFFER, 0, 0);
    SetFocus(Globals.hEdit);
    
    /*  If the file starts with .LOG, add a time/date at the end and set cursor after */
    if (GetWindowTextW(Globals.hEdit, log, ARRAY_SIZE(log)) && !lstrcmpW(log, dotlog))
    {
	static const WCHAR lfW[] = { '\r','\n',0 };
        SendMessageW(Globals.hEdit, EM_SETSEL, GetWindowTextLengthW(Globals.hEdit), -1);
        SendMessageW(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)lfW);
	DIALOG_EditTimeDate();
        SendMessageW(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)lfW);
    }

    SetFileNameAndEncoding(szFileName, enc);
    UpdateWindowCaption();
}

VOID DIALOG_FileNew(VOID)
{
    static const WCHAR empty_strW[] = { 0 };

    /* Close any files and prompt to save changes */
    if (DoCloseFile()) {
        SetWindowTextW(Globals.hEdit, empty_strW);
        SendMessageW(Globals.hEdit, EM_EMPTYUNDOBUFFER, 0, 0);
        SetFocus(Globals.hEdit);
    }
}

/* Used to detect encoding of files selected in Open dialog.
 * Returns ENCODING_AUTO if file can't be read, etc.
 */
static ENCODING detect_encoding_of_file(LPCWSTR szFileName)
{
    DWORD size;
    HANDLE hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
                               OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
        return ENCODING_AUTO;
    size = GetFileSize(hFile, NULL);
    if (size == INVALID_FILE_SIZE)
    {
        CloseHandle(hFile);
        return ENCODING_AUTO;
    }
    else
    {
        DWORD dwNumRead;
        BYTE buffer[MAX_STRING_LEN];
        if (!ReadFile(hFile, buffer, min(size, sizeof(buffer)), &dwNumRead, NULL))
        {
            CloseHandle(hFile);
            return ENCODING_AUTO;
        }
        CloseHandle(hFile);
        return detect_encoding_of_buffer(buffer, dwNumRead);
    }
}

static LPWSTR dialog_print_to_file(HWND hMainWnd)
{
    OPENFILENAMEW ofn;
    static WCHAR file[MAX_PATH] = {'o','u','t','p','u','t','.','p','r','n',0};
    static const WCHAR defExt[] = {'p','r','n',0};

    ZeroMemory(&ofn, sizeof(ofn));

    ofn.lStructSize = sizeof(ofn);
    ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
    ofn.hwndOwner = hMainWnd;
    ofn.lpstrFile = file;
    ofn.nMaxFile = MAX_PATH;
    ofn.lpstrDefExt = defExt;

    if(GetSaveFileNameW(&ofn))
        return file;
    else
        return FALSE;
}
static UINT_PTR CALLBACK OfnHookProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    static HWND hEncCombo;

    switch (uMsg)
    {
    case WM_INITDIALOG:
        {
            ENCODING enc;
            hEncCombo = GetDlgItem(hdlg, IDC_OFN_ENCCOMBO);
            for (enc = MIN_ENCODING; enc <= MAX_ENCODING; enc++)
            {
                WCHAR szEnc[MAX_STRING_LEN];
                load_encoding_name(enc, szEnc, ARRAY_SIZE(szEnc));
                SendMessageW(hEncCombo, CB_ADDSTRING, 0, (LPARAM)szEnc);
            }
            SendMessageW(hEncCombo, CB_SETCURSEL, (WPARAM)Globals.encOfnCombo, 0);
        }
        break;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDC_OFN_ENCCOMBO &&
            HIWORD(wParam) == CBN_SELCHANGE)
        {
            int index = SendMessageW(hEncCombo, CB_GETCURSEL, 0, 0);
            Globals.encOfnCombo = index==CB_ERR ? ENCODING_ANSI : (ENCODING)index;
        }

        break;

    case WM_NOTIFY:
        switch (((OFNOTIFYW*)lParam)->hdr.code)
        {
            case CDN_SELCHANGE:
                if (Globals.bOfnIsOpenDialog)
                {
                    /* Check the start of the selected file for a BOM. */
                    ENCODING enc;
                    WCHAR szFileName[MAX_PATH];
                    SendMessageW(GetParent(hdlg), CDM_GETFILEPATH,
                                 ARRAY_SIZE(szFileName), (LPARAM)szFileName);
                    enc = detect_encoding_of_file(szFileName);
                    if (enc != ENCODING_AUTO)
                    {
                        Globals.encOfnCombo = enc;
                        SendMessageW(hEncCombo, CB_SETCURSEL, (WPARAM)enc, 0);
                    }
                }
                break;

            default:
                break;
        }
        break;

    default:
        break;
    }
    return 0;
}

VOID DIALOG_FileOpen(VOID)
{
    OPENFILENAMEW openfilename;
    WCHAR szPath[MAX_PATH];
    static const WCHAR szDefaultExt[] = { 't','x','t',0 };
    static const WCHAR txt_files[] = { '*','.','t','x','t',0 };

    ZeroMemory(&openfilename, sizeof(openfilename));

    lstrcpyW(szPath, txt_files);

    openfilename.lStructSize       = sizeof(openfilename);
    openfilename.hwndOwner         = Globals.hMainWnd;
    openfilename.hInstance         = Globals.hInstance;
    openfilename.lpstrFilter       = Globals.szFilter;
    openfilename.lpstrFile         = szPath;
    openfilename.nMaxFile          = ARRAY_SIZE(szPath);
    openfilename.Flags = OFN_ENABLETEMPLATE | OFN_ENABLEHOOK | OFN_EXPLORER |
                         OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST |
                         OFN_HIDEREADONLY | OFN_ENABLESIZING;
    openfilename.lpfnHook          = OfnHookProc;
    openfilename.lpTemplateName    = MAKEINTRESOURCEW(IDD_OFN_TEMPLATE);
    openfilename.lpstrDefExt       = szDefaultExt;

    Globals.encOfnCombo = ENCODING_ANSI;
    Globals.bOfnIsOpenDialog = TRUE;

    if (GetOpenFileNameW(&openfilename))
        DoOpenFile(openfilename.lpstrFile, Globals.encOfnCombo);
}

/* Return FALSE to cancel close */
BOOL DIALOG_FileSave(VOID)
{
    if (Globals.szFileName[0] == '\0')
        return DIALOG_FileSaveAs();
    else
    {
        switch (DoSaveFile(Globals.szFileName, Globals.encFile))
        {
            case SAVED_OK:           return TRUE;
            case SHOW_SAVEAS_DIALOG: return DIALOG_FileSaveAs();
            default:                 return FALSE;
        }
    }
}

BOOL DIALOG_FileSaveAs(VOID)
{
    OPENFILENAMEW saveas;
    WCHAR szPath[MAX_PATH];
    static const WCHAR szDefaultExt[] = { 't','x','t',0 };
    static const WCHAR txt_files[] = { '*','.','t','x','t',0 };

    ZeroMemory(&saveas, sizeof(saveas));

    lstrcpyW(szPath, txt_files);

    saveas.lStructSize       = sizeof(OPENFILENAMEW);
    saveas.hwndOwner         = Globals.hMainWnd;
    saveas.hInstance         = Globals.hInstance;
    saveas.lpstrFilter       = Globals.szFilter;
    saveas.lpstrFile         = szPath;
    saveas.nMaxFile          = ARRAY_SIZE(szPath);
    saveas.Flags          = OFN_ENABLETEMPLATE | OFN_ENABLEHOOK | OFN_EXPLORER |
                            OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT |
                            OFN_HIDEREADONLY | OFN_ENABLESIZING;
    saveas.lpfnHook          = OfnHookProc;
    saveas.lpTemplateName    = MAKEINTRESOURCEW(IDD_OFN_TEMPLATE);
    saveas.lpstrDefExt       = szDefaultExt;

    /* Preset encoding to what file was opened/saved last with. */
    Globals.encOfnCombo = Globals.encFile;
    Globals.bOfnIsOpenDialog = FALSE;

retry:
    if (!GetSaveFileNameW(&saveas))
        return FALSE;

    switch (DoSaveFile(szPath, Globals.encOfnCombo))
    {
        case SAVED_OK:
            SetFileNameAndEncoding(szPath, Globals.encOfnCombo);
            UpdateWindowCaption();
            return TRUE;

        case SHOW_SAVEAS_DIALOG:
            goto retry;

        default:
            return FALSE;
    }
}

typedef struct {
    LPWSTR mptr;
    LPWSTR mend;
    LPWSTR lptr;
    DWORD len;
} TEXTINFO, *LPTEXTINFO;

static int notepad_print_header(HDC hdc, RECT *rc, BOOL dopage, BOOL header, int page, LPWSTR text)
{
    SIZE szMetric;

    if (*text)
    {
        /* Write the header or footer */
        GetTextExtentPoint32W(hdc, text, lstrlenW(text), &szMetric);
        if (dopage)
            ExtTextOutW(hdc, (rc->left + rc->right - szMetric.cx) / 2,
                        header ? rc->top : rc->bottom - szMetric.cy,
                        ETO_CLIPPED, rc, text, lstrlenW(text), NULL);
        return 1;
    }
    return 0;
}

static WCHAR *expand_header_vars(WCHAR *pattern, int page)
{
    int length = 0;
    int i;
    BOOL inside = FALSE;
    WCHAR *buffer = NULL;

    for (i = 0; pattern[i]; i++)
    {
        if (inside)
        {
            if (pattern[i] == '&')
                length++;
            else if (pattern[i] == 'p')
                length += 11;
            inside = FALSE;
        }
        else if (pattern[i] == '&')
            inside = TRUE;
        else
            length++;
    }

    buffer = HeapAlloc(GetProcessHeap(), 0, (length + 1) * sizeof(WCHAR));
    if (buffer)
    {
        int j = 0;
        inside = FALSE;
        for (i = 0; pattern[i]; i++)
        {
            if (inside)
            {
                if (pattern[i] == '&')
                    buffer[j++] = '&';
                else if (pattern[i] == 'p')
                {
                    static const WCHAR percent_dW[] = {'%','d',0};
                    j += wnsprintfW(&buffer[j], 11, percent_dW, page);
                }
                inside = FALSE;
            }
            else if (pattern[i] == '&')
                inside = TRUE;
            else
                buffer[j++] = pattern[i];
        }
        buffer[j++] = 0;
    }
    return buffer;
}

static BOOL notepad_print_page(HDC hdc, RECT *rc, BOOL dopage, int page, LPTEXTINFO tInfo)
{
    int b, y;
    TEXTMETRICW tm;
    SIZE szMetrics;
    WCHAR *footer_text = NULL;

    footer_text = expand_header_vars(Globals.szFooter, page);
    if (footer_text == NULL)
        return FALSE;

    if (dopage)
    {
        if (StartPage(hdc) <= 0)
        {
            static const WCHAR failedW[] = { 'S','t','a','r','t','P','a','g','e',' ','f','a','i','l','e','d',0 };
            static const WCHAR errorW[] = { 'P','r','i','n','t',' ','E','r','r','o','r',0 };
            MessageBoxW(Globals.hMainWnd, failedW, errorW, MB_ICONEXCLAMATION);
            HeapFree(GetProcessHeap(), 0, footer_text);
            return FALSE;
        }
    }

    GetTextMetricsW(hdc, &tm);
    y = rc->top + notepad_print_header(hdc, rc, dopage, TRUE, page, Globals.szFileName) * tm.tmHeight;
    b = rc->bottom - 2 * notepad_print_header(hdc, rc, FALSE, FALSE, page, footer_text) * tm.tmHeight;

    do {
        INT m, n;

        if (!tInfo->len)
        {
            /* find the end of the line */
            while (tInfo->mptr < tInfo->mend && *tInfo->mptr != '\n' && *tInfo->mptr != '\r')
            {
                if (*tInfo->mptr == '\t')
                {
                    /* replace tabs with spaces */
                    for (m = 0; m < SPACES_IN_TAB; m++)
                    {
                        if (tInfo->len < PRINT_LEN_MAX)
                            tInfo->lptr[tInfo->len++] = ' ';
                        else if (Globals.bWrapLongLines)
                            break;
                    }
                }
                else if (tInfo->len < PRINT_LEN_MAX)
                    tInfo->lptr[tInfo->len++] = *tInfo->mptr;

                if (tInfo->len >= PRINT_LEN_MAX && Globals.bWrapLongLines)
                     break;

                tInfo->mptr++;
            }
        }

        /* Find out how much we should print if line wrapping is enabled */
        if (Globals.bWrapLongLines)
        {
            GetTextExtentExPointW(hdc, tInfo->lptr, tInfo->len, rc->right - rc->left, &n, NULL, &szMetrics);
            if (n < tInfo->len && tInfo->lptr[n] != ' ')
            {
                m = n;
                /* Don't wrap words unless it's a single word over the entire line */
                while (m  && tInfo->lptr[m] != ' ') m--;
                if (m > 0) n = m + 1;
            }
        }
        else
            n = tInfo->len;

        if (dopage)
            ExtTextOutW(hdc, rc->left, y, ETO_CLIPPED, rc, tInfo->lptr, n, NULL);

        tInfo->len -= n;

        if (tInfo->len)
        {
            memcpy(tInfo->lptr, tInfo->lptr + n, tInfo->len * sizeof(WCHAR));
            y += tm.tmHeight + tm.tmExternalLeading;
        }
        else
        {
            /* find the next line */
            while (tInfo->mptr < tInfo->mend && y < b && (*tInfo->mptr == '\n' || *tInfo->mptr == '\r'))
            {
                if (*tInfo->mptr == '\n')
                    y += tm.tmHeight + tm.tmExternalLeading;
                tInfo->mptr++;
            }
        }
    } while (tInfo->mptr < tInfo->mend && y < b);

    notepad_print_header(hdc, rc, dopage, FALSE, page, footer_text);
    if (dopage)
    {
        EndPage(hdc);
    }
    HeapFree(GetProcessHeap(), 0, footer_text);
    return TRUE;
}

VOID DIALOG_FilePrint(VOID)
{
    DOCINFOW di;
    PRINTDLGW printer;
    int page, dopage, copy;
    LOGFONTW lfFont;
    HFONT hTextFont, old_font = 0;
    DWORD size;
    BOOL ret = FALSE;
    RECT rc;
    LPWSTR pTemp;
    TEXTINFO tInfo;
    WCHAR cTemp[PRINT_LEN_MAX];

    /* Get Current Settings */
    ZeroMemory(&printer, sizeof(printer));
    printer.lStructSize           = sizeof(printer);
    printer.hwndOwner             = Globals.hMainWnd;
    printer.hDevMode              = Globals.hDevMode;
    printer.hDevNames             = Globals.hDevNames;
    printer.hInstance             = Globals.hInstance;

    /* Set some default flags */
    printer.Flags                 = PD_RETURNDC | PD_NOSELECTION;
    printer.nFromPage             = 0;
    printer.nMinPage              = 1;
    /* we really need to calculate number of pages to set nMaxPage and nToPage */
    printer.nToPage               = 0;
    printer.nMaxPage              = -1;
    /* Let commdlg manage copy settings */
    printer.nCopies               = (WORD)PD_USEDEVMODECOPIES;

    if (!PrintDlgW(&printer)) return;

    Globals.hDevMode = printer.hDevMode;
    Globals.hDevNames = printer.hDevNames;

    SetMapMode(printer.hDC, MM_TEXT);

    /* initialize DOCINFO */
    di.cbSize = sizeof(DOCINFOW);
    di.lpszDocName = Globals.szFileTitle;
    di.lpszOutput = NULL;
    di.lpszDatatype = NULL;
    di.fwType = 0; 

    if(printer.Flags & PD_PRINTTOFILE)
    {
        di.lpszOutput = dialog_print_to_file(printer.hwndOwner);
        if(!di.lpszOutput)
            return;
    }

    /* Get the file text */
    size = GetWindowTextLengthW(Globals.hEdit) + 1;
    pTemp = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
    if (!pTemp)
    {
       DeleteDC(printer.hDC);
       ShowLastError();
       return;
    }
    size = GetWindowTextW(Globals.hEdit, pTemp, size);

    if (StartDocW(printer.hDC, &di) > 0)
    {
        /* Get the page margins in pixels. */
        rc.top =    MulDiv(Globals.iMarginTop, GetDeviceCaps(printer.hDC, LOGPIXELSY), 2540) -
                    GetDeviceCaps(printer.hDC, PHYSICALOFFSETY);
        rc.bottom = GetDeviceCaps(printer.hDC, PHYSICALHEIGHT) -
                    MulDiv(Globals.iMarginBottom, GetDeviceCaps(printer.hDC, LOGPIXELSY), 2540);
        rc.left =   MulDiv(Globals.iMarginLeft, GetDeviceCaps(printer.hDC, LOGPIXELSX), 2540) -
                    GetDeviceCaps(printer.hDC, PHYSICALOFFSETX);
        rc.right =  GetDeviceCaps(printer.hDC, PHYSICALWIDTH) -
                    MulDiv(Globals.iMarginRight, GetDeviceCaps(printer.hDC, LOGPIXELSX), 2540);

        /* Create a font for the printer resolution */
        lfFont = Globals.lfFont;
        lfFont.lfHeight = MulDiv(lfFont.lfHeight, GetDeviceCaps(printer.hDC, LOGPIXELSY), get_dpi());
        /* Make the font a bit lighter */
        lfFont.lfWeight -= 100;
        hTextFont = CreateFontIndirectW(&lfFont);
        old_font = SelectObject(printer.hDC, hTextFont);

        for (copy = 1; copy <= printer.nCopies; copy++)
        {
            page = 1;

            tInfo.mptr = pTemp;
            tInfo.mend = pTemp + size;
            tInfo.lptr = cTemp;
            tInfo.len = 0;

            do {
                if (printer.Flags & PD_PAGENUMS)
                {
                    /* a specific range of pages is selected, so
                     * skip pages that are not to be printed
                     */
                    if (page > printer.nToPage)
                        break;
                    else if (page >= printer.nFromPage)
                        dopage = 1;
                    else
                        dopage = 0;
                }
                else
                    dopage = 1;

                ret = notepad_print_page(printer.hDC, &rc, dopage, page, &tInfo);
                page++;
            } while (ret && tInfo.mptr < tInfo.mend);

            if (!ret) break;
        }
        EndDoc(printer.hDC);
        SelectObject(printer.hDC, old_font);
        DeleteObject(hTextFont);
    }
    DeleteDC(printer.hDC);
    HeapFree(GetProcessHeap(), 0, pTemp);
}

VOID DIALOG_FilePrinterSetup(VOID)
{
    PRINTDLGW printer;

    ZeroMemory(&printer, sizeof(printer));
    printer.lStructSize         = sizeof(printer);
    printer.hwndOwner           = Globals.hMainWnd;
    printer.hDevMode            = Globals.hDevMode;
    printer.hDevNames           = Globals.hDevNames;
    printer.hInstance           = Globals.hInstance;
    printer.Flags               = PD_PRINTSETUP;
    printer.nCopies             = 1;

    PrintDlgW(&printer);

    Globals.hDevMode = printer.hDevMode;
    Globals.hDevNames = printer.hDevNames;
}

VOID DIALOG_FileExit(VOID)
{
    PostMessageW(Globals.hMainWnd, WM_CLOSE, 0, 0l);
}

VOID DIALOG_EditUndo(VOID)
{
    SendMessageW(Globals.hEdit, EM_UNDO, 0, 0);
}

VOID DIALOG_EditCut(VOID)
{
    SendMessageW(Globals.hEdit, WM_CUT, 0, 0);
}

VOID DIALOG_EditCopy(VOID)
{
    SendMessageW(Globals.hEdit, WM_COPY, 0, 0);
}

VOID DIALOG_EditPaste(VOID)
{
    SendMessageW(Globals.hEdit, WM_PASTE, 0, 0);
}

VOID DIALOG_EditDelete(VOID)
{
    SendMessageW(Globals.hEdit, WM_CLEAR, 0, 0);
}

VOID DIALOG_EditSelectAll(VOID)
{
    SendMessageW(Globals.hEdit, EM_SETSEL, 0, -1);
}

VOID DIALOG_EditTimeDate(VOID)
{
    SYSTEMTIME   st;
    WCHAR        szDate[MAX_STRING_LEN];
    static const WCHAR spaceW[] = { ' ',0 };

    GetLocalTime(&st);

    GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &st, NULL, szDate, MAX_STRING_LEN);
    SendMessageW(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)szDate);

    SendMessageW(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)spaceW);

    GetDateFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL, szDate, MAX_STRING_LEN);
    SendMessageW(Globals.hEdit, EM_REPLACESEL, TRUE, (LPARAM)szDate);
}

VOID DIALOG_EditWrap(VOID)
{
    BOOL modify = FALSE;
    static const WCHAR editW[] = { 'e','d','i','t',0 };
    DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL |
                    ES_AUTOVSCROLL | ES_MULTILINE;
    RECT rc;
    DWORD size;
    LPWSTR pTemp;

    size = GetWindowTextLengthW(Globals.hEdit) + 1;
    pTemp = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
    if (!pTemp)
    {
        ShowLastError();
        return;
    }
    GetWindowTextW(Globals.hEdit, pTemp, size);
    modify = SendMessageW(Globals.hEdit, EM_GETMODIFY, 0, 0);
    DestroyWindow(Globals.hEdit);
    GetClientRect(Globals.hMainWnd, &rc);
    if( Globals.bWrapLongLines ) dwStyle |= WS_HSCROLL | ES_AUTOHSCROLL;
    Globals.hEdit = CreateWindowExW(WS_EX_CLIENTEDGE, editW, NULL, dwStyle,
                         0, 0, rc.right, rc.bottom, Globals.hMainWnd,
                         NULL, Globals.hInstance, NULL);
    SendMessageW(Globals.hEdit, WM_SETFONT, (WPARAM)Globals.hFont, FALSE);
    SetWindowTextW(Globals.hEdit, pTemp);
    SendMessageW(Globals.hEdit, EM_SETMODIFY, modify, 0);
    SetFocus(Globals.hEdit);
    HeapFree(GetProcessHeap(), 0, pTemp);
    
    Globals.bWrapLongLines = !Globals.bWrapLongLines;
    CheckMenuItem(GetMenu(Globals.hMainWnd), CMD_WRAP,
        MF_BYCOMMAND | (Globals.bWrapLongLines ? MF_CHECKED : MF_UNCHECKED));
}

VOID DIALOG_SelectFont(VOID)
{
    CHOOSEFONTW cf;
    LOGFONTW lf=Globals.lfFont;

    ZeroMemory( &cf, sizeof(cf) );
    cf.lStructSize=sizeof(cf);
    cf.hwndOwner=Globals.hMainWnd;
    cf.lpLogFont=&lf;
    cf.Flags=CF_SCREENFONTS | CF_INITTOLOGFONTSTRUCT | CF_NOVERTFONTS;

    if( ChooseFontW(&cf) )
    {
        HFONT currfont=Globals.hFont;

        Globals.hFont=CreateFontIndirectW( &lf );
        Globals.lfFont=lf;
        SendMessageW( Globals.hEdit, WM_SETFONT, (WPARAM)Globals.hFont, TRUE );
        if( currfont!=NULL )
            DeleteObject( currfont );
    }
}

VOID DIALOG_Search(VOID)
{
        /* Allow only one search/replace dialog to open */
        if(Globals.hFindReplaceDlg != NULL)
        {
            SetActiveWindow(Globals.hFindReplaceDlg);
            return;
        }

        ZeroMemory(&Globals.find, sizeof(Globals.find));
        Globals.find.lStructSize      = sizeof(Globals.find);
        Globals.find.hwndOwner        = Globals.hMainWnd;
        Globals.find.hInstance        = Globals.hInstance;
        Globals.find.lpstrFindWhat    = Globals.szFindText;
        Globals.find.wFindWhatLen     = ARRAY_SIZE(Globals.szFindText);
        Globals.find.Flags            = FR_DOWN|FR_HIDEWHOLEWORD;

        /* We only need to create the modal FindReplace dialog which will */
        /* notify us of incoming events using hMainWnd Window Messages    */

        Globals.hFindReplaceDlg = FindTextW(&Globals.find);
        assert(Globals.hFindReplaceDlg !=0);
}

VOID DIALOG_SearchNext(VOID)
{
    if (Globals.lastFind.lpstrFindWhat == NULL)
        DIALOG_Search();
    else                /* use the last find data */
        NOTEPAD_DoFind(&Globals.lastFind);
}

VOID DIALOG_Replace(VOID)
{
        /* Allow only one search/replace dialog to open */
        if(Globals.hFindReplaceDlg != NULL)
        {
            SetActiveWindow(Globals.hFindReplaceDlg);
            return;
        }

        ZeroMemory(&Globals.find, sizeof(Globals.find));
        Globals.find.lStructSize      = sizeof(Globals.find);
        Globals.find.hwndOwner        = Globals.hMainWnd;
        Globals.find.hInstance        = Globals.hInstance;
        Globals.find.lpstrFindWhat    = Globals.szFindText;
        Globals.find.wFindWhatLen     = ARRAY_SIZE(Globals.szFindText);
        Globals.find.lpstrReplaceWith = Globals.szReplaceText;
        Globals.find.wReplaceWithLen  = ARRAY_SIZE(Globals.szReplaceText);
        Globals.find.Flags            = FR_DOWN|FR_HIDEWHOLEWORD;

        /* We only need to create the modal FindReplace dialog which will */
        /* notify us of incoming events using hMainWnd Window Messages    */

        Globals.hFindReplaceDlg = ReplaceTextW(&Globals.find);
        assert(Globals.hFindReplaceDlg !=0);
}

VOID DIALOG_HelpContents(VOID)
{
    WinHelpW(Globals.hMainWnd, helpfileW, HELP_INDEX, 0);
}

VOID DIALOG_HelpAboutNotepad(VOID)
{
    static const WCHAR notepadW[] = { 'W','i','n','e',' ','N','o','t','e','p','a','d',0 };
    WCHAR szNotepad[MAX_STRING_LEN];
    HICON icon = LoadImageW(Globals.hInstance, MAKEINTRESOURCEW(IDI_NOTEPAD),
                            IMAGE_ICON, 48, 48, LR_SHARED);

    LoadStringW(Globals.hInstance, STRING_NOTEPAD, szNotepad, ARRAY_SIZE(szNotepad));
    ShellAboutW(Globals.hMainWnd, szNotepad, notepadW, icon);
}


/***********************************************************************
 *
 *           DIALOG_FilePageSetup
 */
VOID DIALOG_FilePageSetup(void)
{
    DialogBoxW(Globals.hInstance, MAKEINTRESOURCEW(DIALOG_PAGESETUP),
               Globals.hMainWnd, DIALOG_PAGESETUP_DlgProc);
}


/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *
 *           DIALOG_PAGESETUP_DlgProc
 */

static INT_PTR WINAPI DIALOG_PAGESETUP_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{

   switch (msg)
    {
    case WM_COMMAND:
      switch (wParam)
        {
        case IDOK:
          /* save user input and close dialog */
          GetDlgItemTextW(hDlg, IDC_PAGESETUP_HEADERVALUE, Globals.szHeader, ARRAY_SIZE(Globals.szHeader));
          GetDlgItemTextW(hDlg, IDC_PAGESETUP_FOOTERVALUE, Globals.szFooter, ARRAY_SIZE(Globals.szFooter));

          Globals.iMarginTop = GetDlgItemInt(hDlg, IDC_PAGESETUP_TOPVALUE, NULL, FALSE) * 100;
          Globals.iMarginBottom = GetDlgItemInt(hDlg, IDC_PAGESETUP_BOTTOMVALUE, NULL, FALSE) * 100;
          Globals.iMarginLeft = GetDlgItemInt(hDlg, IDC_PAGESETUP_LEFTVALUE, NULL, FALSE) * 100;
          Globals.iMarginRight = GetDlgItemInt(hDlg, IDC_PAGESETUP_RIGHTVALUE, NULL, FALSE) * 100;
          EndDialog(hDlg, IDOK);
          return TRUE;

        case IDCANCEL:
          /* discard user input and close dialog */
          EndDialog(hDlg, IDCANCEL);
          return TRUE;

        case IDHELP:
        {
          /* FIXME: Bring this to work */
          static const WCHAR sorryW[] = { 'S','o','r','r','y',',',' ','n','o',' ','h','e','l','p',' ','a','v','a','i','l','a','b','l','e',0 };
          static const WCHAR helpW[] = { 'H','e','l','p',0 };
          MessageBoxW(Globals.hMainWnd, sorryW, helpW, MB_ICONEXCLAMATION);
          return TRUE;
        }

	default:
	    break;
        }
      break;

    case WM_INITDIALOG:
       /* fetch last user input prior to display dialog */
       SetDlgItemTextW(hDlg, IDC_PAGESETUP_HEADERVALUE, Globals.szHeader);
       SetDlgItemTextW(hDlg, IDC_PAGESETUP_FOOTERVALUE, Globals.szFooter);
       SetDlgItemInt(hDlg, IDC_PAGESETUP_TOPVALUE, Globals.iMarginTop / 100, FALSE);
       SetDlgItemInt(hDlg, IDC_PAGESETUP_BOTTOMVALUE, Globals.iMarginBottom / 100, FALSE);
       SetDlgItemInt(hDlg, IDC_PAGESETUP_LEFTVALUE, Globals.iMarginLeft / 100, FALSE);
       SetDlgItemInt(hDlg, IDC_PAGESETUP_RIGHTVALUE, Globals.iMarginRight / 100, FALSE);
       break;
    }

  return FALSE;
}
