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

/* Properties to bind between views and documents */
enum
{
	AUTO_INDENT,
	DRAW_SPACES,
	HIGHLIGHT_CURRENT_LINE,
	INDENT_ON_TAB,
	INDENT_WIDTH,
	INSERT_SPACES_INSTEAD_OF_TABS,
	RIGHT_MARGIN_POSITION,
	SHOW_LINE_MARKS,
	SHOW_LINE_NUMBERS,
	SHOW_RIGHT_MARGIN,
	SMART_HOME_END,
	TAB_WIDTH,
	LAST_PROPERTY
};

static GtkWidget *active_widget = NULL;
static GtkWidget *vbox;
static GtkWidget *view1, *view2, *view3;
static GBinding *bindings1[LAST_PROPERTY];
static GBinding *bindings2[LAST_PROPERTY];


static void
bind (GtkWidget *widget1, GtkWidget *widget2, GBinding **bindings)
{
	/* Bind all properties */
	bindings[AUTO_INDENT] =
		g_object_bind_property (widget1,
					"auto-indent",
					widget2,
					"auto-indent",
					G_BINDING_BIDIRECTIONAL);
	bindings[DRAW_SPACES] =
		g_object_bind_property (widget1,
					"draw-spaces",
					widget2,
					"draw-spaces",
					G_BINDING_BIDIRECTIONAL);
	bindings[HIGHLIGHT_CURRENT_LINE] =
		g_object_bind_property (widget1,
					"highlight-current-line",
					widget2,
					"highlight-current-line",
					G_BINDING_BIDIRECTIONAL);
	bindings[INDENT_ON_TAB] =
		g_object_bind_property (widget1,
					"indent-on-tab",
					widget2,
					"indent-on-tab",
					G_BINDING_BIDIRECTIONAL);
	bindings[INDENT_WIDTH] =
		g_object_bind_property (widget1,
					"indent-width",
					widget2,
					"indent-width",
					G_BINDING_BIDIRECTIONAL);
	bindings[INSERT_SPACES_INSTEAD_OF_TABS] =
		g_object_bind_property (widget1,
					"insert-spaces-instead-of-tabs",
					widget2,
					"insert-spaces-instead-of-tabs",
					G_BINDING_BIDIRECTIONAL);
	bindings[RIGHT_MARGIN_POSITION] =
		g_object_bind_property (widget1,
					"right-margin-position",
					widget2,
					"right-margin-position",
					G_BINDING_BIDIRECTIONAL);
	bindings[SHOW_LINE_MARKS] =
		g_object_bind_property (widget1,
					"show-line-marks",
					widget2,
					"show-line-marks",
					G_BINDING_BIDIRECTIONAL);
	bindings[SHOW_LINE_NUMBERS] =
		g_object_bind_property (widget1,
					"show-line-numbers",
					widget2,
					"show-line-numbers",
					G_BINDING_BIDIRECTIONAL);
	bindings[SHOW_RIGHT_MARGIN] =
		g_object_bind_property (widget1,
					"show-right-margin",
					widget2,
					"show-right-margin",
					G_BINDING_BIDIRECTIONAL);
	bindings[SMART_HOME_END] =
		g_object_bind_property (widget1,
					"smart-home-end",
					widget2,
					"smart-home-end",
					G_BINDING_BIDIRECTIONAL);
	bindings[TAB_WIDTH] =
		g_object_bind_property (widget1,
					"tab-width",
					widget2,
					"tab-width",
					G_BINDING_BIDIRECTIONAL);
}

static void
unbind(GBinding **bindings)
{
	gint i;

	for (i = 0; i < LAST_PROPERTY; i++)
	{
		g_object_unref (bindings[i]);
	}
}

static void
on_button_clicked (GtkWidget *button,
		   gpointer useless)
{
	unbind(bindings1);
	unbind(bindings2);

	bind (view1, view3, bindings1);
}

static GtkWidget *
create_window ()
{
	GtkWidget *window;
	GtkWidget *button;

	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);

	vbox = gtk_vbox_new (FALSE, 0);

	view1 = gtk_source_view_new ();
	gtk_box_pack_start(GTK_BOX (vbox), view1, TRUE, TRUE, 0);

	view2 = gtk_source_view_new ();
	gtk_box_pack_start(GTK_BOX (vbox), view2, TRUE, TRUE, 0);

	bind (view1, view2, bindings1);

	view3 = gtk_source_view_new ();
	gtk_box_pack_start(GTK_BOX (vbox), view3, TRUE, TRUE, 0);

	bind (view2, view3, bindings2);

	gtk_container_add (GTK_CONTAINER (window), vbox);

	button = gtk_button_new_with_label ("Unbind");
	g_signal_connect (button, "clicked",
			  G_CALLBACK (on_button_clicked), NULL);

	gtk_box_pack_end (GTK_BOX (vbox), button , FALSE, FALSE, 0);

	return window;
}

int main ()
{
	GtkWidget *window;

	gtk_init (NULL, NULL);

	window = create_window ();
	gtk_widget_show_all (window);

	gtk_main ();
}
