/*
 * Wordpad implementation - Printing and print preview functions
 *
 * Copyright 2007-2008 by Alexander N. Sørnes <alex@thehandofagony.com>
 *
 * 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 <windows.h>
#include <richedit.h>
#include <commctrl.h>
#include <commdlg.h>

#include "wordpad.h"

typedef struct _previewinfo
{
    int page;
    int pages_shown;
    int saved_pages_shown;
    int *pageEnds, pageCapacity;
    int textlength;
    HDC hdc;
    HDC hdc2;
    RECT window;
    RECT rcPage;
    SIZE bmSize;
    SIZE bmScaledSize;
    SIZE spacing;
    float zoomratio;
    int zoomlevel;
    LPWSTR wszFileName;
} previewinfo, *ppreviewinfo;

static HGLOBAL devMode;
static HGLOBAL devNames;

static RECT margins;
static previewinfo preview;

extern const WCHAR wszPreviewWndClass[];

static const WCHAR var_pagemargin[] = {'P','a','g','e','M','a','r','g','i','n',0};
static const WCHAR var_previewpages[] = {'P','r','e','v','i','e','w','P','a','g','e','s',0};

static LPWSTR get_print_file_filter(HWND hMainWnd)
{
    static WCHAR wszPrintFilter[MAX_STRING_LEN*2+6+4+1];
    const WCHAR files_prn[] = {'*','.','P','R','N',0};
    const WCHAR files_all[] = {'*','.','*','\0'};
    LPWSTR p;
    HINSTANCE hInstance = GetModuleHandleW(0);

    p = wszPrintFilter;
    LoadStringW(hInstance, STRING_PRINTER_FILES_PRN, p, MAX_STRING_LEN);
    p += lstrlenW(p) + 1;
    lstrcpyW(p, files_prn);
    p += lstrlenW(p) + 1;
    LoadStringW(hInstance, STRING_ALL_FILES, p, MAX_STRING_LEN);
    p += lstrlenW(p) + 1;
    lstrcpyW(p, files_all);
    p += lstrlenW(p) + 1;
    *p = 0;

    return wszPrintFilter;
}

void registry_set_pagemargins(HKEY hKey)
{
    RegSetValueExW(hKey, var_pagemargin, 0, REG_BINARY, (LPBYTE)&margins, sizeof(RECT));
}

void registry_read_pagemargins(HKEY hKey)
{
    DWORD size = sizeof(RECT);

    if(!hKey || RegQueryValueExW(hKey, var_pagemargin, 0, NULL, (LPBYTE)&margins,
                     &size) != ERROR_SUCCESS || size != sizeof(RECT))
        SetRect(&margins, 1757, 1417, 1757, 1417);
}

void registry_set_previewpages(HKEY hKey)
{
    RegSetValueExW(hKey, var_previewpages, 0, REG_DWORD,
                   (LPBYTE)&preview.pages_shown, sizeof(DWORD));
}

void registry_read_previewpages(HKEY hKey)
{
    DWORD size = sizeof(DWORD);
    if(!hKey ||
       RegQueryValueExW(hKey, var_previewpages, 0, NULL,
                        (LPBYTE)&preview.pages_shown, &size) != ERROR_SUCCESS ||
       size != sizeof(DWORD))
    {
        preview.pages_shown = 1;
    } else {
        if (preview.pages_shown < 1) preview.pages_shown = 1;
        else if (preview.pages_shown > 2) preview.pages_shown = 2;
    }
}


static void AddTextButton(HWND hRebarWnd, UINT string, UINT command, UINT id)
{
    REBARBANDINFOW rb;
    HINSTANCE hInstance = GetModuleHandleW(0);
    WCHAR text[MAX_STRING_LEN];
    HWND hButton;

    LoadStringW(hInstance, string, text, MAX_STRING_LEN);
    hButton = CreateWindowW(WC_BUTTONW, text,
                            WS_VISIBLE | WS_CHILD, 5, 5, 100, 15,
                            hRebarWnd, ULongToHandle(command), hInstance, NULL);

    rb.cbSize = REBARBANDINFOW_V6_SIZE;
    rb.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_ID;
    rb.fStyle = RBBS_NOGRIPPER | RBBS_VARIABLEHEIGHT;
    rb.hwndChild = hButton;
    rb.cyChild = rb.cyMinChild = 22;
    rb.cx = rb.cxMinChild = 90;
    rb.cxIdeal = 100;
    rb.wID = id;

    SendMessageW(hRebarWnd, RB_INSERTBANDW, -1, (LPARAM)&rb);
}

static HDC make_dc(void)
{
    if(devNames && devMode)
    {
        LPDEVNAMES dn = GlobalLock(devNames);
        LPDEVMODEW dm = GlobalLock(devMode);
        HDC ret;

        ret = CreateDCW((LPWSTR)dn + dn->wDriverOffset,
                         (LPWSTR)dn + dn->wDeviceOffset, 0, dm);

        GlobalUnlock(dn);
        GlobalUnlock(dm);

        return ret;
    } else
    {
        return 0;
    }
}

static LONG twips_to_centmm(int twips)
{
    return MulDiv(twips, CENTMM_PER_INCH, TWIPS_PER_INCH);
}

static LONG centmm_to_twips(int mm)
{
    return MulDiv(mm, TWIPS_PER_INCH, CENTMM_PER_INCH);
}

static LONG twips_to_pixels(int twips, int dpi)
{
    return MulDiv(twips, dpi, TWIPS_PER_INCH);
}

static LONG devunits_to_twips(int units, int dpi)
{
    return MulDiv(units, TWIPS_PER_INCH, dpi);
}


static RECT get_print_rect(HDC hdc)
{
    RECT rc;
    int width, height;

    if(hdc)
    {
        int dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
        int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
        width = devunits_to_twips(GetDeviceCaps(hdc, PHYSICALWIDTH), dpiX);
        height = devunits_to_twips(GetDeviceCaps(hdc, PHYSICALHEIGHT), dpiY);
    } else
    {
        width = centmm_to_twips(18500);
        height = centmm_to_twips(27000);
    }

    SetRect(&rc, margins.left, margins.top, width - margins.right, height - margins.bottom);

    return rc;
}

void target_device(HWND hMainWnd, DWORD wordWrap)
{
    HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR);

    if(wordWrap == ID_WORDWRAP_MARGIN)
    {
        int width = 0;
        LRESULT result;
        HDC hdc = make_dc();
        RECT rc = get_print_rect(hdc);

        width = rc.right - rc.left;
        if(!hdc)
        {
            HDC hMaindc = GetDC(hMainWnd);
            hdc = CreateCompatibleDC(hMaindc);
            ReleaseDC(hMainWnd, hMaindc);
        }
        result = SendMessageW(hEditorWnd, EM_SETTARGETDEVICE, (WPARAM)hdc, width);
        DeleteDC(hdc);
        if (result)
            return;
        /* otherwise EM_SETTARGETDEVICE failed, so fall back on wrapping
         * to window using the NULL DC. */
    }

    if (wordWrap != ID_WORDWRAP_NONE) {
        SendMessageW(hEditorWnd, EM_SETTARGETDEVICE, 0, 0);
    } else {
        SendMessageW(hEditorWnd, EM_SETTARGETDEVICE, 0, 1);
    }

}

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};
    static LPWSTR file_filter;

    if(!file_filter)
        file_filter = get_print_file_filter(hMainWnd);

    ZeroMemory(&ofn, sizeof(ofn));

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

    if(GetSaveFileNameW(&ofn))
        return file;
    else
        return FALSE;
}

