/**
 *  File nn_cmd_set.c for printing set related commands
 *  Called by ge_set_apply in ge_set.c
 *   Copyright (c) 2010 P. Vincent.    See GNU GPL ../LICENCE
 */

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

#include "globals.h"
#include "graphs.h"
#include "utils.h"
#include "noxprotos.h"
#include "t1fonts.h"
#include "ng_objects.h"

#include "nn_cmd.h"

/* Macros: c: function to call , v: variable , f: format  */

/* for QDobject of Q_Set type */
#define NCB(c,v,f) c(&(oobj->v) ,obj.v ,f)
#define NCB2(c,v1,v2,f) c(&(oobj->v1) ,&(oobj->v2) ,obj.v1 ,obj.v2 ,f)
/* for colorbar */
#define NCC(c,v,f) c(&(ocolorbar->v) ,po->v ,f)
#define NCC4(c,v1,v2,v3,v4,f) c(&(ocolorbar->v1) ,&(ocolorbar->v2) ,&(ocolorbar->v3) ,&(ocolorbar->v4) \
				,po->v1 ,po->v2 ,po->v3 ,po->v4 ,f)
/* for plotarr */
#define NCO(c,v,f) c(&(old->v)  ,new.v ,f)
#define NCO2(c,v1,v2,f) c(&(old->v1)  ,&(old->v2) ,new.v1 ,new.v2 ,f)
/* utility */
#define IF3(v1,v2,v3) if (old->v1 != new.v1 || old->v2 != new.v2 || old->v3 != new.v3)

extern void nn_cmd_prt (char *buf);

static char buf[1028];

