/* This is -*- C -*- */
/* vim: set sw=2: */
/* $Id: guppi-gnumeric-plot.c,v 1.1 2001/11/26 20:00:10 trow Exp $ */

/*
 * guppi-gnumeric-plot.c
 *
 * Copyright (C) 2001 The Free Software Foundation
 *
 * Developed by Jon Trowbridge <trow@gnu.org>
 *
 * 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 <config.h>
#include "guppi-gnumeric-plot.h"

#include <guppi-memory.h>

#include <ctype.h>
#include <gal/util/e-xml-utils.h>

static GtkObjectClass *parent_class = NULL;

enum {
  REGENERATED,
  LAST_SIGNAL
};

static guint gup_gnm_plot_signals[LAST_SIGNAL] = { 0 };

static void
gup_gnm_plot_finalize (GtkObject *obj)
{

  guppi_finalized (obj);

  if (parent_class->finalize)
    parent_class->finalize (obj);
}

static void
gup_gnm_plot_class_init (GupGnmPlotClass *klass)
{
  GtkObjectClass *object_class = (GtkObjectClass *)klass;

  parent_class = gtk_type_class (GTK_TYPE_OBJECT);

  object_class->finalize = gup_gnm_plot_finalize;

  gup_gnm_plot_signals[REGENERATED] =
    gtk_signal_new ("regenerated",
                    GTK_RUN_FIRST,
                    object_class->type,
                    GTK_SIGNAL_OFFSET (GupGnmPlotClass, regenerated),
                    gtk_marshal_NONE__POINTER_POINTER, GTK_TYPE_NONE, 2,
		    GTK_TYPE_POINTER, GTK_TYPE_POINTER);

  gtk_object_class_add_signals (object_class, gup_gnm_plot_signals,
                                LAST_SIGNAL);
}

static void
gup_gnm_plot_init (GupGnmPlot *obj)
{

}

GtkType
gup_gnm_plot_get_type (void)
{
  static GtkType gup_gnm_plot_type = 0;
  if (!gup_gnm_plot_type) {
    static const GtkTypeInfo gup_gnm_plot_info = {
      "GupGnmPlot",
      sizeof (GupGnmPlot),
      sizeof (GupGnmPlotClass),
      (GtkClassInitFunc)gup_gnm_plot_class_init,
      (GtkObjectInitFunc)gup_gnm_plot_init,
      NULL, NULL, (GtkClassInitFunc)NULL
    };
    gup_gnm_plot_type = gtk_type_unique (GTK_TYPE_OBJECT, &gup_gnm_plot_info);
  }
  return gup_gnm_plot_type;
}

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

static GHashTable *type_hash = NULL;

void
gup_gnm_plot_register_type (const gchar *name, GtkType type)
{
  GtkType *tp;

  g_return_if_fail (name && *name);
  g_return_if_fail (type);

  if (type_hash == NULL)
    type_hash = g_hash_table_new (g_str_hash, g_str_equal);

  /* We don't worry about collisions for now */
  tp = guppi_new (GtkType, 1);
  *tp = type;
  g_hash_table_insert (type_hash, g_strdup (name), tp);
}

static GupGnmPlot *
gup_gnm_plot_construct_by_name (const gchar *name)
{
  GtkType *tp;

  g_return_val_if_fail (name && *name, NULL);

  if (type_hash == NULL)
    return NULL;

  tp = g_hash_table_lookup (type_hash, name);
  if (tp == NULL)
    return NULL;

  return guppi_type_new (*tp);
}

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

GupGnmPlot *
gup_gnm_plot_new (xmlNode *xml)
{
  GupGnmPlot *plot = NULL;
  xmlNode *type_node;
  xmlChar *type_name;

  g_return_val_if_fail (xml != NULL, NULL);

  type_node = e_xml_get_child_by_name (xml, "Type");
  g_return_val_if_fail (type_node != NULL, NULL);

  type_name = xmlGetProp (type_node, "name");
  g_return_val_if_fail (type_name != NULL, NULL);

  plot = gup_gnm_plot_construct_by_name (type_name);
  
  if (plot) {
    plot->type_name = guppi_strdup (type_name);
    gup_gnm_plot_unserialize (plot, xml);
  }

  xmlFree (type_name);

  return plot;
}

