/*
 *  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(_("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(_("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(_("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);
}
