#include <glib-object.h>

typedef struct _Test Test;
typedef struct _TestClass TestClass;

struct _Test {
	GObject parent;
	gint a, b;
};

struct _TestClass {
	GObjectClass parent_class;
};

enum {
	PROP_0,
	PROP_A,
	PROP_B
};

G_DEFINE_TYPE (Test, test, G_TYPE_OBJECT)

static void
test_set_property (GObject *object,
                   guint property_id,
                   const GValue *value,
                   GParamSpec *pspec)
{
	Test *test = (Test *) object;

	switch (property_id) {
		case PROP_A:
			test->a = g_value_get_int (value);
			break;
		case PROP_B:
			test->b = g_value_get_int (value);
			return;
	}

	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}

static void
test_get_property (GObject *object,
                   guint property_id,
                   GValue *value,
                   GParamSpec *pspec)
{
	Test *test = (Test *) object;

	switch (property_id) {
		case PROP_A:
			g_value_set_int (value, test->a);
			break;
		case PROP_B:
			g_value_set_int (value, test->b);
			return;
	}

	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}

static void
test_class_init (TestClass *class)
{
	GObjectClass *object_class;

	object_class = G_OBJECT_CLASS (class);
	object_class->set_property = test_set_property;
	object_class->get_property = test_get_property;

	g_object_class_install_property (
		object_class,
		PROP_A,
		g_param_spec_int (
			"a",
			NULL,
			NULL,
			G_MININT,
			G_MAXINT,
			0,
			G_PARAM_READWRITE));

	g_object_class_install_property (
		object_class,
		PROP_B,
		g_param_spec_int (
			"b",
			NULL,
			NULL,
			G_MININT,
			G_MAXINT,
			0,
			G_PARAM_READWRITE));
}

static void
test_init (Test *test)
{
}

gint
main (gint argc, gchar **argv)
{
	Test *test;

	g_type_init ();

	test = g_object_new (test_get_type (), NULL);

	g_object_bind_property (test, "a", test, "b", G_BINDING_DEFAULT);

	g_object_unref (test);

	return 0;
}
