/*
 * 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 "birblocalizedstring.h"

#include "birbstr.h"

struct _BirbLocalizedString {
    GObject parent;

    char *id;
    char *label;
};

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

/******************************************************************************
 * Helpers
 *****************************************************************************/
static void
birb_localized_string_set_id(BirbLocalizedString *str, const char *id) {
    g_return_if_fail(BIRB_IS_LOCALIZED_STRING(str));

    if(g_set_str(&str->id, id)) {
        g_object_notify_by_pspec(G_OBJECT(str), properties[PROP_ID]);
    }
}

static void
birb_localized_string_set_label(BirbLocalizedString *str, const char *label) {
    g_return_if_fail(BIRB_IS_LOCALIZED_STRING(str));

    if(g_set_str(&str->label, label)) {
        g_object_notify_by_pspec(G_OBJECT(str), properties[PROP_LABEL]);
    }
}

/******************************************************************************
 * GObject Implementation
 *****************************************************************************/
G_DEFINE_TYPE(BirbLocalizedString, birb_localized_string, G_TYPE_OBJECT)

static void
birb_localized_string_finalize(GObject *obj) {
    BirbLocalizedString *str = BIRB_LOCALIZED_STRING(obj);

    g_clear_pointer(&str->id, g_free);
    g_clear_pointer(&str->label, g_free);

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

static void
birb_localized_string_get_property(GObject *obj, guint param_id, GValue *value,
                                   GParamSpec *pspec)
{
    BirbLocalizedString *str = BIRB_LOCALIZED_STRING(obj);

    switch(param_id) {
    case PROP_ID:
        g_value_set_string(value, birb_localized_string_get_id(str));
        break;
    case PROP_LABEL:
        g_value_set_string(value, birb_localized_string_get_label(str));
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
        break;
    }
}

static void
birb_localized_string_set_property(GObject *obj, guint param_id,
                                   const GValue *value, GParamSpec *pspec)
{
    BirbLocalizedString *str = BIRB_LOCALIZED_STRING(obj);

    switch(param_id) {
    case PROP_ID:
        birb_localized_string_set_id(str, g_value_get_string(value));
        break;
    case PROP_LABEL:
        birb_localized_string_set_label(str, g_value_get_string(value));
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
        break;
    }
}

static void
birb_localized_string_init(G_GNUC_UNUSED BirbLocalizedString *str) {
}

static void
birb_localized_string_class_init(BirbLocalizedStringClass *klass) {
    GObjectClass *obj_class = G_OBJECT_CLASS(klass);

    obj_class->finalize = birb_localized_string_finalize;
    obj_class->get_property = birb_localized_string_get_property;
    obj_class->set_property = birb_localized_string_set_property;

    /**
     * BirbLocalizedString:id:
     *
     * The id of the string.
     *
     * Since: 0.5
     */
    properties[PROP_ID] = g_param_spec_string(
        "id", NULL, NULL,
        NULL,
        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS |
        G_PARAM_EXPLICIT_NOTIFY);

    /**
     * BirbLocalizedString:label:
     *
     * The localized label to display.
     *
     * Since: 0.5
     */
    properties[PROP_LABEL] = g_param_spec_string(
        "label", NULL, NULL,
        NULL,
        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS |
        G_PARAM_EXPLICIT_NOTIFY);

    g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
}

/******************************************************************************
 * Public API
 *****************************************************************************/
gboolean
birb_localized_string_equal(BirbLocalizedString *str1,
                            BirbLocalizedString *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->id, str2->id);
}

const char *
birb_localized_string_get_id(BirbLocalizedString *str) {
    g_return_val_if_fail(BIRB_IS_LOCALIZED_STRING(str), NULL);

    return str->id;
}

const char *
birb_localized_string_get_label(BirbLocalizedString *str) {
    g_return_val_if_fail(BIRB_IS_LOCALIZED_STRING(str), NULL);

    return str->label;
}

BirbLocalizedString *
birb_localized_string_new(const char *id, const char *label) {
    return g_object_new(
        BIRB_TYPE_LOCALIZED_STRING,
        "id", id,
        "label", label,
        NULL);
}
