/*
 *  R : A Computer Language for Statistical Data Analysis
 *  Copyright (C) 1999, 2000  Guido Masarotto
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, a copy is available at
 *  https://www.R-project.org/Licenses/
 */

/* Support for printer
 *  printer newprinter()  - return a printer object - to draw to the
 *                          printer use drawto(...) and the drawXXX
 *                          functions + nextpage(printer)
 *                          printers can be deleted by 'del(printer)'
 */

#include "win-nls.h"
#include "internal.h"
#include "rui.h"


/*
 *  Internal printer deletion function.
 */
static void private_delprinter(printer obj)
{
    HDC h = (HDC) obj->handle;
    if (!obj || !h || (obj->kind != PrinterObject)) return;
    EndPage(h);
    EndDoc(h);
    DeleteDC(h);
    return;
}

/*
 *  Create/return the base printer object.
 */
static object get_printer_base(void)
{
    static object printer_base = NULL;

    if (! printer_base)
	printer_base = new_object(BaseObject, 0, NULL);
    return printer_base;
}

static HDC chooseprinter(void)
{
    PRINTDLG pd;
    HDC dc;
    DWORD rc;
    char cwd[MAX_PATH];

    GetCurrentDirectory(MAX_PATH,cwd);

    pd.lStructSize = sizeof( PRINTDLG );
    pd.hwndOwner = NULL;
    pd.hDevMode = (HANDLE)NULL;
    pd.hDevNames = (HANDLE)NULL;
    pd.Flags = PD_RETURNDC | PD_NOSELECTION | PD_NOPAGENUMS |
	PD_USEDEVMODECOPIES;
    pd.nFromPage = 0;
    pd.nToPage = 0;
    pd.nMinPage = 0;
    pd.nMaxPage = 0;
    pd.nCopies = 1;
    pd.hInstance = (HINSTANCE)NULL;
    pd.lCustData = (LPARAM)0;
    pd.lpfnPrintHook = 0;
    pd.lpfnSetupHook = 0;
    pd.lpPrintTemplateName = (LPCSTR) 0;
    pd.lpSetupTemplateName = (LPCSTR) 0;
    pd.hPrintTemplate = (HGLOBAL)0;
    pd.hSetupTemplate = (HGLOBAL)0;

    dc = PrintDlg( &pd ) ? pd.hDC : NULL;
    SetCurrentDirectory(cwd);
    if (!dc) {
	rc = CommDlgExtendedError(); /* 0 means user cancelled */
	if (rc) R_ShowMessage(G_("Unable to choose printer"));
    }
    return dc;
}


printer newprinter(double width, double height, const char *name)
{
    DOCINFO docinfo;
    printer obj;
    HDC hDC;
    double dd,AL;
    int ww,hh,x0,y0;

    if(strlen(name)) {
	OSVERSIONINFO verinfo;
	verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&verinfo);
	switch(verinfo.dwPlatformId) {
	case VER_PLATFORM_WIN32_NT:
	    hDC = CreateDC("WINSPOOL", name, NULL, NULL);
	default:
	    hDC = CreateDC(NULL, name, NULL, NULL);
	}
    } else hDC = chooseprinter();
    if ( !hDC ) return NULL;
    obj = new_object(PrinterObject, (HANDLE) hDC, get_printer_base());
    if ( !obj ) {
	R_ShowMessage(G_("Insufficient memory for new printer"));
	DeleteDC(hDC);
	return NULL;
    }
    if ((width == 0.0) && (height == 0.0)) {
	ww = GetDeviceCaps(hDC, HORZRES);
	hh = GetDeviceCaps(hDC, VERTRES);
    }
    else {
	if (width < 0.1) width = 0.1;
	if (height < 0.1) height = 0.1;
	dd =  GetDeviceCaps(hDC, HORZSIZE) / width;
	AL = (dd < 1.0) ? dd : 1.0;
	dd = GetDeviceCaps(hDC, VERTSIZE) / height;
	AL = (dd < AL) ? dd : AL;
	ww = (AL * width) * GetDeviceCaps(hDC, LOGPIXELSX) / 25.4;
	hh = (AL * height) * GetDeviceCaps(hDC, LOGPIXELSY) / 25.4;
    }
    x0 = (GetDeviceCaps(hDC, HORZRES) - ww) / 2;
    y0 = (GetDeviceCaps(hDC, VERTRES) - hh) / 2;
    obj->rect = rect(x0, y0, ww, hh);
    obj->depth = GetDeviceCaps(hDC, BITSPIXEL)* GetDeviceCaps(hDC, PLANES);
    obj->die = private_delprinter;
    obj->drawstate = copydrawstate();
    obj->drawstate->dest = obj;

    docinfo.cbSize = sizeof(DOCINFO);	/* set this size... */
    docinfo.lpszDocName = "GraphAppPrintJob";
    docinfo.lpszOutput = 0;		/* no file output... */
    docinfo.lpszDatatype = 0;
    docinfo.fwType = 0;

    if (StartDoc(hDC, &docinfo) <= 0) {
	R_ShowMessage(G_("Unable to start the print job"));
	del(obj);
	return NULL;
    }

    StartPage(hDC);
    return obj;
}


void nextpage(printer p)
{
    if (!p || (p->kind != PrinterObject)) return;
    EndPage((HDC) p->handle);
    StartPage((HDC) p->handle);
}
