/*
 *  R : A Computer Language for Statistical Data Analysis
 *  Copyright (C) 2001-12   The R Core Team.
 *
 *  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/
 */

/* The beginning of code which represents an R base graphics system
 * separate from an R graphics engine (separate from R devices)
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <Defn.h>
#include <Graphics.h>
#include <GraphicsBase.h>

#ifdef ENABLE_NLS
#include <libintl.h>
#undef _
#define _(String) dgettext ("graphics", String)
#else
#define _(String) (String)
#endif


static R_INLINE GPar* dpSavedptr(pGEDevDesc dd) {
    if (baseRegisterIndex == -1)
	error(_("no base graphics system is registered"));
    baseSystemState *bss = dd->gesd[baseRegisterIndex]->systemSpecific;
    return &(bss->dpSaved);
}

static void restoredpSaved(pGEDevDesc dd)
{
    /* NOTE that not all params should be restored before playing */
    /* the display list (e.g., don't restore the device size) */

    /* This could probably now just do a memcpy */
    int i, j, nr, nc;

    dpptr(dd)->state = dpSavedptr(dd)->state;
    /* does not restore 'valid' */
    dpptr(dd)->adj = dpSavedptr(dd)->adj;
    dpptr(dd)->ann = dpSavedptr(dd)->ann;
    dpptr(dd)->bg = dpSavedptr(dd)->bg;
    dpptr(dd)->bty = dpSavedptr(dd)->bty;
    dpptr(dd)->cex = dpSavedptr(dd)->cex;
    gpptr(dd)->lheight = dpSavedptr(dd)->lheight;
    dpptr(dd)->col = dpSavedptr(dd)->col;
    dpptr(dd)->crt = dpSavedptr(dd)->crt;
    dpptr(dd)->err = dpSavedptr(dd)->err;
    dpptr(dd)->fg = dpSavedptr(dd)->fg;
    strncpy(dpptr(dd)->family, dpSavedptr(dd)->family, 201);
    dpptr(dd)->font = dpSavedptr(dd)->font;
    dpptr(dd)->gamma = dpSavedptr(dd)->gamma;
    dpptr(dd)->lab[0] = dpSavedptr(dd)->lab[0];
    dpptr(dd)->lab[1] = dpSavedptr(dd)->lab[1];
    dpptr(dd)->lab[2] = dpSavedptr(dd)->lab[2];
    dpptr(dd)->las = dpSavedptr(dd)->las;
    dpptr(dd)->lty = dpSavedptr(dd)->lty;
    dpptr(dd)->lwd = dpSavedptr(dd)->lwd;
    dpptr(dd)->lend = dpSavedptr(dd)->lend;
    dpptr(dd)->ljoin = dpSavedptr(dd)->ljoin;
    dpptr(dd)->lmitre = dpSavedptr(dd)->lmitre;
    dpptr(dd)->mgp[0] = dpSavedptr(dd)->mgp[0];
    dpptr(dd)->mgp[1] = dpSavedptr(dd)->mgp[1];
    dpptr(dd)->mgp[2] = dpSavedptr(dd)->mgp[2];
    dpptr(dd)->mkh = dpSavedptr(dd)->mkh;
    dpptr(dd)->pch = dpSavedptr(dd)->pch;
    dpptr(dd)->ps = dpSavedptr(dd)->ps; /*was commented out --why? Well, it never changes */
    dpptr(dd)->smo = dpSavedptr(dd)->smo;
    dpptr(dd)->srt = dpSavedptr(dd)->srt;
    dpptr(dd)->tck = dpSavedptr(dd)->tck;
    dpptr(dd)->tcl = dpSavedptr(dd)->tcl;
    dpptr(dd)->xaxp[0] = dpSavedptr(dd)->xaxp[0];
    dpptr(dd)->xaxp[1] = dpSavedptr(dd)->xaxp[1];
    dpptr(dd)->xaxp[2] = dpSavedptr(dd)->xaxp[2];
    dpptr(dd)->xaxs = dpSavedptr(dd)->xaxs;
    dpptr(dd)->xaxt = dpSavedptr(dd)->xaxt;
    dpptr(dd)->xpd = dpSavedptr(dd)->xpd;
    /* not oldxpd, which is a gpptr concept */
    dpptr(dd)->xlog = dpSavedptr(dd)->xlog;
    dpptr(dd)->yaxp[0] = dpSavedptr(dd)->yaxp[0];
    dpptr(dd)->yaxp[1] = dpSavedptr(dd)->yaxp[1];
    dpptr(dd)->yaxp[2] = dpSavedptr(dd)->yaxp[2];
    dpptr(dd)->yaxs = dpSavedptr(dd)->yaxs;
    dpptr(dd)->yaxt = dpSavedptr(dd)->yaxt;
    dpptr(dd)->ylog = dpSavedptr(dd)->ylog;
    dpptr(dd)->cexbase = dpSavedptr(dd)->cexbase;
    dpptr(dd)->cexmain = dpSavedptr(dd)->cexmain;
    dpptr(dd)->cexlab = dpSavedptr(dd)->cexlab;
    dpptr(dd)->cexsub = dpSavedptr(dd)->cexsub;
    dpptr(dd)->cexaxis = dpSavedptr(dd)->cexaxis;
    dpptr(dd)->fontmain = dpSavedptr(dd)->fontmain;
    dpptr(dd)->fontlab = dpSavedptr(dd)->fontlab;
    dpptr(dd)->fontsub = dpSavedptr(dd)->fontsub;
    dpptr(dd)->fontaxis = dpSavedptr(dd)->fontaxis;
    dpptr(dd)->colmain = dpSavedptr(dd)->colmain;
    dpptr(dd)->collab = dpSavedptr(dd)->collab;
    dpptr(dd)->colsub = dpSavedptr(dd)->colsub;
    dpptr(dd)->colaxis = dpSavedptr(dd)->colaxis;

    /* must restore layout parameters;	the different graphics */
    /* regions and coordinate transformations will be recalculated */
    /* but they need all of the layout information restored for this */
    /* to happen correctly */

    dpptr(dd)->devmode = dpSavedptr(dd)->devmode;
    dpptr(dd)->fig[0] = dpSavedptr(dd)->fig[0];
    dpptr(dd)->fig[1] = dpSavedptr(dd)->fig[1];
    dpptr(dd)->fig[2] = dpSavedptr(dd)->fig[2];
    dpptr(dd)->fig[3] = dpSavedptr(dd)->fig[3];
    dpptr(dd)->fin[0] = dpSavedptr(dd)->fin[0];
    dpptr(dd)->fin[1] = dpSavedptr(dd)->fin[1];
    dpptr(dd)->fUnits = dpSavedptr(dd)->fUnits;
    dpptr(dd)->defaultFigure = dpSavedptr(dd)->defaultFigure;
    dpptr(dd)->mar[0] = dpSavedptr(dd)->mar[0];
    dpptr(dd)->mar[1] = dpSavedptr(dd)->mar[1];
    dpptr(dd)->mar[2] = dpSavedptr(dd)->mar[2];
    dpptr(dd)->mar[3] = dpSavedptr(dd)->mar[3];
    dpptr(dd)->mai[0] = dpSavedptr(dd)->mai[0];
    dpptr(dd)->mai[1] = dpSavedptr(dd)->mai[1];
    dpptr(dd)->mai[2] = dpSavedptr(dd)->mai[2];
    dpptr(dd)->mai[3] = dpSavedptr(dd)->mai[3];
    dpptr(dd)->mUnits = dpSavedptr(dd)->mUnits;
    dpptr(dd)->mex = dpSavedptr(dd)->mex;
    nr = dpptr(dd)->numrows = dpSavedptr(dd)->numrows;
    nc = dpptr(dd)->numcols = dpSavedptr(dd)->numcols;
    dpptr(dd)->currentFigure = dpSavedptr(dd)->currentFigure;
    dpptr(dd)->lastFigure = dpSavedptr(dd)->lastFigure;
    for (i = 0; i < nr && i < MAX_LAYOUT_ROWS; i++) {
	dpptr(dd)->heights[i] = dpSavedptr(dd)->heights[i];
	dpptr(dd)->cmHeights[i] = dpSavedptr(dd)->cmHeights[i];
    }
    for (j = 0; j < nc && j < MAX_LAYOUT_COLS; j++) {
	dpptr(dd)->widths[j] = dpSavedptr(dd)->widths[j];
	dpptr(dd)->cmWidths[j] = dpSavedptr(dd)->cmWidths[j];
    }
    for (i = 0; i < nr*nc && i < MAX_LAYOUT_CELLS; i++) {
	dpptr(dd)->order[i] = dpSavedptr(dd)->order[i];
	dpptr(dd)->respect[i] = dpSavedptr(dd)->respect[i];
    }
    dpptr(dd)->rspct = dpSavedptr(dd)->rspct;
    dpptr(dd)->layout = dpSavedptr(dd)->layout;
    dpptr(dd)->mfind = dpSavedptr(dd)->mfind;
    dpptr(dd)->new = dpSavedptr(dd)->new;
    dpptr(dd)->oma[0] = dpSavedptr(dd)->oma[0];
    dpptr(dd)->oma[1] = dpSavedptr(dd)->oma[1];
    dpptr(dd)->oma[2] = dpSavedptr(dd)->oma[2];
    dpptr(dd)->oma[3] = dpSavedptr(dd)->oma[3];
    dpptr(dd)->omi[0] = dpSavedptr(dd)->omi[0];
    dpptr(dd)->omi[1] = dpSavedptr(dd)->omi[1];
    dpptr(dd)->omi[2] = dpSavedptr(dd)->omi[2];
    dpptr(dd)->omi[3] = dpSavedptr(dd)->omi[3];
    dpptr(dd)->omd[0] = dpSavedptr(dd)->omd[0];
    dpptr(dd)->omd[1] = dpSavedptr(dd)->omd[1];
    dpptr(dd)->omd[2] = dpSavedptr(dd)->omd[2];
    dpptr(dd)->omd[3] = dpSavedptr(dd)->omd[3];
    dpptr(dd)->oUnits = dpSavedptr(dd)->oUnits;
    dpptr(dd)->plt[0] = dpSavedptr(dd)->plt[0];
    dpptr(dd)->plt[1] = dpSavedptr(dd)->plt[1];
    dpptr(dd)->plt[2] = dpSavedptr(dd)->plt[2];
    dpptr(dd)->plt[3] = dpSavedptr(dd)->plt[3];
    dpptr(dd)->pin[0] = dpSavedptr(dd)->pin[0];
    dpptr(dd)->pin[1] = dpSavedptr(dd)->pin[1];
    dpptr(dd)->pUnits = dpSavedptr(dd)->pUnits;
    dpptr(dd)->defaultPlot = dpSavedptr(dd)->defaultPlot;
    dpptr(dd)->pty = dpSavedptr(dd)->pty;
    dpptr(dd)->usr[0] = dpSavedptr(dd)->usr[0];
    dpptr(dd)->usr[1] = dpSavedptr(dd)->usr[1];
    dpptr(dd)->usr[2] = dpSavedptr(dd)->usr[2];
    dpptr(dd)->usr[3] = dpSavedptr(dd)->usr[3];
    dpptr(dd)->logusr[0] = dpSavedptr(dd)->logusr[0];
    dpptr(dd)->logusr[1] = dpSavedptr(dd)->logusr[1];
    dpptr(dd)->logusr[2] = dpSavedptr(dd)->logusr[2];
    dpptr(dd)->logusr[3] = dpSavedptr(dd)->logusr[3];
}