static void char_from_pagenum(HWND hEditorWnd, FORMATRANGE *fr, int page)
{
    int i;

    fr->chrg.cpMin = 0;

    for(i = 1; i < page; i++)
    {
        int bottom = fr->rc.bottom;
        fr->chrg.cpMin = SendMessageW(hEditorWnd, EM_FORMATRANGE, FALSE, (LPARAM)fr);
        fr->rc.bottom = bottom;
    }
}

static HWND get_ruler_wnd(HWND hMainWnd)
{
    return GetDlgItem(GetDlgItem(hMainWnd, IDC_REBAR), IDC_RULER);
}

void redraw_ruler(HWND hRulerWnd)
{
    RECT rc;

    GetClientRect(hRulerWnd, &rc);
    InvalidateRect(hRulerWnd, &rc, TRUE);
}

static void update_ruler(HWND hRulerWnd)
{
     SendMessageW(hRulerWnd, WM_USER, 0, 0);
     redraw_ruler(hRulerWnd);
}

static void add_ruler_units(HDC hdcRuler, RECT* drawRect, BOOL NewMetrics, LONG EditLeftmost)
{
    static HDC hdc;

    if(NewMetrics)
    {
        static HBITMAP hBitmap;
        int i, x, y, RulerTextEnd;
        int CmPixels;
        int QuarterCmPixels;
        HFONT hFont;
        WCHAR FontName[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f',0};

        if(hdc)
        {
            DeleteDC(hdc);
            DeleteObject(hBitmap);
        }

        hdc = CreateCompatibleDC(0);

        CmPixels = twips_to_pixels(centmm_to_twips(1000), GetDeviceCaps(hdc, LOGPIXELSX));
        QuarterCmPixels = (int)((float)CmPixels / 4.0);

        hBitmap = CreateCompatibleBitmap(hdc, drawRect->right, drawRect->bottom);
        SelectObject(hdc, hBitmap);
        FillRect(hdc, drawRect, GetStockObject(WHITE_BRUSH));

        hFont = CreateFontW(10, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, FontName);

        SelectObject(hdc, hFont);
        SetBkMode(hdc, TRANSPARENT);
        SetTextAlign(hdc, TA_CENTER);
        y = (int)(((float)drawRect->bottom - (float)drawRect->top) / 2.0) + 1;
        RulerTextEnd = drawRect->right - EditLeftmost + 1;
        for(i = 1, x = EditLeftmost; x < (drawRect->right - EditLeftmost + 1); i ++)
        {
            WCHAR str[3];
            WCHAR format[] = {'%','d',0};
            int x2 = x;

            x2 += QuarterCmPixels;
            if(x2 > RulerTextEnd)
                break;

            MoveToEx(hdc, x2, y, NULL);
            LineTo(hdc, x2, y+2);

            x2 += QuarterCmPixels;
            if(x2 > RulerTextEnd)
                break;

            MoveToEx(hdc, x2, y - 3, NULL);
            LineTo(hdc, x2, y + 3);

            x2 += QuarterCmPixels;
            if(x2 > RulerTextEnd)
                break;

            MoveToEx(hdc, x2, y, NULL);
            LineTo(hdc, x2, y+2);

            x += CmPixels;
            if(x > RulerTextEnd)
                break;

            wsprintfW(str, format, i);
            TextOutW(hdc, x, 5, str, lstrlenW(str));
        }
        DeleteObject(hFont);
    }

    BitBlt(hdcRuler, 0, 0, drawRect->right, drawRect->bottom, hdc, 0, 0, SRCAND);
}

static void paint_ruler(HWND hWnd, LONG EditLeftmost, BOOL NewMetrics)
{
    PAINTSTRUCT ps;
    HDC hdc = BeginPaint(hWnd, &ps);
    HDC hdcPrint = make_dc();
    RECT printRect = get_print_rect(hdcPrint);
    RECT drawRect;
    HBRUSH hBrush = CreateSolidBrush(GetSysColor(COLOR_MENU));

    GetClientRect(hWnd, &drawRect);
    FillRect(hdc, &drawRect, hBrush);

    InflateRect(&drawRect, 0, -3);
    drawRect.left = EditLeftmost;
    drawRect.right = twips_to_pixels(printRect.right - margins.left, GetDeviceCaps(hdc, LOGPIXELSX));
    FillRect(hdc, &drawRect, GetStockObject(WHITE_BRUSH));

    drawRect.top--;
    drawRect.bottom++;
    DrawEdge(hdc, &drawRect, EDGE_SUNKEN, BF_RECT);

    drawRect.left = drawRect.right - 1;
    drawRect.right = twips_to_pixels(printRect.right + margins.right - margins.left, GetDeviceCaps(hdc, LOGPIXELSX));
    DrawEdge(hdc, &drawRect, EDGE_ETCHED, BF_RECT);

    drawRect.left = 0;
    drawRect.top = 0;
    add_ruler_units(hdc, &drawRect, NewMetrics, EditLeftmost);

    SelectObject(hdc, GetStockObject(BLACK_BRUSH));
    DeleteObject(hBrush);
    DeleteDC(hdcPrint);
    EndPaint(hWnd, &ps);
}

LRESULT CALLBACK ruler_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    static WNDPROC pPrevRulerProc;
    static LONG EditLeftmost;
    static BOOL NewMetrics;

    switch(msg)
    {
        case WM_USER:
            if(wParam)
            {
                EditLeftmost = ((POINTL*)wParam)->x;
                pPrevRulerProc = (WNDPROC)lParam;
            }
            NewMetrics = TRUE;
            break;

        case WM_PAINT:
            paint_ruler(hWnd, EditLeftmost, NewMetrics);
            break;

        default:
            return CallWindowProcW(pPrevRulerProc, hWnd, msg, wParam, lParam);
    }

    return 0;
}

