/* This is -*- C -*- */
/* vim: set sw=2: */

/*
 * guppi-object-title.c
 *
 * Copyright (C) 2000 EMC Capital Management, Inc.
 * Copyright (C) 2001 Free Software Foundation, Inc.
 *
 * 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-convenient.h>
#include <guppi-group-state.h>
#include <guppi-group-view.h>
#include <guppi-canvas-item.h>
#include <guppi-group-view-layout.h>
#include "guppi-object-title.h"

static GtkObjectClass *parent_class = NULL;

enum {
  ARG_0,
  ARG_ON_TOP,
  ARG_TITLE,
  ARG_SUBTITLE,
  ARG_TITLE_FONT,
  ARG_SUBTITLE_FONT,
  ARG_SUBOBJECT
};

static void
guppi_object_title_set_arg (GtkObject *obj, GtkArg *arg, guint arg_id)
{
  GuppiObjectTitle *tobj = GUPPI_OBJECT_TITLE (obj);

  switch (arg_id) {

  case ARG_ON_TOP:
    tobj->on_top = GTK_VALUE_BOOL (*arg);
    break;

  case ARG_TITLE:
    guppi_free (tobj->title);
    tobj->title = guppi_strdup ((gchar *) GTK_VALUE_POINTER (*arg));
    break;

  case ARG_SUBTITLE:
    guppi_free (tobj->subtitle);
    tobj->subtitle = guppi_strdup ((gchar *) GTK_VALUE_POINTER (*arg));
    break;

  case ARG_TITLE_FONT:
    guppi_refcounting_assign (tobj->title_font,
			      GNOME_FONT (GTK_VALUE_POINTER (*arg)));
    break;

  case ARG_SUBTITLE_FONT:
    guppi_refcounting_assign (tobj->subtitle_font,
			      GNOME_FONT (GTK_VALUE_POINTER (*arg)));
    break;

  case ARG_SUBOBJECT:
    guppi_refcounting_assign (tobj->subobject,
			      GUPPI_OBJECT (GTK_VALUE_POINTER (*arg)));
    guppi_sink (tobj->subobject);
    break;

  default:
    break;
  };
}

static void
guppi_object_title_destroy (GtkObject *obj)
{
  if (parent_class->destroy)
    parent_class->destroy (obj);
}

static void
guppi_object_title_finalize (GtkObject *obj)
{
  GuppiObjectTitle *tobj = GUPPI_OBJECT_TITLE (obj);

  guppi_free (tobj->title);
  guppi_free (tobj->subtitle);

  guppi_unref0 (tobj->title_font);
  guppi_unref0 (tobj->subtitle_font);

  guppi_unref0 (tobj->subobject);

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

static void
update (GuppiObject *obj) 
{
  GuppiObjectTitle *otitle;
  GuppiElementState *title_state;
  GuppiElementState *subtitle_state = NULL;
  
  g_return_if_fail (obj != NULL);
  g_return_if_fail (GUPPI_IS_OBJECT_TITLE (obj));

  otitle = GUPPI_OBJECT_TITLE (obj);
  
  /* FIXME: if the object when built did not have a title or a
     subtitle, they should be created here if there is new title data.
     Right now this isn't done. */



  if (otitle->title_view && otitle->title) {
    title_state = guppi_element_view_state (otitle->title_view);
    
    guppi_element_state_set (title_state,
			     "text", otitle->title,
			     "font", otitle->title_font, 
			     NULL);
  }

  if (otitle->subtitle_view && otitle->subtitle) {
    subtitle_state = guppi_element_view_state (otitle->subtitle_view);
    
    guppi_element_state_set (subtitle_state,
			     "text", otitle->subtitle,
			     "font", otitle->subtitle_font,
			     NULL);
  }
}