static SEXP baseCallback(GEevent task, pGEDevDesc dd, SEXP data)
{
    GESystemDesc *sd;
    baseSystemState *bss, *bss2;
    SEXP result = R_NilValue;

    switch (task) {
    case GE_FinaliseState:
	/* called from unregisterOne */
	sd = dd->gesd[baseRegisterIndex];
	free(sd->systemSpecific);
	sd->systemSpecific = NULL;
	break;
    case GE_InitState:
    {
	/* called from registerOne */
	pDevDesc dev;
	GPar *ddp;
	sd = dd->gesd[baseRegisterIndex];
	dev = dd->dev;
	bss = sd->systemSpecific = malloc(sizeof(baseSystemState));
        /* Bail out if necessary */
        if (!bss) return result;
	/* Make sure initialized, or valgrind may complain. */
        memset(bss, 0, sizeof(baseSystemState));
	ddp = &(bss->dp);
	GInit(ddp);
	/* For some things, the device sets the starting value at least. */
	ddp->ps = dev->startps;
	ddp->col = ddp->fg = dev->startcol;
	ddp->bg = dev->startfill;
	ddp->font = dev->startfont;
	ddp->lty = dev->startlty;
	ddp->gamma = dev->startgamma;
	/* Initialise the gp settings too: formerly in addDevice. */
	copyGPar(ddp, &(bss->gp));
	GReset(dd);
	/*
	 * The device has not yet received any base output
	 */
	bss->baseDevice = FALSE;
        /* Indicate success */
        result = R_BlankString;
	break;
    }
    case GE_CopyState:
    {
	/* called from GEcopyDisplayList */
	pGEDevDesc curdd = GEcurrentDevice();
	bss = dd->gesd[baseRegisterIndex]->systemSpecific;
	bss2 = curdd->gesd[baseRegisterIndex]->systemSpecific;
	copyGPar(&(bss->dpSaved), &(bss2->dpSaved));
	restoredpSaved(curdd);
	copyGPar(&(bss2->dp), &(bss2->gp));
	GReset(curdd);
	break;
    }
    case GE_SaveState:
	/* called from GEinitDisplayList */
	bss = dd->gesd[baseRegisterIndex]->systemSpecific;
	copyGPar(&(bss->dp), &(bss->dpSaved));
	break;
    case GE_RestoreState:
	/* called from GEplayDisplayList */
	bss = dd->gesd[baseRegisterIndex]->systemSpecific;
	restoredpSaved(dd);
	copyGPar(&(bss->dp), &(bss->gp));
	GReset(dd);
	break;
    case GE_SaveSnapshotState:
        /* called from GEcreateSnapshot */
        { 
            SEXP pkgName;
            bss = dd->gesd[baseRegisterIndex]->systemSpecific;
            /* Changed from INTSXP in 2.7.0: but saved graphics lists
               are protected by an R version number */
            PROTECT(result = allocVector(RAWSXP, sizeof(GPar)));
            copyGPar(&(bss->dpSaved), (GPar*) RAW(result));
            PROTECT(pkgName = mkString("graphics"));
            setAttrib(result, install("pkgName"), pkgName);
            UNPROTECT(2);
        }
	break;
    case GE_RestoreSnapshotState:
        /* called from GEplaySnapshot */
        {
            int i, nState = LENGTH(data) - 1;
            SEXP graphicsState, snapshotEngineVersion;
            PROTECT(graphicsState = R_NilValue);
            /* Prior to engine version 11, "pkgName" was not stored.
             * (can tell because "engineVersion" was not stored either.)
             * Assume 'graphics' is first state in snapshot
             * (though this could be fatal).
             */
            PROTECT(snapshotEngineVersion = 
                    getAttrib(data, install("engineVersion")));
            if (isNull(snapshotEngineVersion)) {
                graphicsState = VECTOR_ELT(data, 1);
            } else {
                for (i=0; i<nState; i++) {
                    SEXP state = VECTOR_ELT(data, i + 1);
                    if (!strcmp(CHAR(STRING_ELT(getAttrib(state, 
                                                          install("pkgName")), 
                                                0)), 
                                "graphics")) {
                        graphicsState = state;
                    }
                }
            }
            if (!isNull(graphicsState)) {
                /* Check that RAW blob being restored is same size
                 * as GPar struct in current R version.
                 * Any version difference will have been warned about,
                 * but a difference here means STOP.
                 */
                if (LENGTH(graphicsState) != sizeof(GPar)) {
                    error(_("Incompatible graphics state"));
                }
                bss = dd->gesd[baseRegisterIndex]->systemSpecific;
                copyGPar((GPar*) RAW(graphicsState), &(bss->dpSaved));
                /* These are probably redundant because GE_RestoreState
                 * will follow from GEplayDisplayList(), but no harm
                 * is done 
                 * AND there is at least one place that
                 * depends on this ('gridGraphics' package replays
                 * an empty DL to do restoredpSaved() on new page)
                 */
                restoredpSaved(dd);
                copyGPar(&(bss->dp), &(bss->gp));
                GReset(dd);
                /* Make the device "clean" with respect to 'graphics'
                 * so that the display list replay starts from scratch
                 */
                bss->baseDevice = FALSE;
            }
            UNPROTECT(2);
        }
	break;
    case GE_CheckPlot:
	/* called from GEcheckState:
	   Check that the current plotting state is "valid"
	 */
	bss = dd->gesd[baseRegisterIndex]->systemSpecific;
	result = ScalarLogical(bss->baseDevice ?
			       (bss->gp.state == 1) && bss->gp.valid :
			       TRUE);
	break;
    case GE_ScalePS:
    {
	/* called from GEhandleEvent in devWindows.c */
	GPar *ddp, *ddpSaved;
	bss = dd->gesd[baseRegisterIndex]->systemSpecific;
	ddp = &(bss->dp);
	ddpSaved = &(bss->dpSaved);
	if (isReal(data) && LENGTH(data) == 1) {
	    double rf = REAL(data)[0];
	    ddp->scale *= rf;
	    /* Modify the saved settings so this effects display list too */
	    ddpSaved->scale *= rf;
	} else
	  error("event 'GE_ScalePS' requires a single numeric value");
	break;
    }
    }
    return result;
}