static void print(LPPRINTDLGW pd, LPWSTR wszFileName)
{
    FORMATRANGE fr;
    DOCINFOW di;
    HWND hEditorWnd = GetDlgItem(pd->hwndOwner, IDC_EDITOR);
    int printedPages = 0;

    fr.hdc = pd->hDC;
    fr.hdcTarget = pd->hDC;

    fr.rc = get_print_rect(fr.hdc);
    SetRect(&fr.rcPage, 0, 0, fr.rc.right + margins.right, fr.rc.bottom + margins.bottom);

    ZeroMemory(&di, sizeof(di));
    di.cbSize = sizeof(di);
    di.lpszDocName = wszFileName;

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

    if(pd->Flags & PD_SELECTION)
    {
        SendMessageW(hEditorWnd, EM_EXGETSEL, 0, (LPARAM)&fr.chrg);
    } else
    {
        GETTEXTLENGTHEX gt;
        gt.flags = GTL_DEFAULT;
        gt.codepage = 1200;
        fr.chrg.cpMin = 0;
        fr.chrg.cpMax = SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)&gt, 0);

        if(pd->Flags & PD_PAGENUMS)
            char_from_pagenum(hEditorWnd, &fr, pd->nToPage);
    }

    StartDocW(fr.hdc, &di);
    do
    {
        if(StartPage(fr.hdc) <= 0)
            break;

        fr.chrg.cpMin = SendMessageW(hEditorWnd, EM_FORMATRANGE, TRUE, (LPARAM)&fr);

        if(EndPage(fr.hdc) <= 0)
            break;

        printedPages++;
        if((pd->Flags & PD_PAGENUMS) && (printedPages > (pd->nToPage - pd->nFromPage)))
            break;
    }
    while(fr.chrg.cpMin && fr.chrg.cpMin < fr.chrg.cpMax);

    EndDoc(fr.hdc);
    SendMessageW(hEditorWnd, EM_FORMATRANGE, FALSE, 0);
}

void dialog_printsetup(HWND hMainWnd)
{
    PAGESETUPDLGW ps;

    ZeroMemory(&ps, sizeof(ps));
    ps.lStructSize = sizeof(ps);
    ps.hwndOwner = hMainWnd;
    ps.Flags = PSD_INHUNDREDTHSOFMILLIMETERS | PSD_MARGINS;
    SetRect(&ps.rtMargin, twips_to_centmm(margins.left), twips_to_centmm(margins.top),
            twips_to_centmm(margins.right), twips_to_centmm(margins.bottom));
    ps.hDevMode = devMode;
    ps.hDevNames = devNames;

    if(PageSetupDlgW(&ps))
    {
        SetRect(&margins, centmm_to_twips(ps.rtMargin.left), centmm_to_twips(ps.rtMargin.top),
                centmm_to_twips(ps.rtMargin.right), centmm_to_twips(ps.rtMargin.bottom));
        devMode = ps.hDevMode;
        devNames = ps.hDevNames;
        update_ruler(get_ruler_wnd(hMainWnd));
    }
}

void get_default_printer_opts(void)
{
    PRINTDLGW pd;
    ZeroMemory(&pd, sizeof(pd));

    ZeroMemory(&pd, sizeof(pd));
    pd.lStructSize = sizeof(pd);
    pd.Flags = PD_RETURNDC | PD_RETURNDEFAULT;
    pd.hDevMode = devMode;

    PrintDlgW(&pd);

    devMode = pd.hDevMode;
    devNames = pd.hDevNames;
}

void print_quick(HWND hMainWnd, LPWSTR wszFileName)
{
    PRINTDLGW pd;

    ZeroMemory(&pd, sizeof(pd));
    pd.hwndOwner = hMainWnd;
    pd.hDC = make_dc();

    print(&pd, wszFileName);
    DeleteDC(pd.hDC);
}

