/* dia-canvas-textbox.c
 * Copyright (C) 2000  James Henstridge
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include "dia-textbox.h"
#include <diacanvas/dia-canvas-text.h>
#include <diacanvas/dia-canvas-groupable.h>
#include <diacanvas/diamarshal.h>
#include <libart_lgpl/art_affine.h>
#include <diacanvas/dia-canvas-i18n.h>

enum {
	PROP_FONT = 1,
	PROP_TEXT
};

static void dia_textbox_init		(DiaTextbox	*textbox);
static void dia_textbox_class_init	(DiaTextboxClass *klass);
static void dia_textbox_groupable_init	(DiaCanvasGroupableIface *groupable);
static void dia_textbox_dispose		(GObject *object);
static void dia_textbox_update		(DiaCanvasItem *item,
					 gdouble affine[6]);
//static gboolean dia_textbox_event	(DiaCanvasItem *item,
//					 DiaEvent *event);

/* Interface functions: */
static gboolean dia_textbox_groupable_add	(DiaCanvasGroupable *textbox,
						 DiaCanvasItem *item);
static gboolean dia_textbox_groupable_remove	(DiaCanvasGroupable *textbox,
						 DiaCanvasItem *item);
static gboolean dia_textbox_groupable_get_iter	(DiaCanvasGroupable *textbox,
						 DiaCanvasIter *iter);
static gboolean dia_textbox_groupable_next	(DiaCanvasGroupable *textbox,
						 DiaCanvasIter *iter);
static DiaCanvasItem* dia_textbox_groupable_value (DiaCanvasGroupable *textbox,
						 DiaCanvasIter *iter);
static gint dia_textbox_groupable_length	(DiaCanvasGroupable *textbox);
static gint dia_textbox_groupable_pos		(DiaCanvasGroupable *textbox,
						 DiaCanvasItem *item);

static DiaCanvasElementClass *parent_class = NULL;

GType
dia_textbox_get_type (void)
{
	static GType object_type = 0;

	if (!object_type) {
		static const GTypeInfo object_info = {
			sizeof (DiaTextboxClass),
			(GBaseInitFunc) NULL,
			(GBaseFinalizeFunc) NULL,
			(GClassInitFunc) dia_textbox_class_init,
			(GClassFinalizeFunc) NULL,
			(gconstpointer) NULL, /* class_data */
			sizeof (DiaTextbox),
			(guint16) 0, /* n_preallocs */
			(GInstanceInitFunc) dia_textbox_init,
		};
		static const GInterfaceInfo groupable_info = {
			(GInterfaceInitFunc) dia_textbox_groupable_init,
			NULL,
			NULL,
		};
		object_type = g_type_register_static (DIA_TYPE_CANVAS_ELEMENT,
						      "DiaTextbox",
						      &object_info, 0);
		g_type_add_interface_static (object_type,
					     DIA_TYPE_CANVAS_GROUPABLE,
					     &groupable_info);
	}

	return object_type;
}

static void
dia_textbox_class_init (DiaTextboxClass *klass)
{
	GObjectClass *object_class;
	DiaCanvasItemClass *item_class;
 
	object_class = (GObjectClass*) klass;
	item_class = DIA_CANVAS_ITEM_CLASS(klass);

	parent_class = g_type_class_peek_parent (klass);

	object_class->dispose = dia_textbox_dispose;

	item_class->update = dia_textbox_update;
	//item_class->event = dia_textbox_event;

	//item_class->point = dia_textbox_point;
	/*g_object_class_install_property (object_class,
					 PROP_FONT,
					 g_param_spec_boxed ("font",
						_("Font description"),
						_(""),
						PANGO_TYPE_FONT_DESCRIPTION,
						G_PARAM_WRITABLE));
	g_object_class_install_property (object_class,
					 PROP_TEXT,
					 g_param_spec_string ("text",
						_("Text"),
						_("Text to be displayed"),
						NULL,
						G_PARAM_READWRITE));
	*/
}

static void
dia_textbox_groupable_init (DiaCanvasGroupableIface *groupable)
{
	groupable->add = dia_textbox_groupable_add;
	groupable->remove = dia_textbox_groupable_remove;
	groupable->get_iter = dia_textbox_groupable_get_iter;
	groupable->next = dia_textbox_groupable_next;
	groupable->value = dia_textbox_groupable_value;
	groupable->length = dia_textbox_groupable_length;
	groupable->pos = dia_textbox_groupable_pos;
}

static void
dia_textbox_init (DiaTextbox *textbox)
{
	textbox->text = dia_canvas_item_create (DIA_TYPE_CANVAS_TEXT, NULL);
	dia_canvas_item_set_child_of (textbox->text, DIA_CANVAS_ITEM (textbox));
	
	g_message (__FUNCTION__": %p %p %p %p %p", textbox, textbox->text, textbox->text->parent, DIA_CANVAS_ITEM (textbox)->canvas, textbox->text->canvas);
}

static void
dia_textbox_dispose (GObject *object)
{
	DiaTextbox *textbox = (DiaTextbox*) object;

	if (textbox->text) {
		g_object_unref (textbox->text);
		textbox->text = NULL;
	}

	G_OBJECT_CLASS (parent_class)->dispose (object);
}