/* (un)Register the base graphics system with the graphics engine
 */
void
registerBase(void) {
    GEregisterSystem(baseCallback, &baseRegisterIndex);
}

void
unregisterBase(void) {
    GEunregisterSystem(baseRegisterIndex);
    baseRegisterIndex = -1;   
}

SEXP RunregisterBase(void)
{
    unregisterBase();
    return R_NilValue;
}

/* FIXME: Make this a macro to avoid function call overhead?
   Inline it if you really think it matters.
 */
GPar* gpptr(pGEDevDesc dd) {
    if (baseRegisterIndex == -1)
	error(_("the base graphics system is not registered"));
    baseSystemState *bss = dd->gesd[baseRegisterIndex]->systemSpecific;
    return &(bss->gp);
}

GPar* dpptr(pGEDevDesc dd) {
    if (baseRegisterIndex == -1)
	error(_("the base graphics system is not registered"));
    baseSystemState *bss = dd->gesd[baseRegisterIndex]->systemSpecific;
    return &(bss->dp);
}

/* called in GNewPlot to mark device as 'dirty' */
void Rf_setBaseDevice(Rboolean val, pGEDevDesc dd) {
    if (baseRegisterIndex == -1)
	error(_("the base graphics system is not registered"));
    baseSystemState *bss = dd->gesd[baseRegisterIndex]->systemSpecific;
    bss->baseDevice = val;
}