static gpointer
build (GuppiObject *obj, double hsize, double vsize)
{
  GuppiObjectTitle *tobj;
  GuppiElementState *grp_state;
  GuppiGroupView *grp_view;
  GuppiElementState *title_state = NULL;
  GuppiElementView *title_view = NULL;
  GuppiElementState *subtitle_state = NULL;
  GuppiElementView *subtitle_view = NULL;

  GuppiElementView *upper_text = NULL;
  GuppiElementView *lower_text = NULL;
  GuppiElementView *subview = NULL;

  const double outer_margin = 3.6;
  const double inner_margin = 3.6;

  tobj = GUPPI_OBJECT_TITLE (obj);

  grp_state = guppi_group_state_new ();
  grp_view = GUPPI_GROUP_VIEW (guppi_element_state_make_view (grp_state));
  guppi_unref0 (grp_state);

  if (tobj->title) {
    title_state = guppi_element_state_new ("text",
					   "text", tobj->title,
					   "font", tobj->title_font, NULL);
    title_view = guppi_element_state_make_view (title_state);
    guppi_unref0 (title_state);
  }

  if (tobj->subtitle) {
    subtitle_state = guppi_element_state_new ("text",
					      "text", tobj->subtitle,
					      "font", tobj->subtitle_font,
					      NULL);
    subtitle_view = guppi_element_state_make_view (subtitle_state);
    guppi_unref0 (subtitle_state);
  }

  g_assert (tobj->subobject);
  subview = guppi_object_view (tobj->subobject);
  g_assert (subview);

  /* do layout */

  guppi_group_view_layout_fill_horizontally (grp_view, subview,
					     outer_margin, outer_margin);


  /* If no titles are specified, the only thing in our group is the
     subobject. */
  if (title_view == NULL || subtitle_view == NULL) {
    guppi_group_view_layout_fill_vertically (grp_view, subview,
					     outer_margin, outer_margin);
    return GUPPI_ELEMENT_VIEW (grp_view);
  }
  
  if (title_view) {
    guppi_group_view_layout_same_horizontal_center (grp_view, title_view, subview);
    upper_text = title_view;
  }

  if (subtitle_view) {
    guppi_group_view_layout_same_horizontal_center (grp_view, subtitle_view, subview);
    lower_text = subtitle_view;
  }

  if (upper_text == NULL)
    upper_text = lower_text;
  if (lower_text == NULL)
    lower_text = upper_text;

  if (upper_text != lower_text)
    guppi_group_view_layout_vertically_adjacent (grp_view,
						 upper_text, lower_text,
						 inner_margin);

  if (tobj->on_top) {
    guppi_group_view_layout_flush_top (grp_view, upper_text, outer_margin);
    guppi_group_view_layout_vertically_adjacent (grp_view,
						 lower_text, subview,
						 inner_margin);
    guppi_group_view_layout_flush_bottom (grp_view, subview, outer_margin);
  } else {
    guppi_group_view_layout_flush_top (grp_view, subview, outer_margin);
    guppi_group_view_layout_vertically_adjacent (grp_view,
						 subview, upper_text,
						 inner_margin);
    guppi_group_view_layout_flush_bottom (grp_view, lower_text, outer_margin);
  }

  tobj->subtitle_view = subtitle_view;
  tobj->title_view = title_view;

  return GUPPI_ELEMENT_VIEW (grp_view);
}

static void
item_init (GuppiObject *obj, GnomeCanvasItem *item)
{
  GuppiObjectTitle *tobj = GUPPI_OBJECT_TITLE (obj);
  GuppiObjectClass *subclass;

  /* Forward the item_init call to any subitems */
  if (tobj->subobject) {
    subclass = GUPPI_OBJECT_CLASS (GTK_OBJECT (tobj->subobject)->klass);
    if (subclass->item_init)
      subclass->item_init (tobj->subobject, item);
  }
}

#define add_arg(str, t, symb) \
gtk_object_add_arg_type("GuppiObjectTitle::" str, t, GTK_ARG_WRITABLE, symb)

static void
guppi_object_title_class_init (GuppiObjectTitleClass *klass)
{
  GtkObjectClass *object_class = (GtkObjectClass *) klass;
  GuppiObjectClass *gobj_class = GUPPI_OBJECT_CLASS (klass);

  parent_class = gtk_type_class (GUPPI_TYPE_OBJECT);

  object_class->set_arg = guppi_object_title_set_arg;
  object_class->destroy = guppi_object_title_destroy;
  object_class->finalize = guppi_object_title_finalize;

  gobj_class->build = build;
  gobj_class->item_init = item_init;
  gobj_class->update = update;

  add_arg ("title", GTK_TYPE_POINTER, ARG_TITLE);
  add_arg ("subtitle", GTK_TYPE_POINTER, ARG_SUBTITLE);
  add_arg ("title_font", GTK_TYPE_POINTER, ARG_TITLE_FONT);
  add_arg ("subtitle_font", GTK_TYPE_POINTER, ARG_SUBTITLE_FONT);
  add_arg ("subobject", GTK_TYPE_POINTER, ARG_SUBOBJECT);
  add_arg ("on_top", GTK_TYPE_BOOL, ARG_ON_TOP);
}

static void
guppi_object_title_init (GuppiObjectTitle *obj)
{
  obj->on_top = TRUE;
  obj->title_font = gnome_font_new ("Helvetica", 20.0);
  obj->subtitle_font = gnome_font_new ("Helvetica", 14.0);
}

GtkType guppi_object_title_get_type (void)
{
  static GtkType guppi_object_title_type = 0;
  if (!guppi_object_title_type) {
    static const GtkTypeInfo guppi_object_title_info = {
      "GuppiObjectTitle",
      sizeof (GuppiObjectTitle),
      sizeof (GuppiObjectTitleClass),
      (GtkClassInitFunc) guppi_object_title_class_init,
      (GtkObjectInitFunc) guppi_object_title_init,
      NULL, NULL, (GtkClassInitFunc) NULL
    };
    guppi_object_title_type =
      gtk_type_unique (GUPPI_TYPE_OBJECT, &guppi_object_title_info);
  }
  return guppi_object_title_type;
}

GtkObject *
guppi_object_title_new (void)
{
  return GTK_OBJECT (guppi_type_new (guppi_object_title_get_type ()));
}


syntax highlighted by Code2HTML, v. 0.9.1