void nn_cmd_set (int gno ,int setno ,plotarr *old ,QDobject *oobj ,QDobject *ocolorbar
		 ,plotarr new ,QDobject obj ,int all ,int undo_on)
{
  //22    char *buf = malloc (1028);
  //22  
  char prefix[20];
  ZcLabel *zclist;
  QDobject *po;

  nn_cmd_all (all);
  nn_cmd_undo_on (undo_on);
  nn_cmd_undo_start (TRUE ,gno);

  if (follow_me_on) {
    if (all || gno != follow_gno) {
      sprintf (buf, "@ with g%d\n" ,gno);
      nn_cmd_prt (buf);
      follow_gno = gno;
    }
  }
  sprintf (prefix ,"@    s%d" ,setno);
  nn_cmd_prefix (prefix);

  /* Symbols see at params.c 432  */
  NCO (nn_cmd_t_f ,hidden   ,"%s hidden %s\n");
  NCB (nn_cmd_i   ,layer    ,"%s layer %d\n");
  if (all || old->type != new.type) {
    sprintf (buf, "@    s%1d type %s\n" ,setno ,set_types (new.type));
    nn_cmd_prt (buf);
    old->type = new.type;
  }
  NCO (nn_cmd_i ,sym                ,"%s symbol %d\n");
  NCO (nn_cmd_d ,symsize            ,"%s symbol size %f\n");
  NCO (nn_cmd_i ,sympen.color       ,"%s symbol color %d\n");
  NCO (nn_cmd_i ,sympen.pattern     ,"%s symbol pattern %d\n");
  NCO (nn_cmd_i ,symfillpen.color   ,"%s symbol fill color %d\n");
  NCO (nn_cmd_i ,symfillpen.pattern ,"%s symbol fill pattern %d\n");
  NCO (nn_cmd_d ,symlinew           ,"%s symbol linewidth %.1f\n");
  NCO (nn_cmd_i ,symlines           ,"%s symbol linestyle %d\n");
  // the line below is not correct because symchar is declared unsigned char
  // nn_cmd_i    (&(old->symchar)            ,new.symchar            ,"%s symbol char %d\n");
  if (all || old->symchar != new.symchar) {
    sprintf (buf, "@    s%1d symbol char %d\n" ,setno ,new.symchar);
    nn_cmd_prt (buf);
    old->symchar = new.symchar;
  }
  NCO (nn_cmd_font ,charfont        ,"%s symbol char font %d\n");
  NCO (nn_cmd_i    ,symskip         ,"%s symbol skip %d\n");
 
 
  /* Lines see at params.c 447  A METTRE A JOUR */
  if (new.linet == LINE_TYPE_SPLINE) {
    if (new.method == INTERP_XSPLINE) {
      if (all || old->linet != new.linet || old->method != new.method || old->meshlen != new.meshlen
	  || oobj->xspline_s != obj.xspline_s) {
	sprintf (buf, "@  s%1d line type %d , %d , %d , %f\n" 
		 ,setno ,new.linet ,new.method ,new.meshlen ,obj.xspline_s);	
	nn_cmd_prt (buf);	 
	old->linet   	= new.linet;     	 
	old->method  	= new.method;        	 
	old->meshlen 	= new.meshlen;        	 
	oobj->xspline_s = obj.xspline_s;     
      }
    } else if (new.method == INTERP_XYSPLINE) {
      if (all || old->linet != new.linet || old->method != new.method || old->meshlen != new.meshlen
	  || oobj->xspline_s != obj.xspline_s|| oobj->xspline_p != obj.xspline_p) {
	sprintf (buf, "@  s%1d line type %d , %d , %d , %f , %f\n" 
		 ,setno ,new.linet ,new.method ,new.meshlen ,obj.xspline_s ,obj.xspline_p);	
	nn_cmd_prt (buf);	 
	old->linet   	= new.linet; 
	old->method  	= new.method; 
	old->meshlen 	= new.meshlen; 
	oobj->xspline_s = obj.xspline_s; 
	oobj->xspline_p = obj.xspline_p; 
      }
    } else {                          /* INTERP_LINEAR , INTERP_SPLINE , INTERP_ASPLINE */
      IF3 (linet ,method ,meshlen) {
	sprintf (buf, "@  s%1d line type %d , %d , %d\n" ,setno ,new.linet ,new.method ,new.meshlen);	
	nn_cmd_prt (buf);	 
	old->linet   = new.linet;     	 
	old->method  = new.method;        	 
	old->meshlen = new.meshlen;     
      }
    }
  } else {
    NCO (nn_cmd_i ,linet ,"%s line type %d\n");
  }
  NCO (nn_cmd_i      ,lines              ,"%s line linestyle %d\n");
  NCO (nn_cmd_d      ,linew              ,"%s line linewidth %.1f\n");
  NCO (nn_cmd_linecolor ,linepen.color      ,"%s line color %d\n");
  NCO (nn_cmd_i      	,linepen.pattern    ,"%s line pattern %d\n");
  NCO (nn_cmd_i      	,baseline_type      ,"%s baseline type %d\n");
  NCO (nn_cmd_on_off 	,baseline           ,"%s baseline %s\n");
  NCO (nn_cmd_on_off 	,dropline           ,"%s dropline %s\n");
  NCO (nn_cmd_i      	,filltype           ,"%s fill type %d\n");
  NCO (nn_cmd_i      	,fillrule           ,"%s fill rule %d\n");
  NCO (nn_cmd_i      	,setfillpen.color   ,"%s fill color %d\n");
  NCO (nn_cmd_i      	,setfillpen.pattern ,"%s fill pattern %d\n");
  /* annotations see at params.c 466 */
  NCO (nn_cmd_on_off ,avalue.active      ,"%s avalue %s\n");
  NCO (nn_cmd_i      ,avalue.type        ,"%s avalue type %d\n");
  NCO (nn_cmd_d      ,avalue.size        ,"%s avalue char size %f\n");
  NCO (nn_cmd_font   ,avalue.font        ,"%s avalue font %d\n");
  NCO (nn_cmd_i      ,avalue.color       ,"%s avalue color %d\n");
  NCO (nn_cmd_i      ,avalue.angle       ,"%s avalue rot %d\n");
  NCO (nn_cmd_fmt    ,avalue.format      ,"%s avalue format %s\n");
  NCO (nn_cmd_i      ,avalue.prec        ,"%s avalue prec %d\n");
  nn_cmd_strn (64 ,old->avalue.prestr ,new.avalue.prestr ,"%s avalue prepend \"%s\"\n");
  nn_cmd_strn (64 ,old->avalue.appstr ,new.avalue.appstr ,"%s avalue append \"%s\"\n");
  NCO2 (nn_cmd_2d    ,avalue.offset.x ,avalue.offset.y   ,"%s avalue offset %f , %f\n");
  NCO2 (nn_cmd_2i    ,avalue.skip     ,avalue.start      ,"%s avalue skip %d , %d\n");
  /* Errorbars see at params.c 478 */
  NCO (nn_cmd_on_off   ,errbar.active 	   ,"%s errorbar %s\n");
  NCO (nn_cmd_placemnt ,errbar.ptype  	   ,"%s errorbar place %s\n");
  NCO (nn_cmd_i        ,errbar.pen.color   ,"%s errorbar color %d\n");
  NCO (nn_cmd_i        ,errbar.pen.pattern ,"%s errorbar pattern %d\n");
  NCO (nn_cmd_d        ,errbar.barsize     ,"%s errorbar size %f\n");
  NCO (nn_cmd_d        ,errbar.linew       ,"%s errorbar linewidth %.1f\n");
  NCO (nn_cmd_i        ,errbar.lines       ,"%s errorbar linestyle %d\n");
  NCO (nn_cmd_d        ,errbar.riser_linew ,"%s errorbar riser linewidth %.1f\n");
  NCO (nn_cmd_i        ,errbar.riser_lines ,"%s errorbar riser linestyle %d\n");
  NCO (nn_cmd_on_off   ,errbar.arrow_clip  ,"%s errorbar riser clip %s\n");
  NCO (nn_cmd_d        ,errbar.cliplen     ,"%s errorbar riser clip length %f\n");
 
  switch (new.type) {
  case SET_XYVMAP:
    NCB (nn_cmd_i    ,color            ,"%s vmap color %d\n");
    NCB (nn_cmd_d    ,linew	       ,"%s vmap linewidth %f\n");
    NCB (nn_cmd_i    ,lines	       ,"%s vmap linestyle %d\n");
    NCB (nn_cmd_i    ,arrow.type       ,"%s vmap arrow type %d\n");
    NCB (nn_cmd_d    ,arrow.length     ,"%s vmap arrow length %f\n");
    NCB2 (nn_cmd_2d  ,arrow.dL_ff 
	  ,           arrow.lL_ff      ,"%s vmap arrow layout %f, %f\n");
    break;
  case SET_XYCMAP:
    /* xycmap see at params.c 540 */
    NCO (nn_cmd_cmap   ,contour.nmap       ,"%s Cmap \"%s\"\n");
    NCO (nn_cmd_on_off ,contour.hidden     ,"%s Contour hidden %s\n" );
    NCO (nn_cmd_i      ,contour.line_color ,"%s Contour color %d\n" );
    NCO (nn_cmd_d      ,linew              ,"%s Contour linewidth %f\n");
    if (undo_on == FALSE) {                              /* contour labels are excluded of undo/redo */
      zclist = new.contour.zclist;
      while (zclist != NULL) {
	sprintf (buf ,"@    s%1d Contour label %g , %g , %g\n" ,setno ,zclist->x ,zclist->y ,zclist->z);
	nn_cmd_prt (buf);
	zclist = zclist->next;
      }
    }
    NCO2 (nn_cmd_2d ,contour.z1 ,contour.z2 ,"%s Colorbar zscale  %g , %g\n");
    NCO  (nn_cmd_i  ,contour.nticks         ,"%s Colorbar nticks  %d\n");
    /* Colorbar */
    if (ocolorbar != NULL && obj_is_active (obj.child)) {
      sprintf (prefix ,"@ G%1d.s%1d Colorbar " ,gno ,setno);
      nn_cmd_prefix (prefix);
      po = &objs[obj.child];
      NCC4 (nn_cmd_4d ,x1 ,y1 ,x2 ,y2 ,"%s : %.12g , %.12g , %.12g , %.12g\n");
      NCC (nn_cmd_i    ,layer    ,"%s layer %d\n");
      NCC (nn_cmd_t_f  ,hidden   ,"%s hidden %s\n");
      NCC (nn_cmd_i    ,lines    ,"%s linestyle %d\n");
      NCC (nn_cmd_d    ,linew    ,"%s linewidth %f\n");
      NCC (nn_cmd_i    ,color    ,"%s color %d\n");
      NCC (nn_cmd_i    ,just     ,"%s just %d\n");
      NCC (nn_cmd_font ,font     ,"%s font %d\n");
      NCC (nn_cmd_d    ,charsize ,"%s char size %f\n");
    }
  default:
    break;
  }
 
  // is_hotlinked  ??  see params.c 500
 
  sprintf (prefix ,"@    s%d" ,setno);
  nn_cmd_prefix (prefix);
  NCO (nn_cmd_on_off ,legend_on             		      ,"%s legend %s\n");
  nn_cmd_strn (MAX_STRING_LENGTH ,old->lstr     ,new.lstr     ,"%s legend  \"%s\"\n");
  nn_cmd_strn (MAX_STRING_LENGTH ,old->comments ,new.comments ,"%s comment \"%s\"\n");
 
  /* undo/redo */
  nn_cmd_undo_end (TRUE ,gno);
}