void dialog_print(HWND hMainWnd, LPWSTR wszFileName)
{
    PRINTDLGW pd;
    HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR);
    int from = 0;
    int to = 0;

    ZeroMemory(&pd, sizeof(pd));
    pd.lStructSize = sizeof(pd);
    pd.hwndOwner = hMainWnd;
    pd.Flags = PD_RETURNDC | PD_USEDEVMODECOPIESANDCOLLATE;
    pd.nMinPage = 1;
    pd.nMaxPage = -1;
    pd.hDevMode = devMode;
    pd.hDevNames = devNames;

    SendMessageW(hEditorWnd, EM_GETSEL, (WPARAM)&from, (LPARAM)&to);
    if(from == to)
        pd.Flags |= PD_NOSELECTION;

    if(PrintDlgW(&pd))
    {
        devMode = pd.hDevMode;
        devNames = pd.hDevNames;
        print(&pd, wszFileName);
        update_ruler(get_ruler_wnd(hMainWnd));
    }
}

static void preview_bar_show(HWND hMainWnd, BOOL show)
{
    HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR);
    int i;

    if(show)
    {
        REBARBANDINFOW rb;
        HWND hStatic;
        UINT num_pages_string = preview.pages_shown > 1 ? STRING_PREVIEW_ONEPAGE :
                                                          STRING_PREVIEW_TWOPAGES;

        AddTextButton(hReBar, STRING_PREVIEW_PRINT, ID_PRINT, BANDID_PREVIEW_BTN1);
        AddTextButton(hReBar, STRING_PREVIEW_NEXTPAGE, ID_PREVIEW_NEXTPAGE, BANDID_PREVIEW_BTN2);
        AddTextButton(hReBar, STRING_PREVIEW_PREVPAGE, ID_PREVIEW_PREVPAGE, BANDID_PREVIEW_BTN3);
        AddTextButton(hReBar, num_pages_string, ID_PREVIEW_NUMPAGES, BANDID_PREVIEW_BTN4);
        AddTextButton(hReBar, STRING_PREVIEW_ZOOMIN, ID_PREVIEW_ZOOMIN, BANDID_PREVIEW_BTN5);
        AddTextButton(hReBar, STRING_PREVIEW_ZOOMOUT, ID_PREVIEW_ZOOMOUT, BANDID_PREVIEW_BTN6);
        AddTextButton(hReBar, STRING_PREVIEW_CLOSE, ID_FILE_EXIT, BANDID_PREVIEW_BTN7);

        hStatic = CreateWindowW(WC_STATICW, NULL,
                                WS_VISIBLE | WS_CHILD, 0, 0, 0, 0,
                                hReBar, NULL, NULL, NULL);

        rb.cbSize = REBARBANDINFOW_V6_SIZE;
        rb.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_STYLE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_ID;
        rb.fStyle = RBBS_NOGRIPPER | RBBS_VARIABLEHEIGHT;
        rb.hwndChild = hStatic;
        rb.cyChild = rb.cyMinChild = 22;
        rb.cx = rb.cxMinChild = 90;
        rb.cxIdeal = 100;
        rb.wID = BANDID_PREVIEW_BUFFER;

        SendMessageW(hReBar, RB_INSERTBANDW, -1, (LPARAM)&rb);
    } else
    {
        for(i = 0; i <= PREVIEW_BUTTONS; i++)
            SendMessageW(hReBar, RB_DELETEBAND, SendMessageW(hReBar, RB_IDTOINDEX, BANDID_PREVIEW_BTN1+i, 0), 0);
    }
}

static const int min_spacing = 10;

static void update_preview_scrollbars(HWND hwndPreview, RECT *window)
{
    SCROLLINFO sbi;
    sbi.cbSize = sizeof(sbi);
    sbi.fMask = SIF_PAGE|SIF_RANGE;
    sbi.nMin = 0;
    if (preview.zoomlevel == 0)
    {
        /* Hide scrollbars when zoomed out. */
        sbi.nMax = 0;
        sbi.nPage = window->right;
        SetScrollInfo(hwndPreview, SB_HORZ, &sbi, TRUE);
        sbi.nPage = window->bottom;
        SetScrollInfo(hwndPreview, SB_VERT, &sbi, TRUE);
    } else {
        sbi.nMax = preview.bmScaledSize.cx * preview.pages_shown +
                   min_spacing * (preview.pages_shown + 1);
        sbi.nPage = window->right;
        SetScrollInfo(hwndPreview, SB_HORZ, &sbi, TRUE);
        /* Change in the horizontal scrollbar visibility affects the
         * client rect, so update the client rect. */
        GetClientRect(hwndPreview, window);
        sbi.nMax = preview.bmScaledSize.cy + min_spacing * 2;
        sbi.nPage = window->bottom;
        SetScrollInfo(hwndPreview, SB_VERT, &sbi, TRUE);
    }
}

static void update_preview_sizes(HWND hwndPreview, BOOL zoomLevelUpdated)
{
    RECT window;

    GetClientRect(hwndPreview, &window);

    /* The zoom ratio isn't updated for partial zoom because of resizing the window. */
    if (zoomLevelUpdated || preview.zoomlevel != 1)
    {
        float ratio, ratioHeight, ratioWidth;
        if (preview.zoomlevel == 2)
        {
            ratio = 1.0;
        } else {
            ratioHeight = (window.bottom - min_spacing * 2) / (float)preview.bmSize.cy;

            ratioWidth = (float)(window.right -
                                 min_spacing * (preview.pages_shown + 1)) /
                         (preview.pages_shown * preview.bmSize.cx);

            if(ratioWidth > ratioHeight)
                ratio = ratioHeight;
            else
                ratio = ratioWidth;

            if (preview.zoomlevel == 1)
                ratio += (1.0 - ratio) / 2;
        }
        preview.zoomratio = ratio;
    }

    preview.bmScaledSize.cx = preview.bmSize.cx * preview.zoomratio;
    preview.bmScaledSize.cy = preview.bmSize.cy * preview.zoomratio;

    preview.spacing.cy = max(min_spacing, (window.bottom - preview.bmScaledSize.cy) / 2);

    preview.spacing.cx = (window.right -
                          preview.bmScaledSize.cx * preview.pages_shown) /
                         (preview.pages_shown + 1);
    if (preview.spacing.cx < min_spacing)
        preview.spacing.cx = min_spacing;

    update_preview_scrollbars(hwndPreview, &window);
}

