#include <gtk/gtk.h>
#include <glib/gi18n.h>

GtkListStore *
glade_utils_liststore_from_enum_type (GType    enum_type,
				      gboolean include_empty)
{
	GtkListStore        *store;
	GtkTreeIter          iter;
	GEnumClass          *eclass;
	guint                i;

	eclass = g_type_class_ref (enum_type);

	store = gtk_list_store_new (1, G_TYPE_STRING);

	if (include_empty)
	{
		gtk_list_store_append (store, &iter);
		gtk_list_store_set (store, &iter, 
				    0, _("None"),
				    -1);
	}
	
	for (i = 0; i < eclass->n_values; i++)
	{
		gtk_list_store_append (store, &iter);
		gtk_list_store_set (store, &iter, 
				    0, eclass->values[i].value_nick,
				    -1);
	}

	g_type_class_unref (eclass);

	return store;
}



enum {

	/* Main Data */
	COLUMN_NAME,          /* The title string for PangoAttrType */
	COLUMN_NAME_WEIGHT,   /* For bold names */
	COLUMN_TYPE,          /* The PangoAttrType */
	COLUMN_EDIT_TYPE,     /* The AttrEditType (below) */
	COLUMN_VALUE,         /* The value */
	COLUMN_START,         /* attribute start value */
	COLUMN_END,           /* attribute end value */

	/* Editor renderer related */
	COLUMN_TOGGLE_ACTIVE, /* whether the toggle renderer is being used */
	COLUMN_TOGGLE_DOWN,   /* whether the toggle should be displayed in "downstate" */

	COLUMN_BUTTON_ACTIVE, /* whether the GladeCellRendererButton is to be used (to launch dialogs) */
	COLUMN_TEXT,          /* text attribute value for all text derived renderers */
	COLUMN_TEXT_STYLE,    /* whether to make italic */
	COLUMN_TEXT_FG,       /* forground colour of the text */

	COLUMN_COMBO_ACTIVE,  /* whether the combobox renderer is being used */
	COLUMN_COMBO_MODEL,   /* the model for the dropdown list */

	COLUMN_SPIN_ACTIVE,   /* whether the spin renderer is being used */
	COLUMN_SPIN_DIGITS,   /* How many decimal points to show (used to edit float values) */

	NUM_COLUMNS
};

typedef enum {
	EDIT_TOGGLE = 0,
	EDIT_COMBO,
	EDIT_SPIN,
	EDIT_COLOR,
	EDIT_INVALID
} AttrEditType;

#define ACTIVATE_COLUMN_FROM_TYPE(type)                 \
	((type) == EDIT_TOGGLE ? COLUMN_TOGGLE_ACTIVE : \
	 (type) == EDIT_SPIN ? COLUMN_SPIN_ACTIVE :     \
	 (type) == EDIT_COMBO ? COLUMN_COMBO_ACTIVE: COLUMN_BUTTON_ACTIVE)

static GtkListStore *
get_enum_model_for_combo (PangoAttrType type)
{
	static GtkListStore *style_store = NULL, 
		*weight_store = NULL, *variant_store = NULL,
		*stretch_store = NULL, *gravity_store = NULL,
		*gravity_hint_store = NULL, *default_store = NULL;

	switch (type) 
	{
	case PANGO_ATTR_STYLE:
		if (!style_store)
			style_store = glade_utils_liststore_from_enum_type (PANGO_TYPE_STYLE, TRUE);
		return style_store;

	case PANGO_ATTR_WEIGHT:
		if (!weight_store)
			weight_store = glade_utils_liststore_from_enum_type (PANGO_TYPE_WEIGHT, TRUE);
		return weight_store;

	case PANGO_ATTR_VARIANT:
		if (!variant_store)
			variant_store = glade_utils_liststore_from_enum_type (PANGO_TYPE_VARIANT, TRUE);
		return variant_store;

	case PANGO_ATTR_STRETCH:
		if (!stretch_store)
			stretch_store = glade_utils_liststore_from_enum_type (PANGO_TYPE_STRETCH, TRUE);
		return stretch_store;

	case PANGO_ATTR_GRAVITY:	
		if (!gravity_store)
			gravity_store = glade_utils_liststore_from_enum_type (PANGO_TYPE_GRAVITY, TRUE);
		return gravity_store;

	case PANGO_ATTR_GRAVITY_HINT:
		if (!gravity_hint_store)
			gravity_hint_store = glade_utils_liststore_from_enum_type (PANGO_TYPE_GRAVITY_HINT, TRUE);
		return gravity_hint_store;

	default:
		if (!default_store)
			default_store = gtk_list_store_new (1, G_TYPE_STRING);
		return default_store;
	}
}

