/*
 * Grace - GRaphing, Advanced Computation and Exploration of data
 * 
 * Home page: http://plasma-gate.weizmann.ac.il/Grace/
 * 
 * Copyright (c) 1991-1995 Paul J Turner, Portland, OR
 * Copyright (c) 1996-2000 Grace Development Team
 * 
 * Maintained by Evgeny Stambulchik
 * 
 * 
 *                           All Rights Reserved
 * 
 *    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, write to the Free Software
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/* 
 *
 * Read/write a parameter file
 *
 */

#include <config.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "globals.h"
#include "utils.h"
#include "graphs.h"
#include "graphutils.h"
#include "device.h"
#include "protos.h"

#include "ng_objects.h"
#include "nn_tree.h"
#include "zc.h"


static void put_regions (FILE * pp, int embed);
static void put_objects (FILE * pp, int embed);

static char buf[256];

void putparms(int gno, FILE *pp, int embed)
{
  int i ,j ,jo ,joc ,k ,ming ,maxg ,num;
    int ps ,pt ,gh ,gt ,fx ,fy ,px ,py;
    double dsx, dsy;
    char embedstr[2], tmpstr1[64], tmpstr2[64];
    framep f;
    legend leg;
    QDobject lobj ,*po;
    labels lab;
    plotarr p;
    tickmarks *t;
    world_stack ws;
    world w;
    view v;
    CMap_entry *cmap;
    GLocator locator;
    char *p1, *p2, *tmpbuf;
    int wpp, hpp;
    char cob[24];
    ZcLabel *zclist;

    if (embed) {
        strcpy(embedstr, "@");
    } else {
        embedstr[0] = 0;
    }
    fprintf(pp, "# -*- sh -*-\n");          /* to set emacs mode */
    fprintf(pp, "# Grace project file\n");
    fprintf(pp, "#\n");

    /* Print some global variables */
    fprintf(pp, "%sversion %ld\n", embedstr, bi_version_id());

    get_device_page_dimensions(tdevice, &wpp, &hpp);
    fprintf(pp, "%spage size %d, %d\n", embedstr, wpp, hpp);

    tmpbuf = copy_string(NULL, get_project_description());
    if (tmpbuf != NULL) {
        p1 = tmpbuf;
        while ((p2 = strchr (p1, '\n')) != NULL) {
            *p2 = 0;
            fprintf (pp, "%sdescription \"%s\"\n", embedstr, PSTRING(p1));
            *p2 = '\n';
            p1 = p2;
            p1++;
        }
        if (*p1) {
            fprintf (pp, "%sdescription \"%s\"\n", embedstr, PSTRING(p1));
        }
        xfree(tmpbuf);
    }

    fprintf(pp, "%spage scroll %d%%\n", embedstr, (int) rint(scrollper * 100));
    fprintf(pp, "%spage inout %d%%\n", embedstr, (int) rint(shexper * 100));
    fprintf(pp, "%slink page %s\n", embedstr, scrolling_islinked ? "on" : "off");

    for (i = 0; i < number_of_fonts(); i++) {
        if (get_font_mapped_id(i) != BAD_FONT_ID) {
            fprintf(pp, "%smap font %d to \"%s\", \"%s\"\n", embedstr,
                                                    get_font_mapped_id(i),
                                                    get_fontalias(i),
                                                    get_fontfallback(i));
        }
    }

    for (i = 0; i < number_of_colors(); i++) {
        cmap = get_cmap_entry(i);
        if (cmap != NULL && cmap->ctype == COLOR_MAIN) {
            fprintf(pp, "%smap color %d to (%d, %d, %d), \"%s\"\n", embedstr,
                i, cmap->rgb.red, cmap->rgb.green, cmap->rgb.blue,
                PSTRING(cmap->cname));
        }
    }
    
    fprintf(pp, "%sreference date %.12g\n", embedstr, get_ref_date());
    fprintf(pp, "%sdate wrap %s\n", embedstr,
        on_or_off(two_digits_years_allowed()));
    fprintf(pp, "%sdate wrap year %d\n", embedstr, get_wrap_year());
    
    fprintf(pp, "%sdefault linewidth %.1f\n", embedstr, grdefaults.linew);
    fprintf(pp, "%sdefault linestyle %d\n", embedstr, grdefaults.lines);
    fprintf(pp, "%sdefault color %d\n", embedstr, grdefaults.color);
    fprintf(pp, "%sdefault pattern %d\n", embedstr, grdefaults.pattern);
    fprintf(pp, "%sdefault font %d\n", embedstr, get_font_mapped_id(grdefaults.font));
    fprintf(pp, "%sdefault char size %f\n", embedstr, grdefaults.charsize);
    fprintf(pp, "%sdefault symbol size %f\n", embedstr, grdefaults.symsize);
    fprintf(pp, "%sdefault sformat \"%s\"\n", embedstr, PSTRING(sformat));
    
    fprintf(pp, "%sbackground color %d\n", embedstr, getbgcolor());
    fprintf(pp, "%spage background fill %s\n", embedstr, on_or_off(getbgfill()));
            
    fprintf(pp, "%stimestamp %s\n"          	, embedstr , on_or_off(!objs[iTS].hidden));
    fprintf(pp, "%stimestamp %.12g, %.12g\n"	, embedstr , objs[iTS].x1, objs[iTS].y1);
    fprintf(pp, "%stimestamp color %d\n"    	, embedstr , objs[iTS].color);
    fprintf(pp, "%stimestamp rot %d\n"      	, embedstr , objs[iTS].rot);
    fprintf(pp, "%stimestamp font %d\n"     	, embedstr , get_font_mapped_id(objs[iTS].font));
    fprintf(pp, "%stimestamp just %d\n"     	, embedstr , objs[iTS].just);        /* gracegtk */
    fprintf(pp, "%stimestamp char size %f\n"	, embedstr , objs[iTS].charsize);
    fprintf(pp, "%stimestamp linestyle %d\n"    ,embedstr  , objs[iTS].lines);       /* gracegtk */
    fprintf(pp ,"%stimestamp fill pattern %d\n" ,embedstr  , objs[iTS].fillpattern); /* gracegtk */
    fprintf(pp, "%stimestamp fill color %d\n"   ,embedstr  , objs[iTS].fillcolor);   /* gracegtk */
    fprintf(pp, "%stimestamp def \"%s\"\n"  	, embedstr , PSTRING(objs[iTS].s));


    put_objects (pp, embed);
    
    put_regions(pp, embed);
    
    if (gno == ALL_GRAPHS) {
        maxg = number_of_graphs() - 1;
        ming = 0;
    } else {
        maxg = gno;
        ming = gno;
    }
    for (k = ming; k <= maxg; k++) {
        if (is_graph_active(k)) {
            gno = k;
            gh = is_graph_hidden(gno);
            gt = get_graph_type(gno);
            get_graph_locator(gno, &locator);
            ps = locator.pointset;
            pt = locator.pt_type;
            dsx = locator.dsx;
            dsy = locator.dsy;
            fx = locator.fx;
            fy = locator.fy;
            px = locator.px;
            py = locator.py;

            fprintf(pp, "%sg%1d %s\n", embedstr, gno, 
                                            on_or_off(is_graph_active(gno)));
            fprintf(pp, "%sg%1d hidden %s\n", embedstr, gno,
                                            true_or_false(gh));
            fprintf(pp, "%sg%1d type %s\n", embedstr, gno, graph_types(gt));
            fprintf(pp, "%sg%1d stacked %s\n", embedstr, gno,
                                        true_or_false(is_graph_stacked(gno)));

            fprintf(pp, "%sg%1d bar hgap %f\n", embedstr, gno,
                                                        get_graph_bargap(gno));

            fprintf(pp, "%sg%1d fixedpoint %s\n", embedstr, gno, on_or_off(ps));
            fprintf(pp, "%sg%1d fixedpoint type %d\n", embedstr, gno, pt);
            fprintf(pp, "%sg%1d fixedpoint xy %f, %f\n", embedstr, gno,
                                                                    dsx, dsy);
            strcpy(tmpstr1, get_format_types(fx));
            strcpy(tmpstr2, get_format_types(fy));
            fprintf(pp, "%sg%1d fixedpoint format %s %s\n", embedstr, gno,
                                                            tmpstr1, tmpstr2);
            fprintf(pp, "%sg%1d fixedpoint prec %d, %d\n", embedstr, gno,
                                                                      px, py);

            fprintf(pp, "%swith g%1d\n", embedstr, gno);

            get_graph_world(gno, &w);
            fprintf(pp, "%s    world %.12g, %.12g, %.12g, %.12g\n", embedstr,
                w.xg1, w.yg1, w.xg2, w.yg2);

            for (i = 0; i < graph_world_stack_size(gno); i++) {
                get_world_stack_entry(gno, i, &ws);
                fprintf(pp, "%s    stack world %.9g, %.9g, %.9g, %.9g\n", embedstr,
                        ws.w.xg1, ws.w.xg2, ws.w.yg1, ws.w.yg2);
            }

            fprintf(pp, "%s    znorm %g\n", embedstr, get_graph_znorm(gno));

            get_graph_viewport(gno, &v);
            fprintf(pp, "%s    view %f, %f, %f, %f\n", embedstr,
                v.xv1, v.yv1, v.xv2, v.yv2);

            get_graph_labels(gno, &lab);
            fprintf(pp ,"%s    title \"%s\"\n"   ,embedstr ,PSTRING (lab.title.s));
            fprintf(pp ,"%s    title layer %d\n" ,embedstr ,lab.title.layer);
            fprintf(pp ,"%s    title font %d\n"  ,embedstr ,get_font_mapped_id (lab.title.font));
            fprintf(pp ,"%s    title size %f\n"  ,embedstr ,lab.title.charsize);
            fprintf(pp ,"%s    title color %d\n" ,embedstr ,lab.title.color);
	    fprintf(pp ,"%s    title just %d\n" ,embedstr ,lab.title.just);                        /* gracegtk */
	    fprintf(pp ,"%s    title offset %f , %f\n" ,embedstr ,lab.title.x1 ,lab.title.y1);     /* gracegtk */
            fprintf(pp ,"%s    subtitle \"%s\"\n"   ,embedstr ,PSTRING (lab.stitle.s));
            fprintf(pp ,"%s    subtitle layer %d\n" ,embedstr ,lab.stitle.layer);
            fprintf(pp ,"%s    subtitle font %d\n"  ,embedstr ,get_font_mapped_id (lab.stitle.font));
            fprintf(pp ,"%s    subtitle size %f\n"  ,embedstr ,lab.stitle.charsize);
            fprintf(pp ,"%s    subtitle color %d\n" ,embedstr ,lab.stitle.color);
	    fprintf(pp ,"%s    subtitle just %d\n" ,embedstr ,lab.title.just);                     /* gracegtk */
	    fprintf(pp ,"%s    subtitle offset %f , %f\n" ,embedstr ,lab.stitle.x1 ,lab.stitle.y1);  /* gracegtk */

            fprintf(pp, "%s    xaxes scale %s\n", embedstr, scale_types(get_graph_xscale(gno)));
            fprintf(pp, "%s    yaxes scale %s\n", embedstr, scale_types(get_graph_yscale(gno)));
            fprintf(pp, "%s    xaxes invert %s\n", embedstr, on_or_off(is_graph_xinvert(gno)));
            fprintf(pp, "%s    yaxes invert %s\n", embedstr, on_or_off(is_graph_yinvert(gno)));

            for (i = 0; i < MAXAXES; i++) {
                t   = get_graph_tickmarks(gno, i);
		num = obj_tid_get_num (Q_Axis ,i ,Q_Graph ,gno);
                switch (i) {
                case 0:
                    sprintf(buf, "%s    xaxis ", embedstr);
                    break;
                case 1:
                    sprintf(buf, "%s    yaxis ", embedstr);
                    break;
                case 2:
                    sprintf(buf, "%s    altxaxis ", embedstr);
                    break;
                case 3:
                    sprintf(buf, "%s    altyaxis ", embedstr);
                    break;
                }

                fprintf(pp, "%s %s\n", buf, on_or_off(t && t->active));
                if (!t || t->active == FALSE) {
                    continue;
                }
                fprintf(pp, "%s layer %d\n", buf, objs[num].layer);
                
                fprintf(pp, "%s type zero %s\n", buf, true_or_false(t->zero));

                fprintf(pp, "%s offset %f , %f\n", buf, t->offsx, t->offsy);

                fprintf(pp, "%s bar %s\n", buf, on_or_off(t->t_drawbar));
                fprintf(pp, "%s bar color %d\n", buf, t->t_drawbarcolor);
                fprintf(pp, "%s bar linestyle %d\n", buf, t->t_drawbarlines);
                fprintf(pp, "%s bar linewidth %.1f\n", buf, t->t_drawbarlinew);


                fprintf(pp, "%s label \"%s\"\n", buf, PSTRING(t->label.s));
                if (t->label_layout == LAYOUT_PERPENDICULAR) {
                    fprintf(pp, "%s label layout perp\n", buf);
                } else {
                    fprintf(pp, "%s label layout para\n", buf);
                }
                if (t->label_place == TYPE_AUTO) {
                    fprintf(pp, "%s label place auto\n", buf);
                } else {
                    fprintf(pp, "%s label place spec\n", buf);
                    fprintf(pp, "%s label place %f, %f\n", buf, t->label.x1, t->label.y1);
                }
                fprintf(pp, "%s label char size %f\n", buf, t->label.charsize);
                fprintf(pp, "%s label font %d\n", buf, get_font_mapped_id(t->label.font));
                fprintf(pp, "%s label color %d\n", buf, t->label.color);
                switch (t->label_op) {
                case PLACEMENT_NORMAL:
                    fprintf(pp, "%s label place normal\n", buf);
                    break;
                case PLACEMENT_OPPOSITE:
                    fprintf(pp, "%s label place opposite\n", buf);
                    break;
                case PLACEMENT_BOTH:
                    fprintf(pp, "%s label place both\n", buf);
                    break;
                }

                fprintf(pp, "%s tick %s\n", buf, on_or_off(t->t_flag));
                fprintf(pp, "%s tick major %.12g\n", buf, t->tmajor);
                fprintf(pp, "%s tick minor ticks %d\n", buf, t->nminor);
                fprintf(pp, "%s tick default %d\n", buf, t->t_autonum);
                fprintf(pp, "%s tick place rounded %s\n", buf, true_or_false(t->t_round));
                switch (t->t_inout) {
                case TICKS_IN:
                    fprintf(pp, "%s tick in\n", buf);
                    break;
                case TICKS_OUT:
                    fprintf(pp, "%s tick out\n", buf);
                    break;
                case TICKS_BOTH:
                    fprintf(pp, "%s tick both\n", buf);
                    break;
                }
                fprintf(pp, "%s tick major size %f\n", buf, t->props.size);
                fprintf(pp, "%s tick major color %d\n", buf, t->props.color);
                fprintf(pp, "%s tick major linewidth %.1f\n", buf, t->props.linew);
                fprintf(pp, "%s tick major linestyle %d\n", buf, t->props.lines);
                fprintf(pp, "%s tick major grid %s\n", buf, on_or_off(t->props.gridflag));
                fprintf(pp, "%s tick minor color %d\n", buf, t->mprops.color);
                fprintf(pp, "%s tick minor linewidth %.1f\n", buf, t->mprops.linew);
                fprintf(pp, "%s tick minor linestyle %d\n", buf, t->mprops.lines);
                fprintf(pp, "%s tick minor grid %s\n", buf, on_or_off(t->mprops.gridflag));
                fprintf(pp, "%s tick minor size %f\n", buf, t->mprops.size);


                fprintf(pp, "%s ticklabel %s\n", buf, on_or_off(t->tl_flag));
                fprintf(pp, "%s ticklabel format %s\n", buf, get_format_types(t->tl_format));
                fprintf(pp, "%s ticklabel prec %d\n", buf, t->tl_prec);

                fprintf(pp, "%s ticklabel formula \"%s\"\n",
                    buf, PSTRING(t->tl_formula));

                fprintf(pp, "%s ticklabel append \"%s\"\n", buf, PSTRING(t->tl_appstr));
                fprintf(pp, "%s ticklabel prepend \"%s\"\n", buf, PSTRING(t->tl_prestr));
                fprintf(pp, "%s ticklabel angle %d\n", buf, t->tl_angle);
                fprintf(pp, "%s ticklabel skip %d\n", buf, t->tl_skip);
                fprintf(pp, "%s ticklabel stagger %d\n", buf, t->tl_staggered);
                switch (t->tl_op) {
                case PLACEMENT_NORMAL:
                    fprintf(pp, "%s ticklabel place normal\n", buf);
                    break;
                case PLACEMENT_OPPOSITE:
                    fprintf(pp, "%s ticklabel place opposite\n", buf);
                    break;
                case PLACEMENT_BOTH:
                    fprintf(pp, "%s ticklabel place both\n", buf);
                    break;
                }

                fprintf(pp, "%s ticklabel offset %s\n", buf,
                                t->tl_gaptype == TYPE_AUTO ? "auto" : "spec");

                fprintf(pp, "%s ticklabel offset %f , %f\n", buf, t->tl_gap.x, t->tl_gap.y);
                fprintf(pp, "%s ticklabel start type %s\n", buf,
                                t->tl_starttype == TYPE_AUTO ? "auto" : "spec");
                fprintf(pp, "%s ticklabel start %f\n", buf, t->tl_start);
                fprintf(pp, "%s ticklabel stop type %s\n", buf,
                                t->tl_stoptype == TYPE_AUTO ? "auto" : "spec");
                fprintf(pp, "%s ticklabel stop %f\n", buf, t->tl_stop);
                fprintf(pp, "%s ticklabel char size %f\n", buf, t->tl_charsize);
                fprintf(pp, "%s ticklabel font %d\n", buf, get_font_mapped_id(t->tl_font));
                fprintf(pp, "%s ticklabel color %d\n", buf, t->tl_color);

                switch (t->t_op) {
                case PLACEMENT_NORMAL:
                    fprintf(pp, "%s tick place normal\n", buf);
                    break;
                case PLACEMENT_OPPOSITE:
                    fprintf(pp, "%s tick place opposite\n", buf);
                    break;
                case PLACEMENT_BOTH:
                    fprintf(pp, "%s tick place both\n", buf);
                    break;
                }
                switch (t->t_spec) {
                case TICKS_SPEC_NONE:
                    fprintf(pp, "%s tick spec type none\n", buf);
                    break;
                case TICKS_SPEC_MARKS:
                    fprintf(pp, "%s tick spec type ticks\n", buf);
                    break;
                case TICKS_SPEC_BOTH:
                    fprintf(pp, "%s tick spec type both\n", buf);
                    break;
                }
                
                if (t->t_spec != TICKS_SPEC_NONE) {
                    fprintf(pp, "%s tick spec %d\n", buf, t->nticks);
                    for (j = 0; j < t->nticks; j++) {
                        sprintf(tmpstr1, sformat, t->tloc[j].wtpos);
                        if (t->tloc[j].type == TICK_TYPE_MAJOR) {
                            fprintf(pp, "%s tick major %d, %s\n",
                                buf, j, tmpstr1);
                            if (t->t_spec == TICKS_SPEC_BOTH) {
                                fprintf(pp, "%s ticklabel %d, \"%s\"\n",
                                    buf, j, PSTRING(t->tloc[j].label));
                            }
                        } else {
                            fprintf(pp, "%s tick minor %d, %s\n",
                                buf, j, tmpstr1);
                        }
                    }
                }
            }

            get_graph_legend(gno, &leg ,&lobj);
            fprintf(pp, "%s    legend %s\n"         ,embedstr, on_or_off(leg.active));
            fprintf(pp, "%s    legend layer %d\n"   ,embedstr ,lobj.layer);
            fprintf(pp, "%s    legend loctype %s\n" ,embedstr, w_or_v(leg.loctype));
            fprintf(pp, "%s    legend %.12g, %.12g\n", embedstr, leg.legx, leg.legy);
            fprintf(pp, "%s    legend box color %d\n", embedstr, leg.boxpen.color);
            fprintf(pp, "%s    legend box pattern %d\n", embedstr, leg.boxpen.pattern);
            fprintf(pp, "%s    legend box linewidth %.1f\n", embedstr, leg.boxlinew);
            fprintf(pp, "%s    legend box linestyle %d\n", embedstr, leg.boxlines);
            fprintf(pp, "%s    legend box fill color %d\n", embedstr, leg.boxfillpen.color);
            fprintf(pp, "%s    legend box fill pattern %d\n", embedstr, leg.boxfillpen.pattern);
            fprintf(pp, "%s    legend font %d\n", embedstr, get_font_mapped_id(leg.font));
            fprintf(pp, "%s    legend char size %f\n", embedstr, leg.charsize);
            fprintf(pp, "%s    legend color %d\n", embedstr, leg.color);
            fprintf(pp, "%s    legend length %d\n", embedstr, leg.len);
            fprintf(pp, "%s    legend vgap %d\n", embedstr, leg.vgap);
            fprintf(pp, "%s    legend hgap %d\n", embedstr, leg.hgap);
            fprintf(pp, "%s    legend invert %s\n", embedstr, true_or_false(leg.invert));


            get_graph_framep(gno ,&f);
            fprintf(pp ,"%s    frame type %d\n"        	      ,embedstr ,f.type);
            fprintf(pp ,"%s    frame layer %d\n"   	      ,embedstr ,f.layer);
            fprintf(pp ,"%s    frame linestyle %d\n"   	      ,embedstr ,f.lines);
            fprintf(pp ,"%s    frame linewidth %.1f\n" 	      ,embedstr ,f.linew);
            fprintf(pp ,"%s    frame color %d\n"       	      ,embedstr ,f.pen.color);
            fprintf(pp ,"%s    frame pattern %d\n"     	      ,embedstr ,f.pen.pattern);
            fprintf(pp ,"%s    frame background color %d\n"   ,embedstr ,f.fillpen.color);
            fprintf(pp ,"%s    frame background pattern %d\n" ,embedstr ,f.fillpen.pattern);

            for (i = 0; i < number_of_sets(gno); i++) {
                get_graph_plotarr(gno, i, &p);
                if (is_set_active(gno, i) == TRUE) {
		  num = obj_tid_get_set_num (gno ,i);
		  jo = obj_tid_get_set_num (gno ,i); //15 un des deux en trop
                    fprintf(pp ,"%s    s%1d hidden %s\n" ,embedstr ,i ,true_or_false(p.hidden));
                    fprintf(pp ,"%s    s%1d layer %d\n"  ,embedstr ,i ,objs[num].layer);
		    if (p.type == SET_XYCMAP) {
		      fprintf(pp, "%s    s%1d type %s  %d , %d\n" , embedstr, i, set_types(p.type) ,p.contour.nx ,p.contour.ny);
		    } else {
		      fprintf(pp, "%s    s%1d type %s\n" 	  , embedstr, i, set_types(p.type));
		    }
                    fprintf(pp, "%s    s%1d symbol %d\n", embedstr, i, p.sym);
                    fprintf(pp, "%s    s%1d symbol size %f\n", embedstr, i, p.symsize);
                    fprintf(pp, "%s    s%1d symbol color %d\n", embedstr, i, p.sympen.color);
                    fprintf(pp, "%s    s%1d symbol pattern %d\n", embedstr, i, p.sympen.pattern);
                    fprintf(pp, "%s    s%1d symbol fill color %d\n", embedstr, i, p.symfillpen.color);
                    fprintf(pp, "%s    s%1d symbol fill pattern %d\n", embedstr, i, p.symfillpen.pattern);
                    fprintf(pp, "%s    s%1d symbol linewidth %.1f\n", embedstr, i, p.symlinew);
                    fprintf(pp, "%s    s%1d symbol linestyle %d\n", embedstr, i, p.symlines);
                    fprintf(pp, "%s    s%1d symbol char %d\n", embedstr, i, p.symchar);
                    fprintf(pp, "%s    s%1d symbol char font %d\n", embedstr, i, get_font_mapped_id(p.charfont));
                    fprintf(pp, "%s    s%1d symbol skip %d\n", embedstr, i, p.symskip);

		    if (p.linet == LINE_TYPE_SPLINE) {
		      fprintf(pp, "%s    s%1d line type %d , %d , %d\n", embedstr, i, p.linet ,p.method ,p.meshlen);	 /* gracegtk */
		    } else {
		      fprintf(pp, "%s    s%1d line type %d\n", embedstr, i, p.linet);
		    }
                    fprintf(pp, "%s    s%1d line linestyle %d\n", embedstr, i, p.lines);
                    fprintf(pp, "%s    s%1d line linewidth %.1f\n", embedstr, i, p.linew);
                    fprintf(pp, "%s    s%1d line color %d\n", embedstr, i, p.linepen.color);
                    fprintf(pp, "%s    s%1d line pattern %d\n", embedstr, i, p.linepen.pattern);

                    fprintf(pp, "%s    s%1d baseline type %d\n", embedstr, i, p.baseline_type);
                    fprintf(pp, "%s    s%1d baseline %s\n", embedstr, i, on_or_off(p.baseline));
                    fprintf(pp, "%s    s%1d dropline %s\n", embedstr, i, on_or_off(p.dropline));

                    fprintf(pp, "%s    s%1d fill type %d\n", embedstr, i, p.filltype);
                    fprintf(pp, "%s    s%1d fill rule %d\n", embedstr, i, p.fillrule);
                    fprintf(pp, "%s    s%1d fill color %d\n", embedstr, i, p.setfillpen.color);
                    fprintf(pp, "%s    s%1d fill pattern %d\n", embedstr, i, p.setfillpen.pattern);

                    fprintf(pp, "%s    s%1d avalue %s\n", embedstr, i, on_or_off(p.avalue.active));
                    fprintf(pp, "%s    s%1d avalue type %d\n", embedstr, i, p.avalue.type);
                    fprintf(pp, "%s    s%1d avalue char size %f\n", embedstr, i, p.avalue.size);
                    fprintf(pp, "%s    s%1d avalue font %d\n", embedstr, i, get_font_mapped_id(p.avalue.font));
                    fprintf(pp, "%s    s%1d avalue color %d\n", embedstr, i, p.avalue.color);
                    fprintf(pp, "%s    s%1d avalue rot %d\n", embedstr, i, p.avalue.angle);
                    fprintf(pp, "%s    s%1d avalue format %s\n", embedstr, i, get_format_types(p.avalue.format));
                    fprintf(pp, "%s    s%1d avalue prec %d\n", embedstr, i, p.avalue.prec);
                    fprintf(pp, "%s    s%1d avalue prepend \"%s\"\n", embedstr, i, PSTRING(p.avalue.prestr));
                    fprintf(pp, "%s    s%1d avalue append \"%s\"\n", embedstr, i, PSTRING(p.avalue.appstr));
                    fprintf(pp, "%s    s%1d avalue offset %f , %f\n", embedstr, i, p.avalue.offset.x, p.avalue.offset.y);
                    fprintf(pp, "%s    s%1d avalue skip %d , %d\n", embedstr, i, p.avalue.skip, p.avalue.start);

                    fprintf(pp, "%s    s%1d errorbar %s\n", embedstr, i, on_or_off(p.errbar.active));
                    switch (p.errbar.ptype) {
                    case PLACEMENT_NORMAL:
                        fprintf(pp, "%s    s%1d errorbar place normal\n", embedstr, i);
                        break;
                    case PLACEMENT_OPPOSITE:
                        fprintf(pp, "%s    s%1d errorbar place opposite\n", embedstr, i);
                        break;
                    case PLACEMENT_BOTH:
                        fprintf(pp, "%s    s%1d errorbar place both\n", embedstr, i);
                        break;
                    }
                    fprintf (pp ,"%s    s%1d errorbar color %d\n" 	      ,embedstr ,i ,p.errbar.pen.color);
                    fprintf (pp ,"%s    s%1d errorbar pattern %d\n" 	      ,embedstr ,i ,p.errbar.pen.pattern);
                    fprintf (pp ,"%s    s%1d errorbar size %f\n" 	      ,embedstr ,i ,p.errbar.barsize);
                    fprintf (pp ,"%s    s%1d errorbar linewidth %.1f\n"       ,embedstr ,i ,p.errbar.linew);
                    fprintf (pp ,"%s    s%1d errorbar linestyle %d\n"         ,embedstr ,i ,p.errbar.lines);
                    fprintf (pp ,"%s    s%1d errorbar riser linewidth %.1f\n" ,embedstr ,i ,p.errbar.riser_linew);
                    fprintf (pp ,"%s    s%1d errorbar riser linestyle %d\n"   ,embedstr ,i ,p.errbar.riser_lines);
                    fprintf (pp ,"%s    s%1d errorbar riser clip %s\n" 	     ,embedstr ,i ,on_or_off(p.errbar.arrow_clip));
                    fprintf (pp ,"%s    s%1d errorbar riser clip length %f\n" ,embedstr ,i ,p.errbar.cliplen);

		    switch (p.type) {
		    case SET_XYVMAP:
		      fprintf (pp ,"%s    s%1d vmap color %d\n"      	   ,embedstr ,i ,objs[jo].color);
		      fprintf (pp ,"%s    s%1d vmap linewidth %f\n"  	   ,embedstr ,i ,objs[jo].linew);
		      fprintf (pp ,"%s    s%1d vmap linestyle %d\n"  	   ,embedstr ,i ,objs[jo].lines);
		      fprintf (pp ,"%s    s%1d vmap arrow type %d\n" 	   ,embedstr ,i ,objs[jo].arrow.type);
		      fprintf (pp ,"%s    s%1d vmap arrow length %f\n" 	   ,embedstr ,i ,objs[jo].arrow.length);
		      fprintf (pp ,"%s    s%1d vmap arrow layout %f, %f\n" ,embedstr ,i ,objs[jo].arrow.dL_ff ,objs[jo].arrow.lL_ff);
		      break;
		    case SET_XYCMAP:
		      fprintf (pp ,"%s    s%1d Cmap \"%s\"\n"  	           ,embedstr ,i ,zc_cmap_get_name (p.contour.nmap));
		      fprintf (pp ,"%s    s%1d Contour hidden %s\n" 	   ,embedstr ,i ,on_or_off (p.contour.hidden));
		      fprintf (pp ,"%s    s%1d Contour color %d\n" 	   ,embedstr ,i ,p.contour.line_color);
		      fprintf (pp ,"%s    s%1d Contour linewidth %f\n" 	   ,embedstr ,i ,p.linew);
		      zclist = p.contour.zclist;
		      while (zclist != NULL) {
			fprintf (pp ,"%s    s%1d Contour label %g , %g , %g\n" ,embedstr ,i 
				 ,zclist->x ,zclist->y ,zclist->z);
			zclist = zclist->next;
		      }

		      fprintf (pp ,"%s    s%1d Colorbar zscale  %g , %g\n" ,embedstr ,i ,p.contour.z1 ,p.contour.z2);
		      fprintf (pp ,"%s    s%1d Colorbar nticks  %d\n" 	   ,embedstr ,i ,p.contour.nticks);
		      /* others parameters for colorbars are in the objs[] element */
		      sprintf (cob ,"%s   G%1d.s%1d Colorbar    " ,embedstr ,gno ,i);
		      joc = objs[jo].child; 
		      po = &(objs[joc]);
		      fprintf (pp ,"%s : %.12g , %.12g , %.12g , %.12g\n" ,cob ,po->x1, po->y1, po->x2, po->y2);
		      fprintf (pp, "%s layer %d\n"           	          ,cob ,po->layer);
		      fprintf (pp, "%s hidden %s\n"            	          ,cob ,true_or_false (po->hidden));
		      fprintf (pp, "%s linestyle %d\n"                    ,cob ,po->lines);
		      fprintf (pp, "%s linewidth %f\n"                    ,cob ,po->linew);
		      fprintf (pp, "%s color %d\n"                        ,cob ,po->color);
		      fprintf (pp, "%s just %d\n"                         ,cob ,po->just);
		      fprintf (pp, "%s font %d\n"                         ,cob ,po->font);
		      fprintf (pp, "%s char size %f\n"                    ,cob ,po->charsize);
		      break;
		    default:
		      break;
		    }

                    if (is_hotlinked(gno, i)) {
                        fprintf(pp, "%s    s%1d link %s \"%s\"\n", embedstr, i,
                                p.hotsrc == SOURCE_DISK ? "disk" : "pipe", p.hotfile);
                    }
                    fprintf(pp, "%s    s%1d legend %s\n"     , embedstr, i, on_or_off(p.legend_on));
                    fprintf(pp, "%s    s%1d legend  \"%s\"\n", embedstr, i, PSTRING(p.lstr));
                    fprintf(pp, "%s    s%1d comment \"%s\"\n", embedstr, i, PSTRING(p.comments));
                
                }
            }
        }
    }
}