static void draw_margin_lines(HDC hdc, int x, int y, float ratio)
{
    HPEN hPen, oldPen;
    SIZE dpi;
    RECT page_margin = preview.rcPage;

    dpi.cx = GetDeviceCaps(hdc, LOGPIXELSX);
    dpi.cy = GetDeviceCaps(hdc, LOGPIXELSY);

    SetRect(&page_margin, preview.rcPage.left + margins.left, preview.rcPage.top + margins.top,
            preview.rcPage.right - margins.right, preview.rcPage.bottom - margins.bottom);

    page_margin.left = (int)((float)twips_to_pixels(page_margin.left, dpi.cx) * ratio);
    page_margin.top = (int)((float)twips_to_pixels(page_margin.top, dpi.cy) * ratio);
    page_margin.bottom = (int)((float)twips_to_pixels(page_margin.bottom, dpi.cy) * ratio);
    page_margin.right = (int)((float)twips_to_pixels(page_margin.right, dpi.cx) * ratio);

    OffsetRect(&page_margin, x, y);

    hPen = CreatePen(PS_DOT, 1, RGB(0,0,0));
    oldPen = SelectObject(hdc, hPen);

    MoveToEx(hdc, x, page_margin.top, NULL);
    LineTo(hdc, x + preview.bmScaledSize.cx, page_margin.top);
    MoveToEx(hdc, x, page_margin.bottom, NULL);
    LineTo(hdc, x + preview.bmScaledSize.cx, page_margin.bottom);

    MoveToEx(hdc, page_margin.left, y, NULL);
    LineTo(hdc, page_margin.left, y + preview.bmScaledSize.cy);
    MoveToEx(hdc, page_margin.right, y, NULL);
    LineTo(hdc, page_margin.right, y + preview.bmScaledSize.cy);

    SelectObject(hdc, oldPen);
    DeleteObject(hPen);
}

static BOOL is_last_preview_page(int page)
{
    return preview.pageEnds[page - 1] >= preview.textlength;
}

void init_preview(HWND hMainWnd, LPWSTR wszFileName)
{
    HINSTANCE hInstance = GetModuleHandleW(0);
    preview.page = 1;
    preview.hdc = 0;
    preview.hdc2 = 0;
    preview.wszFileName = wszFileName;
    preview.zoomratio = 0;
    preview.zoomlevel = 0;
    preview_bar_show(hMainWnd, TRUE);

    CreateWindowExW(0, wszPreviewWndClass, NULL,
            WS_VISIBLE | WS_CHILD | WS_VSCROLL | WS_HSCROLL,
            0, 0, 200, 10, hMainWnd, (HMENU)IDC_PREVIEW, hInstance, NULL);
}

void close_preview(HWND hMainWnd)
{
    HWND hwndPreview = GetDlgItem(hMainWnd, IDC_PREVIEW);
    preview.window.right = 0;
    preview.window.bottom = 0;
    preview.page = 0;
    HeapFree(GetProcessHeap(), 0, preview.pageEnds);
    preview.pageEnds = NULL;
    preview.pageCapacity = 0;
    if (preview.zoomlevel > 0)
        preview.pages_shown = preview.saved_pages_shown;
    if(preview.hdc) {
        HBITMAP oldbm = GetCurrentObject(preview.hdc, OBJ_BITMAP);
        DeleteDC(preview.hdc);
        DeleteObject(oldbm);
        preview.hdc = NULL;
    }
    if(preview.hdc2) {
        HBITMAP oldbm = GetCurrentObject(preview.hdc2, OBJ_BITMAP);
        DeleteDC(preview.hdc2);
        DeleteObject(oldbm);
        preview.hdc2 = NULL;
    }

    preview_bar_show(hMainWnd, FALSE);
    DestroyWindow(hwndPreview);
}

BOOL preview_isactive(void)
{
    return preview.page != 0;
}

static void draw_preview(HWND hEditorWnd, FORMATRANGE* lpFr, RECT* paper, int page)
{
    int bottom;

    if (!preview.pageEnds)
    {
        preview.pageCapacity = 32;
        preview.pageEnds = HeapAlloc(GetProcessHeap(), 0,
                                    sizeof(int) * preview.pageCapacity);
        if (!preview.pageEnds) return;
    } else if (page >= preview.pageCapacity) {
        int *new_buffer;
        new_buffer = HeapReAlloc(GetProcessHeap(), 0, preview.pageEnds,
                                 sizeof(int) * preview.pageCapacity * 2);
        if (!new_buffer) return;
        preview.pageCapacity *= 2;
        preview.pageEnds = new_buffer;
    }

    FillRect(lpFr->hdc, paper, GetStockObject(WHITE_BRUSH));
    if (page > 1 && is_last_preview_page(page - 1)) return;
    lpFr->chrg.cpMin = page <= 1 ? 0 : preview.pageEnds[page-2];
    bottom = lpFr->rc.bottom;
    preview.pageEnds[page-1] = SendMessageW(hEditorWnd, EM_FORMATRANGE, TRUE, (LPARAM)lpFr);

    /* EM_FORMATRANGE sets fr.rc.bottom to indicate the area printed in,
     * but we want to keep the original for drawing margins */
    lpFr->rc.bottom = bottom;
    SendMessageW(hEditorWnd, EM_FORMATRANGE, FALSE, 0);
}

