/* $Id: demo.c,v 1.10 2002/01/08 06:28:57 trow Exp $ */

/*
 * demo.c
 *
 * Copyright (C) 1999, 2000 EMC Capital Management, Inc.
 * Copyright (C) 2001 The Free Software Foundation
 *
 * Developed by Jon Trowbridge <trow@gnu.org> and
 * Havoc Pennington <hp@pobox.com>.
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

#include <fcntl.h>
#include <math.h>
#include <gnome.h>
#include <glade/glade.h>
#include "guppi-root-group-view.h"
#include "guppi-group-view-layout.h"

#include <guppi-seq-scalar-core.h>
#include <guppi-data-table-core.h>

#include <guppi-memory.h>
#include <guppi-data-socket.h>
#include <guppi-useful.h>
#include <guppi-data-init.h>
#include <guppi-plot-init.h>
#include <guppi-color-palette.h>
#include <guppi-marker.h>
#include <guppi-config-dialog.h>

#include <guppi-group-state.h>
#include <guppi-group-view.h>

GtkWidget *window;
GtkWidget *canvas;
GuppiRootGroupView *root_view;

GuppiElementState *g1_state, *g2_state, *text_state, *bp_state, *ax_state;
GuppiElementView *g1_view, *g2_view, *text_view, *bp_view, *ax_view;

GuppiData *d1, *d2, *d3;

GuppiColorPalette *pal;

const gchar *labels[] = { "This is a demo program for Guppi",
			  "<center>This text element can handle<br/>two lines of text</center>",
			  "A fun number: <rat integer_part=\"112\" numerator=\"10\" denominator=\"32\"/>",
			  "Another fun number: <sci mantissa=\"6.02\" exponent=\"24\"/>",
			  "Fun <scale factor=\"2\">Large</scale> Text!",
			  "<center>Three lines<br/>of text is also<br/>not a problem</center>",
			  "<center>It<br/>is<br/>possible<br/>to<br/>go<br/>a<br/>bit<br/>too<br/>far<br/>though</center>",
			  NULL
};

gint label_index = 0;
guint timeout = 0;
  

static void
init (gint argc, gchar *argv[])
{
  gnome_init ("demo", "0.0", argc, argv);
  glade_gnome_init ();

  guppi_useful_init_without_guile ();
  guppi_data_init ();
  guppi_plot_init ();

  guppi_plug_in_path_set ("../plug-ins");
  guppi_plug_in_spec_find_all ();
}

static gboolean
label_timeout (gpointer foo)
{
  guppi_element_state_set (text_state,
			   "text", labels[label_index],
			   NULL);
  ++label_index;
  if (labels[label_index] == NULL)
    label_index = 0;

  /* guppi_color_palette_set_offset (pal, guppi_color_palette_get_offset (pal) + 1); */

  /*
  guppi_element_view_set_preferred_view (bar_view, GUPPI_X_AXIS);
  guppi_element_view_set_preferred_view (bar_view, GUPPI_Y_AXIS);
  */

  return TRUE;
}

static void
quit (GtkWidget *w, GdkEventAny *ev, gpointer closure)
{
  if (timeout) 
    gtk_timeout_remove (timeout);
  guppi_unref (root_view);
  guppi_unref (g1_state);
  guppi_unref (g2_state);
  guppi_unref (text_state);
  guppi_unref (ax_state);
  guppi_unref (bp_state);
  guppi_unref (g1_view);
  guppi_unref (g2_view);
  guppi_unref (text_view);
  guppi_unref (bp_view);
  guppi_unref (ax_view);
  guppi_unref (d1);
  guppi_unref (d2);
  guppi_unref (d3);
  guppi_unref (pal);

  gtk_widget_destroy (window);

  gtk_main_quit ();
}

static void
build_gui (void)
{
  canvas = (GtkWidget *) guppi_root_group_view_make_canvas (root_view, NULL);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_usize (window, 800, 600);

  gtk_signal_connect (GTK_OBJECT (window),
		      "delete_event",
		      GTK_SIGNAL_FUNC (quit),
		      NULL);

  gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (canvas));
  gtk_widget_show_all (window);
}

/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */

#define DATA_COUNT 250

