/*
 * Purple - Internet Messaging Library
 * Copyright (C) Pidgin Developers <devel@pidgin.im>
 *
 * Purple is the legal property of its developers, whose names are too numerous
 * to list here. Please refer to the COPYRIGHT 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 General Public License as published by the Free
 * Software Foundation; either version 2 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 General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this library; if not, see <https://www.gnu.org/licenses/>.
 */

#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
# error "only <purple.h> may be included directly"
#endif

#ifndef PURPLE_ACCOUNT_SETTINGS_H
#define PURPLE_ACCOUNT_SETTINGS_H

#include <glib.h>

#include "purpleaccountsetting.h"
#include "purpleversion.h"

G_BEGIN_DECLS

#define PURPLE_TYPE_ACCOUNT_SETTINGS (purple_account_settings_get_type())

/**
 * PurpleAccountSettings:
 *
 * A collection of account settings.
 *
 * [class@PurpleAccount] starts with an empty instance which is updated when
 * [property@Account:protocol] is set. To do that,
 * [method@Protocol.get_default_account_settings] is called and the result is
 * merged into the account's settings with
 * [method@AccountSettings.update_settings].
 *
 * When an account is loaded from disk, the loader will create a new instance
 * with the settings from disk and then merge them into the account's settings
 * with [method@AccountSettings.update_settings].
 *
 * There is opportunity here for settings to exist on disk but not in the
 * protocol so it is possible that [property@AccountSetting:label]s could be
 * missing. In this event, the [property@AccountSetting:id] property should be
 * used.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
G_DECLARE_FINAL_TYPE(PurpleAccountSettings, purple_account_settings, PURPLE,
                     ACCOUNT_SETTINGS, GObject)

/**
 * purple_account_settings_add_setting:
 * @setting: (transfer full): the setting to add
 *
 * Adds a setting to the collection.
 *
 * If a setting with the same id already exists, a warning will be output and
 * the setting will be freed.
 *
 * Returns: true if the setting was added successfully.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
gboolean purple_account_settings_add_setting(PurpleAccountSettings *settings, PurpleAccountSetting *setting);

/**
 * purple_account_settings_get_boolean:
 * @id: the id of the setting
 * @fallback: the fallback value
 *
 * Gets the value of a boolean setting.
 *
 * If a non boolean setting exists with @id, @fallback will be returned.
 *
 * Returns: The value of the boolean if found, otherwise @fallback.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
gboolean purple_account_settings_get_boolean(PurpleAccountSettings *settings, const char *id, gboolean fallback);

/**
 * purple_account_settings_get_int:
 * @id: the id of the setting
 * @fallback: the fallback value
 *
 * Gets the value of an integer setting.
 *
 * If a non integer setting exists with @id, @fallback will be returned.
 *
 * Returns: The value of the integer if found, otherwise @fallback.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
int purple_account_settings_get_int(PurpleAccountSettings *settings, const char *id, int fallback);

/**
 * purple_account_settings_get_string:
 * @id: the id of the setting
 * @fallback: the fallback value
 *
 * Gets the value of a string setting.
 *
 * If a non string setting exists with @id, @fallback will be returned.
 *
 * Returns: (nullable): The value of the string if found, otherwise @fallback.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
const char *purple_account_settings_get_string(PurpleAccountSettings *settings, const char *id, const char *fallback);

/**
 * purple_account_settings_new:
 *
 * Creates a new instance.
 *
 * Returns: (transfer full): The new instance.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
PurpleAccountSettings *purple_account_settings_new(void);

/**
 * purple_account_settings_remove_setting:
 * @id: the id of the setting
 *
 * Removes a setting from the collection.
 *
 * Returns: true if the setting was found and removed.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
gboolean purple_account_settings_remove_setting(PurpleAccountSettings *settings, const char *id);

/**
 * purple_account_settings_remove_all_settings:
 *
 * Removes all settings.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_account_settings_remove_all_settings(PurpleAccountSettings *settings);

/**
 * purple_account_settings_set_boolean:
 * @id: the id of the setting
 * @value: the new value
 *
 * Sets the value of a boolean setting if found.
 *
 * If a setting is not found with the id or the setting is of a different type
 * this does nothing.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_account_settings_set_boolean(PurpleAccountSettings *settings, const char *id, gboolean value);

/**
 * purple_account_settings_set_int:
 * @id: the id of the setting
 * @value: the new value
 *
 * Sets the value of a integer setting if found.
 *
 * If a setting is not found with the id or the setting is of a different type
 * this does nothing.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_account_settings_set_int(PurpleAccountSettings *settings, const char *id, int value);

/**
 * purple_account_settings_set_string:
 * @id: the id of the setting
 * @value: the new value
 *
 * Sets the value of a string setting if found.
 *
 * If a setting is not found with the id or the setting is of a different type
 * this does nothing.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_account_settings_set_string(PurpleAccountSettings *settings, const char *id, const char *value);

/**
 * purple_account_settings_update_settings:
 * @updates: (transfer none): the settings to update
 *
 * Updates a settings object from another settings object.
 *
 * If an update item has a different type than an existing setting, that
 * setting will not be updated.
 *
 * > Note: The [signal@Gio.ListModel::items-changed] signal will only be
 * emitted for newly added items as that signal is supposed to track changes to
 * the number of items in the list and not changes in the items themselves.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_account_settings_update_settings(PurpleAccountSettings *settings, PurpleAccountSettings *updates);

G_END_DECLS

#endif /* PURPLE_ACCOUNT_SETTINGS_H */