static void update_preview_buttons(HWND hMainWnd)
{
    HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR);
    EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_PREVPAGE), preview.page > 1);
    EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_NEXTPAGE),
                 !is_last_preview_page(preview.page) &&
                 !is_last_preview_page(preview.page + preview.pages_shown - 1));
    EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_NUMPAGES),
                 preview.pages_shown > 1 ||
                 (!is_last_preview_page(1) && preview.zoomlevel == 0));
    EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_ZOOMIN), preview.zoomlevel < 2);
    EnableWindow(GetDlgItem(hReBar, ID_PREVIEW_ZOOMOUT), preview.zoomlevel > 0);
}

static LRESULT print_preview(HWND hwndPreview)
{
    HPEN hPen, oldPen;
    HDC hdc;
    HRGN back_rgn, excl_rgn;
    RECT window, background;
    PAINTSTRUCT ps;
    int x, y;

    hdc = BeginPaint(hwndPreview, &ps);
    GetClientRect(hwndPreview, &window);
    back_rgn = CreateRectRgnIndirect(&window);

    x = preview.spacing.cx - GetScrollPos(hwndPreview, SB_HORZ);
    y = preview.spacing.cy - GetScrollPos(hwndPreview, SB_VERT);

    /* draw page outlines */
    hPen = CreatePen(PS_SOLID|PS_INSIDEFRAME, 2, RGB(0,0,0));
    oldPen = SelectObject(hdc, hPen);
    SetRect(&background, x - 2, y - 2, x + preview.bmScaledSize.cx + 2,
            y + preview.bmScaledSize.cy + 2);
    Rectangle(hdc, background.left, background.top,
              background.right, background.bottom);
    excl_rgn = CreateRectRgnIndirect(&background);
    CombineRgn(back_rgn, back_rgn, excl_rgn, RGN_DIFF);
    if(preview.pages_shown > 1)
    {
        background.left += preview.bmScaledSize.cx + preview.spacing.cx;
        background.right += preview.bmScaledSize.cx + preview.spacing.cx;
        Rectangle(hdc, background.left, background.top,
                  background.right, background.bottom);
        SetRectRgn(excl_rgn, background.left, background.top,
                   background.right, background.bottom);
        CombineRgn(back_rgn, back_rgn, excl_rgn, RGN_DIFF);
    }
    SelectObject(hdc, oldPen);
    DeleteObject(hPen);
    FillRgn(hdc, back_rgn, GetStockObject(GRAY_BRUSH));
    DeleteObject(excl_rgn);
    DeleteObject(back_rgn);

    StretchBlt(hdc, x, y, preview.bmScaledSize.cx, preview.bmScaledSize.cy,
               preview.hdc, 0, 0, preview.bmSize.cx, preview.bmSize.cy, SRCCOPY);

    draw_margin_lines(hdc, x, y, preview.zoomratio);

    if(preview.pages_shown > 1)
    {
        if (!is_last_preview_page(preview.page)) {
            x += preview.spacing.cx + preview.bmScaledSize.cx;
            StretchBlt(hdc, x, y,
                       preview.bmScaledSize.cx, preview.bmScaledSize.cy,
                       preview.hdc2, 0, 0,
                       preview.bmSize.cx, preview.bmSize.cy, SRCCOPY);

            draw_margin_lines(hdc, x, y, preview.zoomratio);
        } else {
            InflateRect(&background, -2, -2);
            FillRect(hdc, &background, GetStockObject(WHITE_BRUSH));
        }
    }

    preview.window = window;

    EndPaint(hwndPreview, &ps);

    return 0;
}

static void update_preview_statusbar(HWND hMainWnd)
{
    HWND hStatusbar = GetDlgItem(hMainWnd, IDC_STATUSBAR);
    HINSTANCE hInst = GetModuleHandleW(0);
    WCHAR *p;
    WCHAR wstr[MAX_STRING_LEN];

    p = wstr;
    if (preview.pages_shown < 2 || is_last_preview_page(preview.page))
    {
        static const WCHAR fmt[] = {' ','%','d','\0'};
        p += LoadStringW(hInst, STRING_PREVIEW_PAGE, wstr, MAX_STRING_LEN);
        wsprintfW(p, fmt, preview.page);
    } else {
        static const WCHAR fmt[] = {' ','%','d','-','%','d','\0'};
        p += LoadStringW(hInst, STRING_PREVIEW_PAGES, wstr, MAX_STRING_LEN);
        wsprintfW(p, fmt, preview.page, preview.page + 1);
    }
    SetWindowTextW(hStatusbar, wstr);
}

/* Update for page changes. */
static void update_preview(HWND hMainWnd)
{
    RECT paper;
    HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR);
    HWND hwndPreview = GetDlgItem(hMainWnd, IDC_PREVIEW);
    HBITMAP hBitmapCapture;
    FORMATRANGE fr;
    HDC hdc = GetDC(hwndPreview);

    fr.hdcTarget = make_dc();
    fr.rc = fr.rcPage = preview.rcPage;
    fr.rc.left += margins.left;
    fr.rc.top += margins.top;
    fr.rc.bottom -= margins.bottom;
    fr.rc.right -= margins.right;

    fr.chrg.cpMin = 0;
    fr.chrg.cpMax = preview.textlength;

    SetRect(&paper, 0, 0, preview.bmSize.cx, preview.bmSize.cy);

    if (!preview.hdc) {
        preview.hdc = CreateCompatibleDC(hdc);
        hBitmapCapture = CreateCompatibleBitmap(hdc, preview.bmSize.cx, preview.bmSize.cy);
        SelectObject(preview.hdc, hBitmapCapture);
    }

    fr.hdc = preview.hdc;
    draw_preview(hEditorWnd, &fr, &paper, preview.page);

    if(preview.pages_shown > 1)
    {
        if (!preview.hdc2)
        {
            preview.hdc2 = CreateCompatibleDC(hdc);
            hBitmapCapture = CreateCompatibleBitmap(hdc,
                                                    preview.bmSize.cx,
                                                    preview.bmSize.cy);
            SelectObject(preview.hdc2, hBitmapCapture);
        }

        fr.hdc = preview.hdc2;
        draw_preview(hEditorWnd, &fr, &fr.rcPage, preview.page + 1);
    }
    DeleteDC(fr.hdcTarget);
    ReleaseDC(hwndPreview, hdc);

    InvalidateRect(hwndPreview, NULL, FALSE);
    update_preview_buttons(hMainWnd);
    update_preview_statusbar(hMainWnd);
}