static GuppiElementView *
build_scatter_demo (void)
{
  GuppiElementState *scatter_state, *frame_state, *x_ax_state, *y_ax_state, *x_bp_state, *y_bp_state;
  GuppiElementView *scatter_view, *frame_view, *x_ax_view, *y_ax_view, *x_bp_view, *y_bp_view;
  GuppiGroupView *group_view;
  GuppiSeqScalar *x_data, *y_data;
  gint i;
  double t, x, y;

  x_data = guppi_seq_scalar_core_new ();
  y_data = guppi_seq_scalar_core_new ();

  for (i=0; i<DATA_COUNT; ++i) {
    t = 2*M_PI*i/(double)DATA_COUNT;
    x = sin (4*t);
    y = cos (3*t);
    guppi_seq_scalar_append (GUPPI_SEQ_SCALAR (x_data), x);
    guppi_seq_scalar_append (GUPPI_SEQ_SCALAR (y_data), y);
  }
 
  scatter_state = guppi_element_state_new ("scatter",
					   "label", "scatter_state",
					   "marker", GUPPI_MARKER_FILLED_TRIANGLE,
					   "size1", 3.0,
					   "x_data", x_data,
					   "y_data", y_data,
					   NULL);
  
  frame_state = guppi_element_state_new ("frame", NULL);
  
  x_ax_state = guppi_element_state_new ("axis",
					"label", "scatter_x_axis",
					"position", GUPPI_SOUTH,
					NULL);

  y_ax_state = guppi_element_state_new ("axis",
					"label", "scatter_y_axis",
					"position", GUPPI_WEST,
					NULL);

  x_bp_state = guppi_element_state_new ("boxplot",
					"label", "scatter_x_boxplot",
					"horizontal", TRUE,
					"data", x_data,
					NULL);

  y_bp_state = guppi_element_state_new ("boxplot",
					"label", "scatter_y_boxplot",
					"horizontal", FALSE,
					"data", y_data,
					NULL);

  scatter_view = guppi_element_view_new (scatter_state, NULL);
  frame_view   = guppi_element_view_new (frame_state, NULL);
  x_ax_view    = guppi_element_view_new (x_ax_state, NULL);
  y_ax_view    = guppi_element_view_new (y_ax_state, NULL);
  x_bp_view    = guppi_element_view_new (x_bp_state, NULL);
  y_bp_view    = guppi_element_view_new (y_bp_state, NULL);

  group_view   = guppi_group_view_new ();

  guppi_group_view_layout_flush_left   (group_view, y_ax_view, 0);
  guppi_group_view_layout_flush_right  (group_view, y_bp_view, 0);
  guppi_group_view_layout_flush_top    (group_view, x_bp_view, 0);
  guppi_group_view_layout_flush_bottom (group_view, x_ax_view, 0);

  guppi_group_view_layout_horizontally_aligned (group_view, y_ax_view, scatter_view, 0);
  guppi_group_view_layout_horizontally_aligned (group_view, scatter_view, y_bp_view, 0);

  guppi_group_view_layout_vertically_aligned (group_view, x_bp_view, scatter_view, 0);
  guppi_group_view_layout_vertically_aligned (group_view, scatter_view, x_ax_view, 0);

  guppi_group_view_layout_same_place (group_view, scatter_view, frame_view);

  guppi_element_view_connect_axis_markers (scatter_view, GUPPI_X_AXIS, x_ax_view, GUPPI_X_AXIS);
  guppi_element_view_connect_axis_markers (scatter_view, GUPPI_Y_AXIS, y_ax_view, GUPPI_Y_AXIS);

  guppi_element_view_connect_view_intervals (scatter_view, GUPPI_X_AXIS, x_ax_view, GUPPI_X_AXIS);
  guppi_element_view_connect_view_intervals (scatter_view, GUPPI_Y_AXIS, y_ax_view, GUPPI_Y_AXIS);
  guppi_element_view_connect_view_intervals (scatter_view, GUPPI_X_AXIS, x_bp_view, GUPPI_X_AXIS);
  guppi_element_view_connect_view_intervals (scatter_view, GUPPI_Y_AXIS, y_bp_view, GUPPI_Y_AXIS);

  guppi_element_view_connect_axis_markers (scatter_view, GUPPI_X_AXIS, frame_view, GUPPI_X_AXIS);
  guppi_element_view_connect_axis_markers (scatter_view, GUPPI_Y_AXIS, frame_view, GUPPI_Y_AXIS);
  guppi_element_view_connect_view_intervals (scatter_view, GUPPI_X_AXIS, frame_view, GUPPI_X_AXIS);
  guppi_element_view_connect_view_intervals (scatter_view, GUPPI_Y_AXIS, frame_view, GUPPI_Y_AXIS);
  


  return GUPPI_ELEMENT_VIEW (group_view);
}