static gboolean
append_empty_row (GtkListStore   *store,
		  PangoAttrType   type)
{
	const gchar *name = NULL;
	GtkListStore *model = get_enum_model_for_combo (type);
	GtkTreeIter   iter;
	AttrEditType  edit_type = EDIT_INVALID;

	switch (type) 
	{
		/* PangoAttrLanguage */
	case PANGO_ATTR_LANGUAGE:
		
		break;
		/* PangoAttrInt */
	case PANGO_ATTR_STYLE:	
		edit_type = EDIT_COMBO;
		name = C_("textattr", "Style");
		break;
	case PANGO_ATTR_WEIGHT:
		edit_type = EDIT_COMBO;
		name = C_("textattr", "Weight");
		break;
	case PANGO_ATTR_VARIANT:
		edit_type = EDIT_COMBO;
		name = C_("textattr", "Variant");
		break;
	case PANGO_ATTR_STRETCH:
		edit_type = EDIT_COMBO;
		name = C_("textattr", "Stretch");
		break;
	case PANGO_ATTR_UNDERLINE:
		edit_type = EDIT_TOGGLE;
		name = C_("textattr", "Underline");
		break;
	case PANGO_ATTR_STRIKETHROUGH:	
		edit_type = EDIT_TOGGLE;
		name = C_("textattr", "Strikethrough");
		break;
	case PANGO_ATTR_GRAVITY:
		edit_type = EDIT_COMBO;
		name = C_("textattr", "Gravity");
		break;
	case PANGO_ATTR_GRAVITY_HINT:
		edit_type = EDIT_COMBO;
		name = C_("textattr", "Gravity Hint");
		break;
		
		/* PangoAttrString */	  
	case PANGO_ATTR_FAMILY:
		/* Use a simple editable text renderer ? */
		break;
		
		/* PangoAttrSize */	  
	case PANGO_ATTR_SIZE:
		edit_type = EDIT_SPIN;
		name = C_("textattr", "Size");
		break;
	case PANGO_ATTR_ABSOLUTE_SIZE:
		edit_type = EDIT_SPIN;
		name = C_("textattr", "Absolute Size");
		break;
					
		/* PangoAttrColor */
		/* Colours need editors... */
	case PANGO_ATTR_FOREGROUND:
		edit_type = EDIT_COLOR;
		name = C_("textattr", "Foreground Color");
		break;
	case PANGO_ATTR_BACKGROUND: 
		edit_type = EDIT_COLOR;
		name = C_("textattr", "Background Color");
		break;
	case PANGO_ATTR_UNDERLINE_COLOR:
		edit_type = EDIT_COLOR;
		name = C_("textattr", "Underline Color");
		break;
	case PANGO_ATTR_STRIKETHROUGH_COLOR:
		edit_type = EDIT_COLOR;
		name = C_("textattr", "Strikethrough Color");
		break;
		
		/* PangoAttrShape */
	case PANGO_ATTR_SHAPE:
		/* Unsupported for now */
		break;
		/* PangoAttrFloat */
	case PANGO_ATTR_SCALE:
		edit_type = EDIT_SPIN;
		name = C_("textattr", "Scale");	
		break;
		
	case PANGO_ATTR_INVALID:
	case PANGO_ATTR_LETTER_SPACING:
	case PANGO_ATTR_RISE:
	case PANGO_ATTR_FALLBACK:
	case PANGO_ATTR_FONT_DESC:
	default:
		break;
	}

	if (name)
	{
		gtk_list_store_append (store, &iter);

		gtk_list_store_set (store, &iter,
				    COLUMN_TOGGLE_ACTIVE, FALSE,
				    COLUMN_SPIN_ACTIVE, FALSE,
				    COLUMN_COMBO_ACTIVE, FALSE,
				    COLUMN_BUTTON_ACTIVE, FALSE,
				    -1);

		gtk_list_store_set (store, &iter,
				    COLUMN_NAME, name,
				    COLUMN_TYPE, type,
				    COLUMN_EDIT_TYPE, edit_type,
				    COLUMN_NAME_WEIGHT, PANGO_WEIGHT_NORMAL,
				    COLUMN_TEXT, _("<Enter Value>"),
				    COLUMN_TEXT_STYLE, PANGO_STYLE_ITALIC,
				    COLUMN_TEXT_FG, "Grey",
				    COLUMN_COMBO_MODEL, model,
				    ACTIVATE_COLUMN_FROM_TYPE (edit_type), TRUE,
				    -1);
		return TRUE;
	}
	return FALSE;
}

