/*
 * 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 library 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 library 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 library; if not, see <https://www.gnu.org/licenses/>.
 */

#include "birbstringobject.h"

#include "birbstr.h"

struct _BirbStringObject {
	GObject parent;

	char *string;
};

enum {
	PROP_0,
	PROP_STRING,
	N_PROPERTIES,
};
static GParamSpec *properties[N_PROPERTIES] = {NULL, };

/******************************************************************************
 * GObject Implementation
 *****************************************************************************/
G_DEFINE_FINAL_TYPE(BirbStringObject, birb_string_object, G_TYPE_OBJECT)

static void
birb_string_object_finalize(GObject *obj) {
	BirbStringObject *str_obj = BIRB_STRING_OBJECT(obj);

	g_clear_pointer(&str_obj->string, g_free);

	G_OBJECT_CLASS(birb_string_object_parent_class)->finalize(obj);
}

static void
birb_string_object_get_property(GObject *obj, guint param_id, GValue *value,
                                GParamSpec *pspec)
{
	BirbStringObject *str_obj = BIRB_STRING_OBJECT(obj);

	switch(param_id) {
	case PROP_STRING:
		g_value_set_string(value, birb_string_object_get_string(str_obj));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
		break;
	}
}

static void
birb_string_object_set_property(GObject *obj, guint param_id,
                                const GValue *value, GParamSpec *pspec)
{
	BirbStringObject *str_obj = BIRB_STRING_OBJECT(obj);

	switch(param_id) {
	case PROP_STRING:
		birb_string_object_set_string(str_obj, g_value_get_string(value));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
		break;
	}
}

static void
birb_string_object_init(G_GNUC_UNUSED BirbStringObject *str_obj) {
}

static void
birb_string_object_class_init(BirbStringObjectClass *klass) {
	GObjectClass *obj_class = G_OBJECT_CLASS(klass);

	obj_class->finalize = birb_string_object_finalize;
	obj_class->get_property = birb_string_object_get_property;
	obj_class->set_property = birb_string_object_set_property;

	/**
	 * BirbStringObject:string:
	 *
	 * The string that is being wrapped.
	 *
	 * Since: 0.3
	 */
	properties[PROP_STRING] = g_param_spec_string(
		"string", NULL, NULL,
		NULL,
		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);

	g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
}

/******************************************************************************
 * Public API
 *****************************************************************************/
gboolean
birb_string_object_equal(BirbStringObject *str1, BirbStringObject *str2) {
	if(str1 == str2) {
		return TRUE;
	}

	if(str1 == NULL && str2 != NULL) {
		return FALSE;
	}

	if(str1 != NULL && str2 == NULL) {
		return FALSE;
	}

	return birb_str_equal(str1->string, str2->string);
}

const char *
birb_string_object_get_string(BirbStringObject *obj) {
	g_return_val_if_fail(BIRB_IS_STRING_OBJECT(obj), NULL);

	return obj->string;
}

BirbStringObject *
birb_string_object_new(const char *str) {
	return g_object_new(BIRB_TYPE_STRING_OBJECT, "string", str, NULL);
}

void
birb_string_object_set_string(BirbStringObject *obj, const char *str) {
	g_return_if_fail(BIRB_IS_STRING_OBJECT(obj));

	if(g_set_str(&obj->string, str)) {
		g_object_notify_by_pspec(G_OBJECT(obj), properties[PROP_STRING]);
	}
}