static FILE *ppa = NULL;

static void print_compound (int i ,int depth)
{
  int child;
  if (objs[i].typ == Q_Compound) {
    child  = objs[i].child;
    if (objs[i].s != NULL) {
      fprintf (ppa ,"@ New Compound %d \"%s\" %s %d\n" ,objs[i].id ,objs[i].s ,Qtype_name[objs[child].typ] ,objs[child].id);
    } else {
      fprintf (ppa ,"@ New Compound %d %s %d\n"        ,objs[i].id 	      ,Qtype_name[objs[child].typ] ,objs[child].id);
    }
    while (objs[child].brother >= 0) {
      child = objs[child].brother;
      fprintf (ppa ,"@   Compound %d %s %d\n" ,objs[i].id 
	       ,Qtype_name[objs[child].typ]
	       ,objs[child].id);
    }
    fprintf (ppa, "@   Compound  %d hidden %s\n"            ,objs[i].id ,true_or_false (objs[i].hidden));
    fprintf (ppa ,"@   Compound  %d loctype %s\n"           ,objs[i].id ,w_or_v (objs[i].loctyp));
    fprintf (ppa ,"@   Compound  %d : %f , %f , %f , %f\n"  ,objs[i].id ,objs[i].x1 ,objs[i].y1 ,objs[i].x2 ,objs[i].y2);
  }
}



