/*
 *  R : A Computer Language for Statistical Data Analysis
 *  Copyright (C) 1999-2001  Guido Masarotto and Brian Ripley
 *
 *  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/
 */

/*
 *  metafile newmetafile(char *name,rect r)
 *     return a metafile object of 'nominal' size (r.width)x(r.height)
 *     in 0.01mm. Use drawto(...)/drawXXX/gdrawXXX to draw to the
 *     metafile. If "name"=="" metafile is in memory.
 *
 *  del(metafile)  finalizes/closes the metafile. Closed in memory
 *     metafile are saved to the clipboard.
 *
*/

#define ENABLE_NLS 1
#include "win-nls.h"
#include "internal.h"
#include "rui.h"

/*
 *  Internal metafile deletion function.
 */

static void private_delmetafile(metafile obj)
{
    HENHMETAFILE hm;

    if (!obj || (obj->kind != MetafileObject)) return;
    hm = (HENHMETAFILE) CloseEnhMetaFile((HDC) obj->handle);
    if (strlen(GA_gettext(obj))) { /* real file*/
	DeleteEnhMetaFile(hm);
	return;
    }
    if (OpenClipboard(NULL) && EmptyClipboard() && /* try to save to the*/
	SetClipboardData(CF_ENHMETAFILE, hm) &&     /*clipboard */
	CloseClipboard())
	return;
    else {
	R_ShowMessage(G_("Unable to save metafile to the clipboard"));
	DeleteEnhMetaFile(hm);
	return;
    }
}

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

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

/* width and height are in mm */
metafile newmetafile(const char *name, double width, double height,
                     double xpinch, double ypinch)
{
    metafile obj;
    HDC hDC;
    RECT wr;
    static double cppix=-1, ppix, cppiy, ppiy;

    /* If user has overridden, do not query Windows for device info */
    if (xpinch > 0.0 && ypinch > 0.0) {
        cppix = xpinch;
        ppix = 100 * xpinch;
        cppiy = ypinch;
        ppiy = 100 * ypinch;
    } else {
        /*
         * In theory, (cppix=ppix) and (cppiy=ppiy). However, we
         * use the ratio to adjust the 'reference dimension'
         * in case.... ("Importing graph in MsWord" thread)
         */
        if (cppix < 0) {
            cppix = 25.40 * devicewidth(NULL) / devicewidthmm(NULL);
            ppix  = 100 * devicepixelsx(NULL);
            cppiy = 25.40 * deviceheight(NULL) / deviceheightmm(NULL);
            ppiy = 100 * devicepixelsy(NULL);
        }
    }
    /* This is all very peculiar. We would really like to create
       a metafile measured in some sensible units, but it seems
       we get it in units of 0.01mm *on the current screen* with
       horizontal and vertical resolution set for that screen.
       And of course Windows is famous for getting screen sizes wrong.
    */

    wr.left = 0;
    wr.top =  0 ;
    wr.right =  (ppix * width) / cppix ;
    wr.bottom = (ppiy * height) / cppiy ;

    /* Here the size is in 0.01mm units */
    hDC = CreateEnhMetaFile(NULL, strlen(name) ? name : NULL, &wr,
			    "GraphApp\0\0");
    if ( !hDC ) {
	R_ShowMessage(G_("Unable to create metafile"));
	return NULL;
    }
    obj = new_object(MetafileObject, (HANDLE) hDC, get_metafile_base());
    if ( !obj ) {
	R_ShowMessage(G_("Insufficient memory to create metafile"));
	DeleteEnhMetaFile(CloseEnhMetaFile(hDC));
	return NULL;
    }
    /* In looks like Windows rounds up the width and height, so we
       do too.  1 out is common, but 2 out has been seen.
       This is needed to get complete painting of the background.
    */
    obj->rect = rect(0, 0, 2+(ppix * width)/2540, 2+(ppiy * height)/2540);
    obj->depth = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
    obj->die = private_delmetafile;
    obj->drawstate = copydrawstate();
    obj->drawstate->dest = obj;
    settext(obj, name ? name : "");
    return obj;
}