#define DATA_ROWS 5
#define DATA_COLS 3
 
static GuppiElementView *
build_barchart_demo (void)
{
  GuppiElementState *bar_state, *x_ax_state, *y_ax_state, *legend_state;
  GuppiElementView *bar_view, *x_ax_view, *y_ax_view, *legend_view;
  GuppiGroupView *group_view;
  GuppiDataTable *table;
  gint i, j;
  gchar *str;

  table = guppi_data_table_core_new ();
  guppi_data_table_set_dimensions (table, DATA_ROWS, DATA_COLS);
  for (i = 0; i < DATA_ROWS; ++i) {

    str = g_strdup_printf ("Row %d", i);
    guppi_data_table_set_row_label (table, i, str);
    g_free (str);
    
    for (j = 0; j < DATA_COLS; ++j) {

      if (i == 0) {
	str = g_strdup_printf ("Column %d", j);
	guppi_data_table_set_col_label (table, j, str);
	g_free (str);
      }

      guppi_data_table_set_entry (table, i, j, 1 + i + sin ((i+1)*j));
    }
  }

  bar_state = guppi_element_state_new ("barchart",
				       "label", "bar_state",
				       "vertical_bars", FALSE,
				       "data", table,
				       NULL);

  x_ax_state = guppi_element_state_new ("axis",
					"label", "x_ax_state",
					"position", GUPPI_SOUTH,
					NULL);

  y_ax_state = guppi_element_state_new ("axis",
					"label", "y_ax_state",
					"position", GUPPI_WEST,
					NULL);

  legend_state = guppi_element_state_new ("legend",
					  "labels", table,
					  NULL);

  bar_view    = guppi_element_view_new (bar_state, NULL);
  x_ax_view   = guppi_element_view_new (x_ax_state, NULL);
  y_ax_view   = guppi_element_view_new (y_ax_state, NULL);
  legend_view = guppi_element_view_new (legend_state, NULL);

  group_view  = guppi_group_view_new ();

  guppi_group_view_layout_flush_left (group_view, y_ax_view, 0);
  guppi_group_view_layout_horizontally_aligned (group_view, y_ax_view, bar_view, 0);
  guppi_group_view_layout_vertically_aligned (group_view, bar_view, x_ax_view, 0);
  guppi_group_view_layout_flush_bottom (group_view, x_ax_view, 0);
  guppi_group_view_layout_flush_top (group_view, bar_view, 0);
  guppi_group_view_layout_horizontally_adjacent (group_view, bar_view, legend_view, 0);
  guppi_group_view_layout_center_vertically (group_view, legend_view);
  guppi_group_view_layout_flush_right (group_view, legend_view, 0);

  guppi_element_view_connect_axis_markers (bar_view, GUPPI_X_AXIS,
					   x_ax_view, GUPPI_X_AXIS);
  
  guppi_element_view_connect_axis_markers (bar_view, GUPPI_Y_AXIS,
					   y_ax_view, GUPPI_Y_AXIS);

  guppi_element_view_connect_view_intervals (bar_view, GUPPI_X_AXIS,
					     x_ax_view, GUPPI_X_AXIS);
					     
  guppi_element_view_connect_view_intervals (bar_view, GUPPI_Y_AXIS,
					     y_ax_view, GUPPI_Y_AXIS);

  /* a hack */
  guppi_element_view_set_preferred_view (bar_view, GUPPI_X_AXIS);
  guppi_element_view_set_preferred_view (bar_view, GUPPI_Y_AXIS);

  return GUPPI_ELEMENT_VIEW (group_view);
}

/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */

#define LINE_SEQ_LEN 10

