/**
 *  File nn_cmd_obj.c for printing obj related commands
 *  Called by ge_obj_apply in ge_obj.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 "graphutils.h"
#include "utils.h"
#include "noxprotos.h"
#include "t1fonts.h"

#include "ng_objects.h"
#include "nn_cmd.h"
#include "nn_tree.h"

extern void gg_cmd_prt (char *buf);

/* c: function to call, v: variable, f: format */
#define NC1(c,v,f) c(&(old->v) ,new->v ,f)
#define NC2(c,v1,v2,f) c(&(old->v1) ,&(old->v2) ,new->v1 ,new->v2 ,f)

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

char *nmt = NULL;

void nn_cmd_obj_prefix (QDobject *new ,char *prefix)
{
  Qtype typ = new->typ;
  int subarc;
  if (typ == Q_TimeStamp) {
    strcpy (prefix ,"@timestamp");
  } else {
    nmt = Qtype_name[typ];
    if (new->typ == Q_Arc){
      subarc = arc_subtyp (new->pmask);
      if (subarc == 1) {
	nmt = "Ellipse";    /* for Grace-5 compatibility */
      } else {
	nmt = "Arc";
      }
    }
    sprintf (prefix ,"@    %s %d " ,nmt ,new->id);
  }
}


/**
 * Print commands reflecting objs parameters
 *  See put_objects  in params.c
 */
void nn_cmd_obj (QDobject *old ,QDobject *new ,int all ,int undo_on)
{
  int gno ,old_gno;
  char prefix[64];
  //12 int subarc;
  Qtype typ = new->typ;
  if (old->typ != typ) {
    errmsg ("nn_cmd_obj internal error: changing type is forbidden");
    return;
  }
  old_gno = old->father_id;
  gno     = obj_get_typed_ancestor_id (new->self ,Q_Graph);

  nn_cmd_all 	    (all);
  nn_cmd_undo_on    (undo_on);
  nn_cmd_undo_start (FALSE ,-1);
  nn_cmd_obj_prefix (new ,prefix);
  nn_cmd_prefix (prefix);
  NC1 (nn_cmd_i       ,layer     ,"%s layer %d\n");
  NC1 (nn_cmd_on_off  ,hidden    ,"%s hidden  %s\n");
  if (typ != Q_TimeStamp) {
    if (gno >= 0) nn_cmd_i (&old_gno ,gno ,"%s g%d\n");
    NC1 (nn_cmd_w_v   ,loctyp    ,"%s loctype %s\n");
  }
  NC1 (nn_cmd_i ,color      	 ,"%s color %d\n");
  if (typ == Q_String || typ == Q_TimeStamp) {
    NC2 (nn_cmd_2d   ,x1 ,y1      ,"%s anchor %.12g , %.12g\n");
    NC1 (nn_cmd_i    ,rot         ,"%s rot %d\n");
    NC1 (nn_cmd_font ,font        ,"%s font %d\n");
    NC1 (nn_cmd_i    ,just        ,"%s just %d\n");
    NC1 (nn_cmd_d    ,charsize    ,"%s char size %f\n");
    NC1 (nn_cmd_i    ,lines       ,"%s linestyle %d\n");
    NC1 (nn_cmd_d    ,linew       ,"%s linewidth %.1f\n");
    NC1 (nn_cmd_i    ,fillcolor   ,"%s fill color %d\n");
    NC1 (nn_cmd_i    ,fillpattern ,"%s fill pattern %d\n");
  } else {
    /* Q_Arc , Q_Box  , Q_Line  , Q_Polyline */
    nn_cmd_4d (&(old->x1) ,&(old->y1) ,&(old->x2) ,&(old->y2)
	       ,new->x1     ,new->y1    ,new->x2    ,new->y2
	       ,"%s : %.12g , %.12g , %.12g , %.12g \n");
    NC1 (nn_cmd_i    ,lines       ,"%s linestyle %d\n");
    NC1 (nn_cmd_d    ,linew       ,"%s linewidth %.1f\n");
    if (typ != Q_Line && typ != Q_Polyline) {
      /* Q_Arc , Q_Box */
      NC1 (nn_cmd_i  ,fillcolor   ,"%s fill color %d\n");
      NC1 (nn_cmd_i  ,fillpattern ,"%s fill pattern %d\n");
      if (typ == Q_Arc && !(new->pmask & MARC_Ellipse)) {
	NC2 (nn_cmd_2i ,astart ,aend ,"%s angles  %d , %d \n");
      }
    }
    if (typ == Q_Line || typ == Q_Polyline ||
	(typ == Q_Arc &&  !(new->pmask & MARC_Ellipse))) {
      NC1 (nn_cmd_i  ,arrow_end   ,"%s arrow %d\n");
      NC1 (nn_cmd_i  ,arrow.type  ,"%s arrow type %d\n");
      NC1 (nn_cmd_d  ,arrow.length,"%s arrow length %f\n");
      NC2 (nn_cmd_2d ,arrow.dL_ff ,arrow.lL_ff ,"%s arrow layout %f, %f\n");
    }
    if (typ == Q_Line) {             /* for label */
      NC1 (nn_cmd_i    ,label_opt   ,"%s label type %d\n");
      NC1 (nn_cmd_i    ,rot         ,"%s rot %d\n");
      NC1 (nn_cmd_font ,font        ,"%s font %d\n");
      NC1 (nn_cmd_i    ,just        ,"%s just %d\n");
      NC1 (nn_cmd_d    ,charsize    ,"%s char size %f\n");
      NC1 (nn_cmd_str  ,frmt        ,"%s label format \"%s\"\n");
      NC2 (nn_cmd_2d   ,perp ,para  ,"%s label offset %g , %g\n");
    } else if (typ == Q_Polyline) {  
      /* always write polyline points (in file only) */
      obj_polyline_write (new->id ,nn_cmd_get_filep ());
    }
  }
  if (new->s != NULL) {
    NC1 (nn_cmd_str ,s ,"%s def \"%s\"\n");
  }
  /* undo/redo */
  if (undo_on) nn_cmd_undo_end (FALSE ,-1);
}