xmlNode *
gup_gnm_plot_serialize (GupGnmPlot *plot)
{
  GupGnmPlotClass *klass;

  g_return_val_if_fail (IS_GUP_GNM_PLOT (plot), NULL);

  klass = GUP_GNM_PLOT_CLASS (GTK_OBJECT (plot)->klass);
  g_return_val_if_fail (klass->serialize != NULL, NULL);

  return klass->serialize (plot);
}

void
gup_gnm_plot_unserialize (GupGnmPlot *plot, xmlNode *xml)
{
  GupGnmPlotClass *klass;
  GuppiRootGroupView *new_rgv, *old_rgv;
  xmlNode *type_node;
  xmlChar *type_name;

  g_return_if_fail (IS_GUP_GNM_PLOT (plot));
  g_return_if_fail (xml != NULL);

  klass = GUP_GNM_PLOT_CLASS (GTK_OBJECT (plot)->klass);
  g_return_if_fail (klass->unserialize != NULL);

  /* Sanity check: make sure the xml we are unserializing has the same
     type as the pre-existing object. */
  type_node = e_xml_get_child_by_name (xml, "Type");
  type_name = xmlGetProp (type_node, "name");
  g_assert (!strcmp (type_name, plot->type_name));
  xmlFree (type_name);

  new_rgv = klass->unserialize (plot, xml);
  g_return_if_fail (new_rgv != NULL);

  old_rgv = plot->rgv;
  plot->rgv = new_rgv;

  gtk_signal_emit (GTK_OBJECT (plot), gup_gnm_plot_signals[REGENERATED], old_rgv, new_rgv);
  guppi_unref (old_rgv);
}

GuppiRootGroupView *
gup_gnm_plot_get_root_group_view (GupGnmPlot *plot)
{
  g_return_val_if_fail (IS_GUP_GNM_PLOT (plot), NULL);

  return plot->rgv;
}

static void
canvas_regen_cb (GupGnmPlot *plot, GuppiRootGroupView *old_view, GuppiRootGroupView *new_view, gpointer closure)
{
  GnomeCanvas *canv = closure;
  GuppiCanvasItem *old_item = gtk_object_get_data (GTK_OBJECT (canv), "item");
  GuppiCanvasItem *new_item;

  if (old_view == new_view)
    return;

  gtk_object_destroy (GTK_OBJECT (old_item));
  new_item = guppi_root_group_view_make_canvas_item (new_view, canv);
  gtk_object_set_data (GTK_OBJECT (canv), "item", new_item);
}

GnomeCanvas *
gup_gnm_plot_make_canvas (GupGnmPlot *plot)
{
  GuppiRootGroupView *rgv;
  GnomeCanvas *canv;
  GuppiCanvasItem *item;

  g_return_val_if_fail (IS_GUP_GNM_PLOT (plot), NULL);

  rgv = gup_gnm_plot_get_root_group_view (plot);
  if (rgv == NULL)
    return NULL;

  canv = guppi_root_group_view_make_canvas (rgv, &item);
  gtk_object_set_data (GTK_OBJECT (canv), "item", item);

  gtk_signal_connect (GTK_OBJECT (plot),
		      "regenerated",
		      GTK_SIGNAL_FUNC (canvas_regen_cb),
		      canv);
  
  return canv;
}

GuppiConfigModel *
gup_gnm_plot_make_config_model (GupGnmPlot *plot)
{
  g_return_val_if_fail (IS_GUP_GNM_PLOT (plot), NULL);

  /* FIXME */

  return NULL;
}


syntax highlighted by Code2HTML, v. 0.9.1