static void
dia_textbox_update (DiaCanvasItem *item, gdouble affine[6])
{
	DiaTextbox *textbox;
	
	g_return_if_fail(item != NULL);
	g_return_if_fail(DIA_IS_TEXTBOX(item));
	
	//g_message (__FUNCTION__);

	DIA_CANVAS_ITEM_CLASS (parent_class)->update (item, affine);

	textbox = DIA_TEXTBOX(item);
	
	/* update `leafs' */
	//if (DIA_CANVAS_ITEM_NEED_UPDATE (textbox->text)) {
	DIA_CANVAS_TEXT (textbox->text)->width = DIA_CANVAS_ELEMENT (item)->width;
	DIA_CANVAS_TEXT (textbox->text)->height = DIA_CANVAS_ELEMENT (item)->height;
	
	if (DIA_CANVAS_ITEM_GET_CLASS (textbox->text)->update) {
		gdouble a[6];
		art_affine_multiply (a, affine, textbox->text->affine);
		//g_message ("%f %f %f %f %f %f",
		//	   a[0], a[1], a[2],  a[3], a[4], a[5]);
		DIA_CANVAS_ITEM_GET_CLASS (textbox->text)->update (textbox->text, a);
	} else
		g_assert_not_reached ();
	DIA_UNSET_FLAGS (textbox->text, DIA_NEED_UPDATE);
	
	if (DIA_CANVAS_ITEM_VISIBLE (textbox->text)) {
		gdouble x1, x2, y1, y2;

		dia_canvas_item_bb_affine (textbox->text, textbox->text->affine,
					   &x1, &y1, &x2, &y2);

		item->bounds.left = x1;
		item->bounds.top = y1;
		item->bounds.right = x2;
		item->bounds.bottom = y2;
	} else {
		item->bounds.left = item->bounds.top =
		item->bounds.right = item->bounds.bottom = 0.0;
	}
	//g_message (__FUNCTION__": (%f, %f) (%f, %f)", item->bounds.left,
	//		item->bounds.top, item->bounds.right, item->bounds.bottom);
	//g_message (__FUNCTION__": bond: (%f, %f) (%f, %f)",
	//	new_bounds.left, new_bounds.top,
	//	new_bounds.right, new_bounds.bottom);
}

#if 0
static gboolean
dia_textbox_event (DiaCanvasItem *item, DiaEvent *event)
{
	/* Request updates for the text at some events. */
	switch (event->type) {
	case DIA_EVENT_BUTTON_PRESS:
		if (event->button.button == 1) {
			dia_canvas_item_request_update (DIA_TEXTBOX (item)->text);
		}
		break;
	case DIA_EVENT_BUTTON_RELEASE:
		if (DIA_CANVAS_ITEM_GRAB (item)) {
			dia_canvas_item_request_update (DIA_TEXTBOX (item)->text);
		}
		break;
	case DIA_EVENT_MOTION:
		if (DIA_CANVAS_ITEM_GRAB (item)) {
			dia_canvas_item_request_update (DIA_TEXTBOX (item)->text);
		}
	default:
		break;
	}
	return DIA_CANVAS_ITEM_CLASS (parent_class)->event (item, event);
}
#endif

static gboolean
dia_textbox_groupable_add (DiaCanvasGroupable *textbox, DiaCanvasItem *item)
{
	g_return_val_if_fail (DIA_IS_TEXTBOX (textbox), FALSE);

#if 0
	//g_message (__FUNCTION__);
	if ((DIA_TEXTBOX (textbox)->text == NULL)
	    && DIA_IS_CANVAS_TEXT (item)) {
		g_message (__FUNCTION__": Setting text");
		/* The canvas is set by the goupable_add() function. */
		DIA_TEXTBOX (textbox)->text = item;
		item->parent = textbox;
		//item->canvas = textbox->canvas;
		return TRUE;
	}
#endif
	return FALSE;
}

static gboolean
dia_textbox_groupable_remove (DiaCanvasGroupable *textbox, DiaCanvasItem *item)
{
	g_return_val_if_fail (DIA_IS_TEXTBOX (textbox), FALSE);
	return FALSE;
}

static gboolean
dia_textbox_groupable_get_iter (DiaCanvasGroupable *textbox, DiaCanvasIter *iter)
{
	g_return_val_if_fail (DIA_IS_TEXTBOX (textbox),  FALSE);

	iter->data[0] = DIA_TEXTBOX (textbox)->text;
	//g_message (__FUNCTION__": %p", iter->data[0]);

	return TRUE;
}

static gboolean
dia_textbox_groupable_next (DiaCanvasGroupable *textbox, DiaCanvasIter *iter)
{
	g_return_val_if_fail (DIA_IS_TEXTBOX (textbox),  FALSE);

	iter->data[0] = NULL;

	return FALSE;
}

static DiaCanvasItem*
dia_textbox_groupable_value (DiaCanvasGroupable *textbox, DiaCanvasIter *iter)
{
	g_return_val_if_fail (DIA_IS_TEXTBOX (textbox),  NULL);

	return iter->data[0];
}

static gint
dia_textbox_groupable_length (DiaCanvasGroupable *textbox)
{
	g_return_val_if_fail (DIA_IS_TEXTBOX (textbox),  -1);

	return DIA_TEXTBOX (textbox)->text ? 1 : 0;
}

static gint
dia_textbox_groupable_pos (DiaCanvasGroupable *textbox, DiaCanvasItem *item)
{
	g_return_val_if_fail (DIA_IS_TEXTBOX (textbox),  -1);

	return (item == DIA_TEXTBOX (textbox)->text) ? 0 : -1;
}