static void toggle_num_pages(HWND hMainWnd)
{
    HWND hReBar = GetDlgItem(hMainWnd, IDC_REBAR);
    WCHAR name[MAX_STRING_LEN];
    HINSTANCE hInst = GetModuleHandleW(0);
    int nPreviewPages;

    preview.pages_shown = preview.pages_shown > 1 ? 1 : 2;

    nPreviewPages = preview.zoomlevel > 0 ? preview.saved_pages_shown :
                                            preview.pages_shown;

    LoadStringW(hInst, nPreviewPages > 1 ? STRING_PREVIEW_ONEPAGE :
                                           STRING_PREVIEW_TWOPAGES,
                name, MAX_STRING_LEN);

    SetWindowTextW(GetDlgItem(hReBar, ID_PREVIEW_NUMPAGES), name);
    update_preview_sizes(GetDlgItem(hMainWnd, IDC_PREVIEW), TRUE);
    update_preview(hMainWnd);
}

/* Returns the page shown that the point is in (1 or 2) or 0 if the point
 * isn't inside either page */
static int preview_page_hittest(POINT pt)
{
    RECT rc;
    rc.left = preview.spacing.cx;
    rc.right = rc.left + preview.bmScaledSize.cx;
    rc.top = preview.spacing.cy;
    rc.bottom = rc.top + preview.bmScaledSize.cy;
    if (PtInRect(&rc, pt))
        return 1;

    if (preview.pages_shown <= 1)
        return 0;

    rc.left += preview.bmScaledSize.cx + preview.spacing.cx;
    rc.right += preview.bmScaledSize.cx + preview.spacing.cx;
    if (PtInRect(&rc, pt))
        return is_last_preview_page(preview.page) ? 1 : 2;

    return 0;
}