static GtkWidget *
glade_eprop_attrs_view (void)
{
	GtkWidget         *view_widget;
 	GtkCellRenderer   *renderer;
	GtkTreeViewColumn *column;
	GtkAdjustment     *adjustment;
	GtkTreeModel      *model;
	
	model = (GtkTreeModel *)gtk_list_store_new
		(NUM_COLUMNS,
		 /* Main Data */
		 G_TYPE_STRING,  // COLUMN_NAME
		 G_TYPE_INT,     // COLUMN_NAME_WEIGHT
		 G_TYPE_INT,     // COLUMN_TYPE
		 G_TYPE_INT,     // COLUMN_EDIT_TYPE
		 G_TYPE_POINTER, // COLUMN_VALUE
		 G_TYPE_UINT,    // COLUMN_START
		 G_TYPE_UINT,    // COLUMN_END
		 /* Editor renderer related */
		 G_TYPE_BOOLEAN, // COLUMN_TOGGLE_ACTIVE
		 G_TYPE_BOOLEAN, // COLUMN_TOGGLE_DOWN
		 G_TYPE_BOOLEAN, // COLUMN_BUTTON_ACTIVE
		 G_TYPE_STRING,  // COLUMN_TEXT
		 G_TYPE_INT,     // COLUMN_TEXT_STYLE
		 G_TYPE_STRING,  // COLUMN_TEXT_FG
		 G_TYPE_BOOLEAN, // COLUMN_COMBO_ACTIVE
		 GTK_TYPE_LIST_STORE, // COLUMN_COMBO_MODEL
		 G_TYPE_BOOLEAN, // COLUMN_SPIN_ACTIVE
		 G_TYPE_UINT);   // COLUMN_SPIN_DIGITS

	view_widget = gtk_tree_view_new_with_model (model);
	gtk_tree_view_set_show_expanders (GTK_TREE_VIEW (view_widget), FALSE);
	gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view_widget), FALSE);

	/********************* attribute name column *********************/
 	renderer = gtk_cell_renderer_text_new ();
	g_object_set (G_OBJECT (renderer), "editable", FALSE, NULL);
	column = gtk_tree_view_column_new_with_attributes
		(_("Attribute"),  renderer, 
		 "text", COLUMN_NAME, 
		 "weight", COLUMN_NAME_WEIGHT,
		 NULL);

	gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
 	gtk_tree_view_append_column (GTK_TREE_VIEW (view_widget), column);

	/********************* attribute value column *********************/
	column = gtk_tree_view_column_new ();
	gtk_tree_view_column_set_title (column, _("Value"));

	/* Toggle renderer */
 	renderer = gtk_cell_renderer_toggle_new ();
	gtk_tree_view_column_pack_start (column, renderer, FALSE);
	gtk_tree_view_column_set_attributes (column, renderer, 
					     "activatable", COLUMN_TOGGLE_ACTIVE,
					     "visible", COLUMN_TOGGLE_ACTIVE,
					     "active", COLUMN_TOGGLE_DOWN,
					     NULL);
/* 	g_signal_connect (G_OBJECT (renderer), "toggled", */
/* 			  G_CALLBACK (value_toggled), eprop); */


	/* Button renderer */
/*  	renderer = glade_cell_renderer_button_new (); */
/* 	g_object_set (G_OBJECT (renderer), "entry-editable", FALSE, NULL); */
/* 	gtk_tree_view_column_pack_start (column, renderer, FALSE); */
/* 	gtk_tree_view_column_set_attributes (column, renderer,  */
/* 					     "editable", COLUMN_BUTTON_ACTIVE, */
/* 					     "visible", COLUMN_BUTTON_ACTIVE, */
/* 					     "text", COLUMN_TEXT, */
/* 					     "style", COLUMN_TEXT_STYLE, */
/* 					     "foreground", COLUMN_TEXT_FG, */
/* 					     NULL); */
/* 	g_signal_connect (G_OBJECT (renderer), "clicked", */
/* 			  G_CALLBACK (value_button_clicked), eprop); */

	/* Combo renderer */
 	renderer = gtk_cell_renderer_combo_new ();
	g_object_set (G_OBJECT (renderer), "text-column", 0, "has-entry", FALSE, NULL);
	gtk_tree_view_column_pack_start (column, renderer, TRUE);
	gtk_tree_view_column_set_attributes (column, renderer, 
					     "editable", COLUMN_COMBO_ACTIVE,
					     "visible", COLUMN_COMBO_ACTIVE,
					     "model", COLUMN_COMBO_MODEL,
					     "text", COLUMN_TEXT,
					     "style", COLUMN_TEXT_STYLE,
					     "foreground", COLUMN_TEXT_FG,
					     NULL);