/**
 * Colorbar is a special type of object
 */
void nm_cmd_colorbar  (QDobject *old ,QDobject *new
		       ,Contour *ocontour ,Contour *contour
		       ,int gno ,int setno ,int all ,int undo_on)
{
  char prefix[64];
  sprintf (prefix ,"@ G%1d.s%1d   Colorbar " ,gno ,setno);
  nn_cmd_undo_on    (undo_on);
  nn_cmd_all        (all);
  nn_cmd_undo_start (FALSE ,-1);
  nn_cmd_prefix     (prefix);

  nn_cmd_2d     (&(ocontour->z1) ,&(ocontour->z2) ,contour->z1 ,contour->z2 ,"%s zscale %.12g, %.12g\n");
  nn_cmd_i      (&(ocontour->nticks) ,contour->nticks    ,"%s nticks %d\n");
  NC1 (nn_cmd_i      ,layer    ,"%s layer %d\n");
  NC1 (nn_cmd_on_off ,hidden   ,"%s hidden  %s\n");
  NC1 (nn_cmd_i      ,color    ,"%s color %d\n");
  NC1 (nn_cmd_i      ,lines    ,"%s linestyle %d\n");
  NC1 (nn_cmd_d      ,linew    ,"%s linewidth %.1f\n");
  NC1 (nn_cmd_i      ,just     ,"%s just %d\n");
  NC1 (nn_cmd_font   ,font     ,"%s font %d\n");
  NC1 (nn_cmd_d      ,charsize ,"%s char size %f\n");
  nn_cmd_4d     (&(old->x1) ,&(old->y1) ,&(old->x2) ,&(old->y2)
		 ,new->x1    ,new->y1    ,new->x2    ,new->y2
		 ,"%s : %.12g , %.12g , %.12g , %.12g \n");
  /* undo/redo */
  if (undo_on) nn_cmd_undo_end (FALSE ,-1);
}