LRESULT CALLBACK preview_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
        case WM_CREATE:
        {
            HWND hMainWnd = GetParent(hWnd);
            HWND hEditorWnd = GetDlgItem(hMainWnd, IDC_EDITOR);
            FORMATRANGE fr;
            GETTEXTLENGTHEX gt = {GTL_DEFAULT, 1200};
            HDC hdc = GetDC(hWnd);
            HDC hdcTarget = make_dc();

            fr.rc = preview.rcPage = get_print_rect(hdcTarget);
            preview.rcPage.bottom += margins.bottom;
            preview.rcPage.right += margins.right;
            preview.rcPage.top = preview.rcPage.left = 0;
            fr.rcPage = preview.rcPage;

            preview.bmSize.cx = twips_to_pixels(preview.rcPage.right, GetDeviceCaps(hdc, LOGPIXELSX));
            preview.bmSize.cy = twips_to_pixels(preview.rcPage.bottom, GetDeviceCaps(hdc, LOGPIXELSY));

            preview.textlength = SendMessageW(hEditorWnd, EM_GETTEXTLENGTHEX, (WPARAM)&gt, 0);

            fr.hdc = CreateCompatibleDC(hdc);
            fr.hdcTarget = hdcTarget;
            fr.chrg.cpMin = 0;
            fr.chrg.cpMax = preview.textlength;
            DeleteDC(fr.hdc);
            DeleteDC(hdcTarget);
            ReleaseDC(hWnd, hdc);

            update_preview_sizes(hWnd, TRUE);
            update_preview(hMainWnd);
            break;
        }

        case WM_PAINT:
            return print_preview(hWnd);

        case WM_SIZE:
        {
            update_preview_sizes(hWnd, FALSE);
            InvalidateRect(hWnd, NULL, FALSE);
            break;
        }

        case WM_VSCROLL:
        case WM_HSCROLL:
        {
            SCROLLINFO si;
            RECT rc;
            int nBar = (msg == WM_VSCROLL) ? SB_VERT : SB_HORZ;
            int origPos;

            GetClientRect(hWnd, &rc);
            si.cbSize = sizeof(si);
            si.fMask = SIF_ALL;
            GetScrollInfo(hWnd, nBar, &si);
            origPos = si.nPos;
            switch(LOWORD(wParam))
            {
                case SB_TOP: /* == SB_LEFT */
                    si.nPos = si.nMin;
                    break;
                case SB_BOTTOM: /* == SB_RIGHT */
                    si.nPos = si.nMax;
                    break;
                case SB_LINEUP: /* == SB_LINELEFT */
                    si.nPos -= si.nPage / 10;
                    break;
                case SB_LINEDOWN: /* == SB_LINERIGHT */
                    si.nPos += si.nPage / 10;
                    break;
                case SB_PAGEUP: /* == SB_PAGELEFT */
                    si.nPos -= si.nPage;
                    break;
                case SB_PAGEDOWN: /* SB_PAGERIGHT */
                    si.nPos += si.nPage;
                    break;
                case SB_THUMBTRACK:
                    si.nPos = si.nTrackPos;
                    break;
            }
            si.fMask = SIF_POS;
            SetScrollInfo(hWnd, nBar, &si, TRUE);
            GetScrollInfo(hWnd, nBar, &si);
            if (si.nPos != origPos)
            {
                int amount = origPos - si.nPos;
                if (msg == WM_VSCROLL)
                    ScrollWindow(hWnd, 0, amount, NULL, NULL);
                else
                    ScrollWindow(hWnd, amount, 0, NULL, NULL);
            }
            return 0;
        }

        case WM_SETCURSOR:
        {
            POINT pt;
            RECT rc;
            int bHittest = 0;
            DWORD messagePos = GetMessagePos();
            pt.x = (short)LOWORD(messagePos);
            pt.y = (short)HIWORD(messagePos);
            ScreenToClient(hWnd, &pt);

            GetClientRect(hWnd, &rc);
            if (PtInRect(&rc, pt))
            {
                pt.x += GetScrollPos(hWnd, SB_HORZ);
                pt.y += GetScrollPos(hWnd, SB_VERT);
                bHittest = preview_page_hittest(pt);
            }

            if (bHittest)
                SetCursor(LoadCursorW(GetModuleHandleW(0),
                                      MAKEINTRESOURCEW(IDC_ZOOM)));
            else
                SetCursor(LoadCursorW(NULL, (WCHAR*)IDC_ARROW));

            return TRUE;
        }

        case WM_LBUTTONDOWN:
        {
            int page;
            POINT pt;
            pt.x = (short)LOWORD(lParam) + GetScrollPos(hWnd, SB_HORZ);
            pt.y = (short)HIWORD(lParam) + GetScrollPos(hWnd, SB_VERT);
            if ((page = preview_page_hittest(pt)) > 0)
            {
                HWND hMainWnd = GetParent(hWnd);

                /* Convert point from client coordinate to unzoomed page
                 * coordinate. */
                pt.x -= preview.spacing.cx;
                if (page > 1)
                    pt.x -= preview.bmScaledSize.cx + preview.spacing.cx;
                pt.y -= preview.spacing.cy;
                pt.x /= preview.zoomratio;
                pt.y /= preview.zoomratio;

                if (preview.zoomlevel == 0)
                    preview.saved_pages_shown = preview.pages_shown;
                preview.zoomlevel = (preview.zoomlevel + 1) % 3;
                preview.zoomratio = 0;
                if (preview.zoomlevel == 0 && preview.saved_pages_shown > 1)
                {
                    toggle_num_pages(hMainWnd);
                } else if (preview.pages_shown > 1) {
                    if (page >= 2) preview.page++;
                    toggle_num_pages(hMainWnd);
                } else {
                    update_preview_sizes(hWnd, TRUE);
                    InvalidateRect(hWnd, NULL, FALSE);
                    update_preview_buttons(hMainWnd);
                }

                if (preview.zoomlevel > 0) {
                    SCROLLINFO si;
                    /* Convert the coordinate back to client coordinate. */
                    pt.x *= preview.zoomratio;
                    pt.y *= preview.zoomratio;
                    pt.x += preview.spacing.cx;
                    pt.y += preview.spacing.cy;
                    /* Scroll to center view at that point on the page */
                    si.cbSize = sizeof(si);
                    si.fMask = SIF_PAGE;
                    GetScrollInfo(hWnd, SB_HORZ, &si);
                    pt.x -= si.nPage / 2;
                    SetScrollPos(hWnd, SB_HORZ, pt.x, TRUE);
                    GetScrollInfo(hWnd, SB_VERT, &si);
                    pt.y -= si.nPage / 2;
                    SetScrollPos(hWnd, SB_VERT, pt.y, TRUE);
                }
            }
        }

        default:
            return DefWindowProcW(hWnd, msg, wParam, lParam);
    }

    return 0;
}

LRESULT preview_command(HWND hWnd, WPARAM wParam)
{
    switch(LOWORD(wParam))
    {
        case ID_FILE_EXIT:
            PostMessageW(hWnd, WM_CLOSE, 0, 0);
            break;

        case ID_PREVIEW_NEXTPAGE:
        case ID_PREVIEW_PREVPAGE:
        {
            if(LOWORD(wParam) == ID_PREVIEW_NEXTPAGE)
                preview.page++;
            else
                preview.page--;

            update_preview(hWnd);
        }
        break;

        case ID_PREVIEW_NUMPAGES:
            toggle_num_pages(hWnd);
            break;

        case ID_PREVIEW_ZOOMIN:
            if (preview.zoomlevel < 2)
            {
                if (preview.zoomlevel == 0)
                    preview.saved_pages_shown = preview.pages_shown;
                preview.zoomlevel++;
                preview.zoomratio = 0;
                if (preview.pages_shown > 1)
                {
                    /* Forced switch to one page when zooming in. */
                    toggle_num_pages(hWnd);
                } else {
                    HWND hwndPreview = GetDlgItem(hWnd, IDC_PREVIEW);
                    update_preview_sizes(hwndPreview, TRUE);
                    InvalidateRect(hwndPreview, NULL, FALSE);
                    update_preview_buttons(hWnd);
                }
            }
            break;

        case ID_PREVIEW_ZOOMOUT:
            if (preview.zoomlevel > 0)
            {
                HWND hwndPreview = GetDlgItem(hWnd, IDC_PREVIEW);
                preview.zoomlevel--;
                preview.zoomratio = 0;
                if (preview.zoomlevel == 0 && preview.saved_pages_shown > 1) {
                    toggle_num_pages(hWnd);
                } else {
                    update_preview_sizes(hwndPreview, TRUE);
                    InvalidateRect(hwndPreview, NULL, FALSE);
                    update_preview_buttons(hWnd);
                }
            }
            break;

        case ID_PRINT:
            dialog_print(hWnd, preview.wszFileName);
            SendMessageW(hWnd, WM_CLOSE, 0, 0);
            break;
    }

    return 0;
}