static GuppiElementView *
build_linechart_demo (void)
{
  GuppiElementState *line_state, *x_ax_state, *y_ax_state, *legend_state;
  GuppiElementView *line_view, *x_ax_view, *y_ax_view, *legend_view;
  GuppiGroupView *group_view;
  GuppiSeqScalar *seq;
  gint i;

  seq = guppi_seq_scalar_core_new ();

  for (i = 0; i < LINE_SEQ_LEN; ++i)
    guppi_seq_scalar_append (seq, sin (i));

  
  line_state = guppi_element_state_new ("linechart",
					"data", seq,
					NULL);

  x_ax_state = guppi_element_state_new ("axis",
					"label", "x_ax_state",
					"position", GUPPI_SOUTH,
					NULL);

  y_ax_state = guppi_element_state_new ("axis",
					"label", "y_ax_state",
					"position", GUPPI_WEST,
					NULL);

  legend_state = guppi_element_state_new ("legend",
					  NULL);

  line_view    = guppi_element_view_new (line_state, NULL);
  x_ax_view   = guppi_element_view_new (x_ax_state, NULL);
  y_ax_view   = guppi_element_view_new (y_ax_state, NULL);
  legend_view = guppi_element_view_new (legend_state, NULL);

  group_view  = guppi_group_view_new ();

  guppi_group_view_layout_flush_left (group_view, y_ax_view, 0);
  guppi_group_view_layout_horizontally_aligned (group_view, y_ax_view, line_view, 0);
  guppi_group_view_layout_vertically_aligned (group_view, line_view, x_ax_view, 0);
  guppi_group_view_layout_flush_bottom (group_view, x_ax_view, 0);
  guppi_group_view_layout_flush_top (group_view, line_view, 0);
  guppi_group_view_layout_horizontally_adjacent (group_view, line_view, legend_view, 0);
  guppi_group_view_layout_center_vertically (group_view, legend_view);
  guppi_group_view_layout_flush_right (group_view, legend_view, 0);

  guppi_element_view_connect_axis_markers (line_view, GUPPI_X_AXIS,
					   x_ax_view, GUPPI_X_AXIS);
  
  guppi_element_view_connect_axis_markers (line_view, GUPPI_Y_AXIS,
					   y_ax_view, GUPPI_Y_AXIS);


  /* a hack */
  guppi_element_view_set_preferred_view (line_view, GUPPI_X_AXIS);
  guppi_element_view_set_preferred_view (line_view, GUPPI_Y_AXIS);

  return GUPPI_ELEMENT_VIEW (group_view);
}

/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */

static GuppiElementView *
build_pie_demo (void)
{
  GuppiElementState *pie_state;
  GuppiElementView *pie_view;
  GuppiSeqScalar *seq;
  GuppiColorPalette *pal;
  gint i;

  seq = guppi_seq_scalar_core_new ();
  for (i = 0; i < 10; ++i) {
    guppi_seq_scalar_append (GUPPI_SEQ_SCALAR (seq), i+1);
  }

  pal = guppi_color_palette_new ();
  
  pie_state = guppi_element_state_new ("pie",
				       "label", "pie_state",
				       "use_stock_colors", FALSE,
				       "slice_colors", pal,
				       "data", seq,
				       NULL);

  pie_view = guppi_element_view_new (pie_state, NULL);

  return pie_view;
}

static guppi_compass_t compass_pos = GUPPI_NORTH;

static gint
compass_cb (gpointer closure)
{
  GuppiElementState *state = (GuppiElementState *) closure;

  switch (compass_pos) {
  case GUPPI_NORTH:
    compass_pos = GUPPI_WEST;
    break;
  case GUPPI_WEST:
    compass_pos = GUPPI_SOUTH;
    break;
  case GUPPI_SOUTH:
    compass_pos = GUPPI_EAST;
    break;
  case GUPPI_EAST:
    compass_pos = GUPPI_NORTH;
    break;
  default:
  ;
  }

  guppi_element_state_set (state,
			   "position", compass_pos,
			   NULL);

  return TRUE;
}

static GuppiElementView *
build_compass_pie_demo (void)
{
  GuppiElementState *text_state;
  GuppiElementState *compass_box_state;
  GuppiElementView *compass_box_view;
  GuppiElementView *floating_view;
  GuppiElementView *fixed_view;

  text_state = guppi_element_state_new ("text",
					"text", "<center>compass<br/>item</center>",
					NULL);

  compass_box_state = guppi_element_state_new ("compass-box",
					       "position", compass_pos,
					       NULL);
  compass_box_view = guppi_element_view_new (compass_box_state, NULL);

  gtk_timeout_add (2000, compass_cb, compass_box_state);

  floating_view = guppi_element_view_new (text_state, NULL);
  fixed_view = build_pie_demo ();

  guppi_group_view_add (GUPPI_GROUP_VIEW (compass_box_view), floating_view);
  guppi_group_view_add (GUPPI_GROUP_VIEW (compass_box_view), fixed_view);

  return compass_box_view;
}

