/*
 *  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 <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)
{
  WCHAR szCaption[MAX_STRING_LEN];
  WCHAR szNotepad[MAX_STRING_LEN];
  static const WCHAR hyphenW[] = { ' ','-',' ',0 };

  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;

    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;
}
