/*****
 NAME
	cwidget.m - source code for CWidget class
 VERSION
	$Id$
 CHANGELOG
	$Log$
 */

#include <coconut/gtk/cwidget.h>
#include <coconut/gtk/devent.h>
#include <coconut/cmemalloc.h>
#include <stdlib.h>

static gint destroy_receiver(GtkWidget * w, gpointer p) ;
static gint delete_receiver(GtkWidget * w, gpointer p) ;
static gint clicked_receiver(GtkWidget * w, gpointer p) ;

#define	OBJECT_PTR	GTK_OBJECT(widget_ptr)

@implementation CWidget 

+ (gfloat) alignToFloat: (align_t) dir
{
	gfloat	align ;
	switch(dir){
	  case align_middle: align = 0.5 ; break ;
	  case align_bottom: align = 1.0 ; break ;
	  default: align = 0.0 ; break ;
	} 
	return align ;
}

+ (align_t) floatToAlign: (gfloat) align
{
	align_t	dir ;
	if(align <= 0.3333)
		dir = align_top ;
	else if(align <= 0.6666)
		dir = align_middle ;
	else
		dir = align_bottom ;
	return dir ;
}

+ (align_t) justificationToAlign: (justification_t) just
{
	align_t		align = align_left ;
	switch(just){
	  case justify_left:	align = align_left ;	break ;
	  case justify_right:	align = align_right ;	break ;
	  case justify_center:	align = align_center ;	break ;
	  case justify_fill:	align = align_left ;	break ;
	}
	return align ;
}

- init
{
	fprintf(stderr, "CWidget class: init method is not supported") ;
	return [super init] ;
}

- initWidget: (widget_t) type widget: (GtkWidget *) widget 
{
	widget_type = type ;
	widget_ptr = widget ;

	/* initialize */
	user_object = nil ;
	SET_SIGNAL(clicked_event, nil, NULL, NULL, NULL) ;

	gtk_object_set_user_data(OBJECT_PTR, (gpointer) self) ;
	gtk_signal_connect_full(OBJECT_PTR, DESTROY_EVENT_STR, 
	  GTK_SIGNAL_FUNC(destroy_receiver), 0, NULL, 0, 0, 0) ;
	gtk_signal_connect_full(OBJECT_PTR, DELETE_EVENT_STR, 
	  GTK_SIGNAL_FUNC(delete_receiver), 0, NULL, 0, 0, 0) ;
	/* gtk_widget_realize(widget_ptr) ; */
	return [super init] ;
}

- (void) dealloc
{
	gtk_widget_destroy(widget_ptr) ;
	[user_object release] ;
	[super dealloc] ;
}

- (widget_t) type
{
	return widget_type ;
}

- (GtkWidget *) widgetPtr
{	
	return widget_ptr ;
}

- (boolean) isContainer
{
	return FALSE ;
}

- (boolean) isDeletable
{
	return TRUE ;
}

- (boolean) isGrowable
{	
	return FALSE ;
}

- (boolean) hasAlign
{
	return FALSE ;
}

- (boolean) hasJustification
{
	return FALSE ;
}

- (boolean) hasDirection
{
	return FALSE ;
}

- (boolean) hasInconsistent
{
	return FALSE ;
}

- (boolean) hasIndicator
{
	return FALSE ;
}

- (boolean) hasPadding
{
	return FALSE ;
}

- (boolean) hasShadow
{
	return FALSE ;
}

- (boolean) hasToggleSwitch
{
	return FALSE ;
}

- (boolean) hasTitle
{
	return FALSE ;
}

- (boolean) hasTextView
{
	return FALSE ;
}

- show
{
	gtk_widget_show(widget_ptr) ;
	return nil ;
}

- hide
{
	gtk_widget_hide(widget_ptr) ;
	return nil ;
}

- connectClickedEvent: (id) obj message: (SEL) msg with: param
{
	if(clicked_event.obj == nil){
		SET_SIGNAL(clicked_event, obj, msg, (void *) self, param) ;
		gtk_signal_connect(OBJECT_PTR, CLICKED_EVENT_STR, 
		  GTK_SIGNAL_FUNC(clicked_receiver), &clicked_event) ;
	} 
	return nil ;
}

- doExitAfterDelete
{
	gtk_signal_connect(OBJECT_PTR, DESTROY_EVENT_STR, 
	  GTK_SIGNAL_FUNC(gtk_main_quit), NULL) ;
	return nil ;
}

- setUserObject: (id) obj
{
	[user_object release] ;
	user_object = obj ; [user_object retain] ;
	return nil ;
}

- getUserObject
{
	return user_object ;
}

@end

static gint destroy_receiver(GtkWidget * w, gpointer p)
{
	[GtkWidget2WidgetObj(w) release] ; 
	return 0 ; 
}

static gint delete_receiver(GtkWidget * w, gpointer p)
{
	/* the return value "0" means, it can be deleted */
	return [GtkWidget2WidgetObj(w) isDeletable] ? 0 : 1 ;
}

static gint clicked_receiver(GtkWidget * w, gpointer p)
{
	id <PWidget> 	dst = GtkWidget2WidgetObj(w) ;
	signal_t *	sig = (signal_t *) p ;
	[sig->obj perform: sig->message with: dst with: sig->param2] ;
	return 0 ;
}

