/* This is -*- C -*- */
/* $Id: guppi-struct.c,v 1.16 2001/10/10 06:48:08 trow Exp $ */

/*
 * guppi-struct.c
 *
 * Copyright (C) 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 <config.h>
#include "guppi-struct.h"

/* #include <gnome.h> */
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-config.h>
#include <libgnome/gnome-i18n.h>

#include <guppi-memory.h>
#include "guppi-struct.h"

static GtkObjectClass *parent_class = NULL;

static void
guppi_struct_finalize (GtkObject *obj)
{
  if (parent_class->finalize)
    parent_class->finalize (obj);
}

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

struct xml_out {
  GuppiData *data;
  GuppiXMLDocument *doc;
  xmlNodePtr node;
};

static void
export_xml_subdata (const gchar *name, GuppiData *subdata, gpointer user_data)
{
  struct xml_out *xo = (struct xml_out *)user_data;
  GtkType type;
  xmlNodePtr subdata_node;

  type = guppi_struct_get_field_type (GUPPI_STRUCT (xo->data), name);

  subdata_node = xmlNewNode (xo->doc->ns, "SubData");
  xmlNewProp (subdata_node, "name", name);
  if (type)
    xmlNewProp (subdata_node, "type", gtk_type_name (type));

  xmlAddChild (subdata_node, guppi_data_export_xml (subdata, xo->doc));

  xmlAddChild (xo->node, subdata_node);
}

static void
export_xml (GuppiData *data, GuppiXMLDocument *doc, xmlNodePtr node)
{
  struct xml_out xo;
  xo.data = data;
  xo.doc = doc;
  xo.node = node;

  guppi_struct_foreach_subdata (GUPPI_STRUCT (data), export_xml_subdata, &xo);
}

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

static void
guppi_struct_class_init (GuppiStructClass *klass)
{
  GtkObjectClass *object_class = (GtkObjectClass *) klass;
  GuppiDataClass *data_class = GUPPI_DATA_CLASS (klass);

  parent_class = gtk_type_class (GUPPI_TYPE_DATA);

  data_class->export_xml = export_xml;

  object_class->finalize = guppi_struct_finalize;
}

static void
guppi_struct_init (GuppiStruct *obj)
{

}

GtkType guppi_struct_get_type (void)
{
  static GtkType guppi_struct_type = 0;
  if (!guppi_struct_type) {
    static const GtkTypeInfo guppi_struct_info = {
      "GuppiStruct",
      sizeof (GuppiStruct),
      sizeof (GuppiStructClass),
      (GtkClassInitFunc) guppi_struct_class_init,
      (GtkObjectInitFunc) guppi_struct_init,
      NULL, NULL, (GtkClassInitFunc) NULL
    };
    guppi_struct_type = gtk_type_unique (GUPPI_TYPE_DATA, &guppi_struct_info);
  }
  return guppi_struct_type;
}

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

GtkType
guppi_struct_get_field_type (const GuppiStruct *gs, const gchar *field)
{
  GuppiStructClass *klass;

  g_return_val_if_fail (GUPPI_IS_STRUCT (gs), (GtkType) 0);
  g_return_val_if_fail (field != NULL, (GtkType) 0);

  klass = GUPPI_STRUCT_CLASS (GTK_OBJECT (gs)->klass);

  g_assert (klass->field_type);
  return klass->field_type ((GuppiStruct *) gs, field);
}

GuppiData *
guppi_struct_get (const GuppiStruct *gs, const gchar *field)
{
  GuppiStructClass *klass;

  g_return_val_if_fail (GUPPI_IS_STRUCT (gs), NULL);
  g_return_val_if_fail (field != NULL, NULL);

  klass = GUPPI_STRUCT_CLASS (GTK_OBJECT (gs)->klass);

  g_assert (klass->get);
  return klass->get ((GuppiStruct *) gs, field);
}

void
guppi_struct_set (GuppiStruct *gs, const gchar *field, GuppiData *data)
{
  GuppiStructClass *klass;
  gboolean success;

  g_return_if_fail (GUPPI_IS_STRUCT (gs));
  g_return_if_fail (field != NULL);

  klass = GUPPI_STRUCT_CLASS (GTK_OBJECT (gs)->klass);

  g_assert (klass->set);
  success = klass->set (gs, field, data);

  if (!success)
    g_warning ("struct set failed - unknown field: %s", field);
}

void
guppi_struct_add_field (GuppiStruct *gs, const gchar *field, GtkType type)
{
  GuppiStructClass *klass;
  gboolean success;

  g_return_if_fail (GUPPI_IS_STRUCT (gs));
  g_return_if_fail (field != NULL);

  klass = GUPPI_STRUCT_CLASS (GTK_OBJECT (gs)->klass);

  g_assert (klass->add_field);
  success = klass->add_field (gs, field, type);
  if (!success)
    g_warning ("struct add failed - field collision: %s", field);
}

void
guppi_struct_add_free_field (GuppiStruct *gs, const gchar *field)
{
  g_return_if_fail (GUPPI_IS_STRUCT (gs));

  guppi_struct_add_field (gs, field, (GtkType) 0);
}

void
guppi_struct_foreach_subdata (GuppiStruct *gs, GuppiStructFn fn, gpointer user_data)
{
  GuppiStructClass *klass;

  g_return_if_fail (GUPPI_IS_STRUCT (gs));
  g_return_if_fail (fn != NULL);

  klass = GUPPI_STRUCT_CLASS (GTK_OBJECT (gs)->klass);
  
  g_assert (klass->foreach);
  klass->foreach (gs, fn, user_data);
}


/* $Id: guppi-struct.c,v 1.16 2001/10/10 06:48:08 trow Exp $ */


syntax highlighted by Code2HTML, v. 0.9.1