/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */

static GuppiElementView *
build_image_demo (void)
{
  GuppiElementState *img_state;
  GuppiElementView *img_view;

  img_state = guppi_element_state_new ("image",
				       "filename", "../pixmaps/guppi-splash.png",
				       NULL);
  img_view = guppi_element_view_new (img_state, NULL);

  return img_view;
}

/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */

static void
layout_elements (void)
{
  GuppiGroupView *group;
  GuppiElementView *bar_view = build_barchart_demo ();
  GuppiElementView *scatter_view = build_scatter_demo ();
  GuppiElementView *pie_view = build_compass_pie_demo ();
  GuppiElementView *img_view = build_image_demo ();

  root_view = GUPPI_ROOT_GROUP_VIEW (guppi_root_group_view_new ());
  guppi_root_group_view_set_size (root_view, 72*11, 72*8.5);

  text_state = guppi_element_state_new ("text",
					"label", "text_state",
					"text", "Initial Text",
					NULL);
  text_view = guppi_element_view_new (text_state, NULL);

  /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
  
  group = GUPPI_GROUP_VIEW (root_view);

  guppi_group_view_layout_horizontally_aligned (group, scatter_view, pie_view, 0);
  guppi_group_view_layout_horizontally_aligned (group, pie_view, bar_view, 0);

  guppi_group_view_layout_flush_left (group, scatter_view, 0);
  guppi_group_view_layout_flush_bottom (group, scatter_view, 0);
  guppi_group_view_layout_flush_right (group, bar_view, 0);     
  
  guppi_group_view_layout_same_width (group, scatter_view, pie_view); 
  guppi_group_view_layout_same_width (group, pie_view, bar_view); 
  
  guppi_group_view_layout_flush_top (group, img_view, 0); 
  guppi_group_view_layout_vertically_adjacent (group, img_view, text_view, 0);
  guppi_group_view_layout_center_horizontally (group, img_view);
  guppi_group_view_layout_center_horizontally (group, text_view);

  guppi_group_view_layout_vertically_adjacent (group, text_view, scatter_view, 0); 

  {
    GuppiConfigModel *model;
    GtkWidget *w;

    model = guppi_element_view_make_config_model ((GuppiElementView *) root_view);
    w = guppi_config_dialog_new (model, root_view);
    guppi_unref (model);

    gtk_widget_show (w);
  }
}

int
main (int argc, char *argv[])
{
  gint fd;

  fd = open ("workaround.c", O_RDONLY);
  if (fd == -1) {
    g_print ("For obscure technical reasons, you need to be in the same directory as the\n");
    g_print ("'demo' executable in order for things to work properly.\n");
    exit (0);
  }
  close (fd);
  
  init (argc, argv);
  
  // guppi_memory_trace (TRUE);
  // guppi_set_verbosity (GUPPI_VERBOSE);



#if 0
  g_message ("building data");
  build_data ();

  g_message ("building elements");
  build_elements ();
#endif

  g_message ("laying out elements");
  layout_elements ();

#if 0
  {
    GuppiXMLDocument *doc;
    xmlNodePtr node;

    doc = guppi_xml_document_new ();
    guppi_xml_document_set_root (doc, guppi_element_view_export_xml (root_view, doc));
    guppi_xml_document_write_file (doc, "/tmp/guppi.foo");
    guppi_xml_document_free (doc);
    guppi_unref (root_view);

    doc = guppi_xml_document_read_file ("/tmp/guppi.foo");
    root_view = guppi_element_view_import_xml (doc, guppi_xml_document_get_root (doc));
    guppi_xml_document_free (doc);


    doc = guppi_xml_document_new ();
    guppi_xml_document_set_root (doc, guppi_element_view_export_xml (root_view, doc));
    guppi_xml_document_write_file (doc, "/tmp/guppi.bar");
    guppi_xml_document_free (doc);
  }
#endif

  g_message ("building gui");
  build_gui ();

#if 0
  g_message ("printing");
  guppi_element_view_print_ps_to_file ((GuppiElementView *) root_view, "./demo.ps");
  g_message ("done printing");
#endif
  
  timeout = gtk_timeout_add (3000, label_timeout, NULL);

  gtk_main ();

  return 0;
}




/* $Id: demo.c,v 1.10 2002/01/08 06:28:57 trow Exp $ */


syntax highlighted by Code2HTML, v. 0.9.1