static void put_objects (FILE * pp, int embed)
{
  int gno ,i;
  char embedstr[2];
  QDobject o;
  Qtype typ = Q_Undef;
  char *nmt = NULL;
  int subarc = 0;
  ppa = pp;
  if (pp == NULL) return;

  if (embed) {
    strcpy(embedstr, "@");
  } else {
    embedstr[0] = 0;
  }

  /* timestamp (i.e. objs[iTS]) is printed above and compounds at the end */
  for (i = iTS+1; i < objs_max(); i++) {
    if (obj_is_active (i) && objs[i].id >= 0) {  // Q_LegendBox a inclure
      switch (objs[i].typ) {
      case Q_Line:
      case Q_Polyline:
      case Q_Arc:
      case Q_String:
      case Q_Box:
	o = objs[i];
	if (o.father_id > -2) { 
	  typ = o.typ;
	  nmt = Qtype_name[typ];
	  switch (typ) {        /* for Grace-5 compatibility */
	  case Q_Arc:
	    subarc = arc_subtyp (o.pmask);
	    if (subarc == 1) nmt =  "Ellipse";
	    break;
	  case Q_Polyline:
	   if (o.nxy == 2) nmt = "Line";
	    break;
	  default:
	    break;
	  }
	  fprintf (pp ,"%sWITH %s %d\n"                   	,embedstr ,nmt ,o.id);
	  fprintf (pp, "%s    %s  hidden %s\n"          ,embedstr ,nmt ,true_or_false (o.hidden)); //24
	  fprintf (pp ,"%s    %s on\n"                 	,embedstr ,nmt);
	  if (typ == Q_Arc && subarc != 1) {
	    fprintf (pp, "%s    %s Type  %d \n"  ,embedstr ,nmt ,subarc);
	  }
	}
	fprintf (pp, "%s    %s layer %d\n"           	,embedstr ,nmt ,o.layer);
	gno = obj_get_typed_ancestor_id (i ,Q_Graph);
	if (gno >= 0){
	  fprintf (pp, "%s    %s g%1d\n"             	,embedstr ,nmt ,gno);
	}
	fprintf (pp ,"%s    %s loctype %s\n"         	,embedstr ,nmt ,w_or_v(o.loctyp));
	fprintf (pp, "%s    %s color %d\n"           	,embedstr ,nmt ,o.color);
	if (typ == Q_String) {
	  fprintf (pp, "%s    %s %.12g , %.12g\n"    	,embedstr ,nmt ,o.x1, o.y1 );
	  fprintf (pp, "%s    %s rot %d\n"           	,embedstr ,nmt ,o.rot    );
	  fprintf (pp, "%s    %s font %d\n"          	,embedstr ,nmt ,get_font_mapped_id (o.font));
	  fprintf (pp, "%s    %s just %d\n"          	,embedstr ,nmt ,o.just   );
	  fprintf (pp, "%s    %s char size %f\n"     	,embedstr ,nmt ,o.charsize);
	  fprintf (pp, "%s    %s linestyle %d\n"        ,embedstr ,nmt ,o.lines);
	  fprintf (pp ,"%s    %s fill pattern %d\n"     ,embedstr ,nmt ,o.fillpattern);
	  fprintf (pp ,"%s    %s fill color %d\n"       ,embedstr ,nmt ,o.fillcolor);
	} else {
	  /* Q_Arc , Q_Box  , Q_Line */
	  fprintf (pp ,"%s    %s %.12g , %.12g , %.12g , %.12g\n" ,embedstr ,nmt, o.x1, o.y1, o.x2, o.y2);
	  fprintf (pp, "%s    %s linestyle %d\n"        ,embedstr ,nmt ,o.lines);
	  fprintf (pp, "%s    %s linewidth %.1f\n"      ,embedstr ,nmt ,o.linew);
	  if (typ != Q_Line && typ != Q_Polyline) {
	    /* Q_Arc , Q_Box */
	    fprintf (pp ,"%s    %s fill color %d\n"       ,embedstr ,nmt ,o.fillcolor);
	    fprintf (pp ,"%s    %s fill pattern %d\n"     ,embedstr ,nmt ,o.fillpattern);
	    if (typ == Q_Arc && !(o.pmask & MARC_Ellipse)) {
	      fprintf (pp, "%s    %s Angles  %d , %d \n"  ,embedstr ,nmt ,o.astart ,o.aend);
	    }
	  }
	  if (typ == Q_Line || typ == Q_Polyline || 
	      (typ == Q_Arc &&  !(o.pmask & MARC_Ellipse))) {
	    /* Q_Line, Q_Polyline and Q_Arc with arrows */
	    fprintf (pp ,"%s    %s arrow %d\n"            ,embedstr ,nmt ,o.arrow_end);
	    fprintf (pp ,"%s    %s arrow type %d\n"       ,embedstr ,nmt ,o.arrow.type);
	    fprintf (pp ,"%s    %s arrow length %f\n"     ,embedstr ,nmt ,o.arrow.length);
	    fprintf (pp ,"%s    %s arrow layout %f, %f\n" ,embedstr ,nmt ,o.arrow.dL_ff, o.arrow.lL_ff);
	  }
	}
	if (typ == Q_String) {
	  fprintf(pp, "%s    string def \"%s\"\n", embedstr, PSTRING(o.s));
	} else if (o.s != NULL) {
	  fprintf(pp, "%s    %s def \"%s\"\n" ,embedstr ,nmt ,o.s);
	} else {
	  fprintf(pp, "%s %s def\n" ,embedstr ,nmt);
	}
	if (typ == Q_Line) {  /* for label */
	  fprintf (pp ,"%s    %s label type %d\n"       ,embedstr ,nmt ,o.label_opt);
	  fprintf (pp, "%s    %s rot %d\n"           	,embedstr ,nmt ,o.rot    );
	  fprintf (pp, "%s    %s font %d\n"          	,embedstr ,nmt ,get_font_mapped_id (o.font));
	  fprintf (pp, "%s    %s just %d\n"          	,embedstr ,nmt ,o.just   );
	  fprintf (pp, "%s    %s char size %f\n"     	,embedstr ,nmt ,o.charsize);
	  fprintf (pp ,"%s    %s label format \"%s\"\n" ,embedstr ,nmt ,PSTRING (o.frmt));
	  fprintf (pp ,"%s    %s label offset %g , %g\n",embedstr ,nmt ,o.perp ,o.para);
	}
	break;
      default:
	/* other types are printed elsewhere */
	break;
      }
      if (objs[i].typ == Q_Polyline && o.nxy != 2) {
	obj_polyline_write (o.id ,pp);
      }
    }
  }

  /* Now, print compounds */
  /* Compounds are always written and
   * we must start with the compounds the further from the root */
  nn_traverse_child_first (0 ,NULL ,print_compound);
 

}

