/*
 * Copyright (C) Birb Developers
 *
 * Birb is the legal property of its developers, whose names are too numerous
 * to list here. Please refer to the AUTHORS file distributed with this source
 * distribution
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation; either version 2.1 of the License, or (at your
 * option) any later version.
 *
 * This program 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 Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses/>.
 */

#include <glib.h>

#include <birb.h>

/******************************************************************************
 * Formatter
 *****************************************************************************/
#define TEST_BIRB_TYPE_PANGO_FORMATTER (test_birb_pango_formatter_get_type())
G_DECLARE_FINAL_TYPE(TestBirbPangoFormatter, test_birb_pango_formatter,
                     TEST_BIRB, PANGO_FORMATTER, BirbPangoFormatter)

struct _TestBirbPangoFormatter {
	BirbPangoFormatter parent;

	GString *str;
};

G_DEFINE_FINAL_TYPE(TestBirbPangoFormatter, test_birb_pango_formatter,
                    BIRB_TYPE_PANGO_FORMATTER)

static void
test_birb_pango_formatter_start(BirbPangoFormatter *birb_formatter) {
	TestBirbPangoFormatter *test_formatter = NULL;

	test_formatter = TEST_BIRB_PANGO_FORMATTER(birb_formatter);

	test_formatter->str = g_string_new("");
}

static void
test_birb_pango_formatter_attribute_start(BirbPangoFormatter *birb_formatter,
                                          PangoAttribute *attribute)
{
	TestBirbPangoFormatter *test_formatter = NULL;
	PangoAttrType type;

	test_formatter = TEST_BIRB_PANGO_FORMATTER(birb_formatter);

	type = attribute->klass->type;
	if(type == PANGO_ATTR_WEIGHT) {
		g_string_append(test_formatter->str, "<b>");
	} else if(type == PANGO_ATTR_STYLE) {
		g_string_append(test_formatter->str, "<i>");
	}
}

static void
test_birb_pango_formatter_attribute_end(BirbPangoFormatter *birb_formatter,
                                        PangoAttribute *attribute)
{
	TestBirbPangoFormatter *test_formatter = NULL;
	PangoAttrType type;

	test_formatter = TEST_BIRB_PANGO_FORMATTER(birb_formatter);

	type = attribute->klass->type;
	if(type == PANGO_ATTR_WEIGHT) {
		g_string_append(test_formatter->str, "</b>");
	} else if(type == PANGO_ATTR_STYLE) {
		g_string_append(test_formatter->str, "</i>");
	}
}

static void
test_birb_pango_formatter_text(BirbPangoFormatter *birb_formatter,
                               const char *text)
{
	TestBirbPangoFormatter *test_formatter = NULL;

	test_formatter = TEST_BIRB_PANGO_FORMATTER(birb_formatter);

	g_string_append(test_formatter->str, text);
}

static char *
test_birb_pango_formatter_finish(BirbPangoFormatter *birb_formatter) {
	TestBirbPangoFormatter *test_formatter = NULL;
	char *ret = NULL;

	test_formatter = TEST_BIRB_PANGO_FORMATTER(birb_formatter);

	ret = g_string_free_and_steal(test_formatter->str);
	test_formatter->str = NULL;

	return ret;
}

static void
test_birb_pango_formatter_init(G_GNUC_UNUSED TestBirbPangoFormatter *formatter)
{
}

static void
test_birb_pango_formatter_class_init(TestBirbPangoFormatterClass *klass) {
	BirbPangoFormatterClass *formatter_class = NULL;

	formatter_class = BIRB_PANGO_FORMATTER_CLASS(klass);
	formatter_class->start = test_birb_pango_formatter_start;
	formatter_class->attribute_start =
		test_birb_pango_formatter_attribute_start;
	formatter_class->attribute_end = test_birb_pango_formatter_attribute_end;
	formatter_class->text = test_birb_pango_formatter_text;
	formatter_class->finish = test_birb_pango_formatter_finish;
}

static BirbPangoFormatter *
test_birb_pango_formatter_new(void) {
	return g_object_new(TEST_BIRB_TYPE_PANGO_FORMATTER, NULL);
}

/******************************************************************************
 * Tests
 *****************************************************************************/
static void
test_birb_pango_formatter_plain(void) {
	BirbPangoFormatter *formatter = NULL;
	char *result = NULL;

	formatter = test_birb_pango_formatter_new();

	result = birb_pango_formatter_format(formatter, "plain", NULL);
	g_assert_cmpstr(result, ==, "plain");
	g_clear_pointer(&result, g_free);

	g_assert_finalize_object(formatter);
}

static void
test_birb_pango_formatter_simple(void) {
	BirbPangoFormatter *formatter = NULL;
	PangoAttrList *attrs = NULL;
	PangoAttribute *attr = NULL;
	char *result = NULL;

	formatter = test_birb_pango_formatter_new();

	attrs = pango_attr_list_new();

	attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
	attr->start_index = 4;
	pango_attr_list_insert(attrs, attr);

	attr = pango_attr_style_new(PANGO_STYLE_ITALIC);
	attr->start_index = 8;
	pango_attr_list_insert(attrs, attr);

	result = birb_pango_formatter_format(formatter, "foo bar baz", attrs);
	g_assert_cmpstr(result, ==, "foo <b>bar </b><b><i>baz</i></b>");
	g_clear_pointer(&result, g_free);

	g_assert_finalize_object(formatter);

	g_clear_pointer(&attrs, pango_attr_list_unref);
}

/******************************************************************************
 * Main
 *****************************************************************************/
int
main(int argc, char **argv) {
	g_test_init(&argc, &argv, NULL);

	g_test_set_nonfatal_assertions();

	g_test_add_func("/birb/pango-formatter/plain",
	                test_birb_pango_formatter_plain);
	g_test_add_func("/birb/pango-formatter/simple",
	                test_birb_pango_formatter_simple);

	return g_test_run();
}