/* 	g_signal_connect (G_OBJECT (renderer), "edited", */
/* 			  G_CALLBACK (value_combo_spin_edited), eprop); */


	/* Spin renderer */
 	renderer = gtk_cell_renderer_spin_new ();
	adjustment = (GtkAdjustment *)gtk_adjustment_new (0, -G_MAXDOUBLE, G_MAXDOUBLE, 100, 100, 100);
	g_object_set (G_OBJECT (renderer), "adjustment", adjustment, NULL);
	gtk_tree_view_column_pack_start (column, renderer, TRUE);
	gtk_tree_view_column_set_attributes (column, renderer, 
					     "visible", COLUMN_SPIN_ACTIVE,
					     "editable", COLUMN_SPIN_ACTIVE,
					     "text", COLUMN_TEXT,
					     "style", COLUMN_TEXT_STYLE,
					     "foreground", COLUMN_TEXT_FG,
					     "digits", COLUMN_SPIN_DIGITS,
					     NULL);
/* 	g_signal_connect (G_OBJECT (renderer), "edited", */
/* 			  G_CALLBACK (value_combo_spin_edited), eprop); */

	gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
 	gtk_tree_view_append_column (GTK_TREE_VIEW (view_widget), column);

	return view_widget;
}

static void
glade_eprop_attrs_populate_view (GtkTreeView         *view)
{
	GtkListStore       *model = (GtkListStore *)gtk_tree_view_get_model (view);

	append_empty_row (model, PANGO_ATTR_LANGUAGE);
	append_empty_row (model, PANGO_ATTR_STYLE);
	append_empty_row (model, PANGO_ATTR_WEIGHT);
	append_empty_row (model, PANGO_ATTR_VARIANT);
	append_empty_row (model, PANGO_ATTR_STRETCH);
	append_empty_row (model, PANGO_ATTR_UNDERLINE);
	append_empty_row (model, PANGO_ATTR_STRIKETHROUGH);
	append_empty_row (model, PANGO_ATTR_GRAVITY);
	append_empty_row (model, PANGO_ATTR_GRAVITY_HINT);
	append_empty_row (model, PANGO_ATTR_FAMILY);
	append_empty_row (model, PANGO_ATTR_SIZE);
	append_empty_row (model, PANGO_ATTR_ABSOLUTE_SIZE);
	append_empty_row (model, PANGO_ATTR_FOREGROUND);
	append_empty_row (model, PANGO_ATTR_BACKGROUND);
	append_empty_row (model, PANGO_ATTR_UNDERLINE_COLOR);
	append_empty_row (model, PANGO_ATTR_STRIKETHROUGH_COLOR);
	append_empty_row (model, PANGO_ATTR_SHAPE);
	append_empty_row (model, PANGO_ATTR_SCALE);

}

static void
glade_eprop_attrs_show_dialog (void)
{
	GtkWidget        *dialog, *parent, *vbox, *sw, *tree_view;
	gint              res;

	dialog = gtk_dialog_new_with_buttons (_("Setup Text Attributes"),
					      GTK_WINDOW (parent),
					      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
/* 					      GTK_STOCK_CLEAR, GLADE_RESPONSE_CLEAR, */
					      GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
					      GTK_STOCK_OK, GTK_RESPONSE_OK,
					      NULL);

	gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);

	vbox = gtk_vbox_new (FALSE, 6);
	gtk_widget_show (vbox);

	gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);

	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), vbox, TRUE, TRUE, 0);

	sw = gtk_scrolled_window_new (NULL, NULL);
	gtk_widget_show (sw);
	gtk_box_pack_start (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
	gtk_widget_set_size_request (sw, 400, 200);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
					GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);

	tree_view = glade_eprop_attrs_view ();
	glade_eprop_attrs_populate_view (GTK_TREE_VIEW (tree_view));

	gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));

	gtk_widget_show (tree_view);
	gtk_container_add (GTK_CONTAINER (sw), tree_view);

	/* Run the dialog */
	res = gtk_dialog_run (GTK_DIALOG (dialog));
	/* Clean up ...
	 */
	gtk_widget_destroy (dialog);

}


void main (int argc, char *argv[]) { gtk_init(&argc, &argv); glade_eprop_attrs_show_dialog (); }