static void put_regions(FILE * pp, int embed)
{
    int i, j;
    char embedstr[2];

    if (embed) {
        strcpy(embedstr, "@");
    } else {
        embedstr[0] = 0;
    }
    for (i = 0; i < MAXREGION; i++) {
      fprintf(pp, "%sr%1d %s\n", embedstr, i, on_or_off(rg[i].active));
      
      fprintf(pp, "%slink r%1d to g%1d\n", embedstr, i, rg[i].linkto);
      
      switch (rg[i].type) {
      case REGION_ABOVE:
	fprintf(pp, "%sr%1d type above\n", embedstr, i);
	break;
      case REGION_BELOW:
	fprintf(pp, "%sr%1d type below\n", embedstr, i);
	break;
      case REGION_TOLEFT:
	fprintf(pp, "%sr%1d type left\n", embedstr, i);
	break;
      case REGION_TORIGHT:
	fprintf(pp, "%sr%1d type right\n", embedstr, i);
	break;
      case REGION_POLYI:
	fprintf(pp, "%sr%1d type polyi\n", embedstr, i);
	break;
      case REGION_POLYO:
	fprintf(pp, "%sr%1d type polyo\n", embedstr, i);
	break;
      case REGION_HORIZI:
	fprintf(pp, "%sr%1d type horizi\n", embedstr, i);
	break;
      case REGION_VERTI:
	fprintf(pp,"%sr%1d type verti\n", embedstr, i);
	break;
      case REGION_HORIZO:
	fprintf(pp, "%sr%1d type horizo\n", embedstr, i);
	break;
      case REGION_VERTO:
	fprintf(pp,"%sr%1d type verto\n", embedstr, i);
	break;
      }
      fprintf(pp, "%sr%1d linestyle %d\n", embedstr, i, rg[i].lines);
      fprintf(pp, "%sr%1d linewidth %.1f\n", embedstr, i, rg[i].linew);
      fprintf(pp, "%sr%1d color %d\n", embedstr, i, rg[i].color);
      if (rg[i].type != REGION_POLYI && rg[i].type != REGION_POLYO) {
	fprintf(pp, "%sr%1d line %.12g, %.12g, %.12g, %.12g\n", embedstr, i, rg[i].x1, rg[i].y1, rg[i].x2, rg[i].y2);
      } else {
	if (rg[i].x != NULL) {
	  for (j = 0; j < rg[i].n; j++) {
	    fprintf(pp, "%sr%1d xy %.12g, %.12g\n", embedstr, i, rg[i].x[j], rg[i].y[j]);
	  }
	}
      }
    }
}

void put_fitparms(FILE * pp, int embed)
{
    int i;
    char embedstr[2];

    if (embed) {
        strcpy(embedstr, "@");
    } else {
        embedstr[0] = 0;
    }
    
    fprintf(pp, "# Grace fit description file\n");
    fprintf(pp, "#\n");

    fprintf(pp, "%sfit title \"%s\"\n", embedstr, PSTRING(nonl_opts.title));
    fprintf(pp, "%sfit formula \"%s\"\n", embedstr, PSTRING(nonl_opts.formula));
    fprintf(pp, "%sfit with %1d parameters\n", embedstr, nonl_opts.parnum);
    fprintf(pp, "%sfit prec %g\n", embedstr, nonl_opts.tolerance);
    
    for (i = 0; i < nonl_opts.parnum; i++) {
        fprintf(pp, "%sa%1d = %g\n", embedstr, i, nonl_parms[i].value);
        if (nonl_parms[i].constr) {
            fprintf(pp, "%sa%1d constraints on\n", embedstr, i);
        } else {
            fprintf(pp, "%sa%1d constraints off\n", embedstr, i);
        }
        fprintf(pp, "%sa%1dmin = %g\n", embedstr, i, nonl_parms[i].min);
        fprintf(pp, "%sa%1dmax = %g\n", embedstr, i, nonl_parms[i].max);
    }
}

