/*
 * 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_CONTACT_INFO_H
#define PURPLE_CONTACT_INFO_H

#include <glib.h>
#include <glib-object.h>

#include <birb.h>

#include "purplebadges.h"
#include "purpleimage.h"
#include "purplepresence.h"
#include "purpletags.h"
#include "purpleversion.h"

G_BEGIN_DECLS

#define PURPLE_TYPE_CONTACT_INFO (purple_contact_info_get_type())

PURPLE_AVAILABLE_IN_3_0
G_DECLARE_DERIVABLE_TYPE(PurpleContactInfo, purple_contact_info, PURPLE,
                         CONTACT_INFO, GObject)

/**
 * PurpleContactInfoPermission:
 * @PURPLE_CONTACT_INFO_PERMISSION_UNSET: The value is unset.
 * @PURPLE_CONTACT_INFO_PERMISSION_ALLOW: The contact is allowed to contact the
 *                                        user.
 * @PURPLE_CONTACT_INFO_PERMISSION_DENY: The contact is not allowed to contact the
 *                                       user.
 *
 * A representation of whether or not a contact has permission to contact the
 * user.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_TYPE_IN_3_0
typedef enum {
	PURPLE_CONTACT_INFO_PERMISSION_UNSET = 0,
	PURPLE_CONTACT_INFO_PERMISSION_ALLOW,
	PURPLE_CONTACT_INFO_PERMISSION_DENY,
} PurpleContactInfoPermission;

#include "purpleperson.h"

struct _PurpleContactInfoClass {
	/*< private >*/
	GObjectClass parent;

	/*< private >*/
	gpointer reserved[4];
};

/**
 * PurpleContactInfo:
 *
 * The information about a contact. This information is used everywhere you
 * need to refer to a user. Be it a chat, an direct message, a file transfer,
 * etc.
 *
 * Since: 3.0
 */

/**
 * purple_contact_info_new:
 * @id: (nullable): The id of the contact.
 *
 * Creates a new [class@Purple.ContactInfo].
 *
 * If @id is %NULL, an ID will be randomly generated.
 *
 * Returns: (transfer full): The new instance.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
PurpleContactInfo *purple_contact_info_new(const gchar *id);

/**
 * purple_contact_info_get_id:
 * @info: The instance.
 *
 * Gets the id of @info.
 *
 * If a protocol would like to set this, it should call
 * [ctor@GObject.Object.new] and pass in the id attribute manually.
 *
 * Returns: The id of the contact.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
const gchar *purple_contact_info_get_id(PurpleContactInfo *info);

/**
 * purple_contact_info_set_id:
 * @info: The instance.
 * @id: The new identifier.
 *
 * Sets the identifier of @info to @id. Note, this should be used rarely if
 * at all. The main intent of this, is for protocols to update the id of an
 * an account when it is connected if the id is missing.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_id(PurpleContactInfo *info, const char *id);

/**
 * purple_contact_info_get_display_name:
 * @info: The instance.
 *
 * Gets the display name for @info. The display name is typically set by the
 * contact and is handled by the protocol plugin.
 *
 * Returns: (nullable): The display name of @info if one is set, otherwise
 *          %NULL will be returned.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
const gchar *purple_contact_info_get_display_name(PurpleContactInfo *info);

/**
 * purple_contact_info_set_display_name:
 * @info: The instance.
 * @display_name: (nullable): The new displayname.
 *
 * Sets the display name of @info to @display_name.
 *
 * This should primarily only be used by protocol plugins and everyone else
 * should be using [method@Purple.ContactInfo.set_alias].
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_display_name(PurpleContactInfo *info, const gchar *display_name);

/**
 * purple_contact_info_get_alias:
 * @info: The instance.
 *
 * Gets the alias for @info.
 *
 * Returns: (nullable): The alias of @info if one is set, otherwise %NULL.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
const gchar *purple_contact_info_get_alias(PurpleContactInfo *info);

/**
 * purple_contact_info_set_alias:
 * @info: The instance.
 * @alias: (nullable): The new alias.
 *
 * Sets the alias of @info to @alias.
 *
 * Protocol plugins may use this value to synchronize across instances.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_alias(PurpleContactInfo *info, const gchar *alias);

/**
 * purple_contact_info_get_color:
 * @info: The instance.
 *
 * Gets the color that should be used to render this contact info. This is a
 * RGB hex code in a string format.
 *
 * Returns: The RGB hex code.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
const char *purple_contact_info_get_color(PurpleContactInfo *info);

/**
 * purple_contact_info_set_color:
 * @info: The instance.
 * @color: The RGB hex code to set.
 *
 * Sets the color to use when rendering @info to @color.
 *
 * @color should start with a `#` and have a valid number of hex digits
 * following it. Different user interfaces may be able to handle additional
 * precision, but using `#RRGGBB` will have the highest compatibility.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_color(PurpleContactInfo *info, const char *color);

/**
 * purple_contact_info_get_email:
 * @info: The instance.
 *
 * Gets the primary email address from @info.
 *
 * Returns: (nullable): The primary email address or %NULL if not set.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
const char *purple_contact_info_get_email(PurpleContactInfo *info);

/**
 * purple_contact_info_set_email:
 * @info: The instance.
 * @email: (nullable): The new email address.
 *
 * Sets the primary email address for @info.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_email(PurpleContactInfo *info, const char *email);

/**
 * purple_contact_info_get_phone_number:
 * @info: The instance:
 *
 * Gets the primary phone number for the contact.
 *
 * Returns: (nullable): The primary phone number for the contact.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
const char *purple_contact_info_get_phone_number(PurpleContactInfo *info);

/**
 * purple_contact_info_set_phone_number:
 * @info: The instance.
 * @phone_number: (nullable): The new phone number to set.
 *
 * Sets the primary phone number for @info.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_phone_number(PurpleContactInfo *info, const char *phone_number);

/**
 * purple_contact_info_get_time_zone:
 * @info: The instance.
 *
 * Gets the [struct@GLib.TimeZone] for @info.
 *
 * Returns: (transfer none) (nullable): The time zone if set, otherwise %NULL.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
GTimeZone *purple_contact_info_get_time_zone(PurpleContactInfo *info);

/**
 * purple_contact_info_set_time_zone:
 * @info: The instance.
 * @time_zone: (transfer none) (nullable): The new time zone.
 *
 * Sets the time zone of @info to @time_zone.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_time_zone(PurpleContactInfo *info, GTimeZone *time_zone);

/**
 * purple_contact_info_get_note:
 * @info: The instance.
 *
 * Gets the "note" for and @info.
 *
 * Returns: The note.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
const char *purple_contact_info_get_note(PurpleContactInfo *info);

/**
 * purple_contact_info_set_note:
 * @info: The instance.
 * @note: (nullable): The new note.
 *
 * Sets the note for @info to @note.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_note(PurpleContactInfo *info, const char *note);

/**
 * purple_contact_info_get_avatar:
 * @info: The instance.
 *
 * Gets the avatar for @info if one is set.
 *
 * Returns: (transfer none): The avatar if set, otherwise %NULL.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
PurpleImage *purple_contact_info_get_avatar(PurpleContactInfo *info);

/**
 * purple_contact_info_get_avatar_for_display:
 *
 * Get the avatar that should be displayed for this contact info.
 *
 * If [property@ContactInfo:person] is set and its [property@Person:avatar] is
 * set, that will be returned.
 *
 * Otherwise the value of [property@PurpleContactInfo:avatar] will be returned.
 *
 * Returns: (transfer none) (nullable): the avatar.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
PurpleImage *purple_contact_info_get_avatar_for_display(PurpleContactInfo *info);

/**
 * purple_contact_info_get_badges:
 *
 * Gets the badges for this contact info.
 *
 * Returns: (transfer none): The badges.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
PurpleBadges *purple_contact_info_get_badges(PurpleContactInfo *info);

/**
 * purple_contact_info_set_avatar:
 * @info: The instance.
 * @avatar: (nullable): The new avatar to set.
 *
 * Sets the avatar for @info to @avatar. If @avatar is %NULL an existing
 * avatar will be removed.
 *
 * Typically this should only called by the protocol plugin.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_avatar(PurpleContactInfo *info, PurpleImage *avatar);

/**
 * purple_contact_info_get_presence:
 * @info: The instance.
 *
 * Gets the [class@Purple.Presence] for @info.
 *
 * Returns: (transfer none) (nullable): The presence for @info if one is
 *          set, otherwise %NULL.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
PurplePresence *purple_contact_info_get_presence(PurpleContactInfo *info);

/**
 * purple_contact_info_get_tags:
 * @info: The instance.
 *
 * Gets the [class@Purple.Tags] instance for @info.
 *
 * Returns: (transfer none): The tags for @info.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
PurpleTags *purple_contact_info_get_tags(PurpleContactInfo *info);

/**
 * purple_contact_info_set_person:
 * @info: The instance.
 * @person: (nullable): The new [class@Purple.Person] or %NULL.
 *
 * Sets the person that @info belongs to to @person.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_person(PurpleContactInfo *info, PurplePerson *person);

/**
 * purple_contact_info_get_person:
 * @info: The instance.
 *
 * Gets the [class@Purple.Person] that @info belongs to.
 *
 * Returns: (transfer none) (nullable): The [class@Purple.Person] that @info
 *          belongs to, or %NULL.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
PurplePerson *purple_contact_info_get_person(PurpleContactInfo *info);

/**
 * purple_contact_info_get_permission:
 * @info: The instance.
 *
 * Gets the [enum@Purple.ContactInfoPermission] for @info.
 *
 * Returns: The permission for @info.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
PurpleContactInfoPermission purple_contact_info_get_permission(PurpleContactInfo *info);

/**
 * purple_contact_info_set_permission:
 * @info: The instance.
 * @permission: The new permission of the contact.
 *
 * Sets the permission of @info to @permission.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_permission(PurpleContactInfo *info, PurpleContactInfoPermission permission);

/**
 * purple_contact_info_get_sid:
 * @info: The instance.
 *
 * Gets the sid, or secondary id, of @info.
 *
 * Returns: (transfer none) (nullable): The sid if set.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
const char *purple_contact_info_get_sid(PurpleContactInfo *info);

/**
 * purple_contact_info_set_sid:
 * @info: The instance.
 * @sid: (nullable): The sid or secondary id.
 *
 * Sets the sid, or secondary id, of @info to @sid.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_sid(PurpleContactInfo *info, const char *sid);

/**
 * purple_contact_info_get_favorite:
 * @info: The instance.
 *
 * Gets whether or not @info is a favorite or starred contact.
 *
 * Returns: %TRUE if @info is a favorite, otherwise %FALSE.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
gboolean purple_contact_info_get_favorite(PurpleContactInfo *info);

/**
 * purple_contact_info_set_favorite:
 * @info: The instance.
 * @favorite: %TRUE to mark @info as a favorite, otherwise %FALSE.
 *
 * Sets whether or not @info is a favorite.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_favorite(PurpleContactInfo *info, gboolean favorite);

/**
 * purple_contact_info_get_name_for_display:
 * @info: The instance.
 *
 * Gets the name that should be displayed for @info. See
 * [property@Purple.ContactInfo:name-for-display] for more information.
 *
 * Returns: (transfer none): The name to display for @info.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
const char *purple_contact_info_get_name_for_display(PurpleContactInfo *info);

/**
 * purple_contact_info_compare:
 * @a: (nullable): The first instance.
 * @b: (nullable): The second instance.
 *
 * Compares contacts @a and @b
 *
 * Returns: less than 0 if @a should be sorted before @b, 0 if they sorted
 *          equally, and greater than 0 if @a should be sorted after @b.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
int purple_contact_info_compare(PurpleContactInfo *a, PurpleContactInfo *b);

/**
 * purple_contact_info_equal:
 * @a: (nullable): The first instance.
 * @b: (nullable): The second instance.
 *
 * Checks two [class@ContactInfo] objects for equality.
 *
 * Returns: %TRUE if @a and @b are equal, otherwise %FALSE.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
gboolean purple_contact_info_equal(PurpleContactInfo *a, PurpleContactInfo *b);

/**
 * purple_contact_info_matches:
 * @info: The instance.
 * @needle: (nullable): The string to match.
 *
 * This will determine if the alias, display name, or username matches @needle.
 * The id is ignored because generally it is a UUID or hex string which will
 * give very confusing results to end users.
 *
 * If @needle is %NULL or empty string, %TRUE will be returned.
 *
 * Returns: %TRUE if @needle matches any of the above properties, otherwise
 *          %FALSE.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
gboolean purple_contact_info_matches(PurpleContactInfo *info, const char *needle);

/**
 * purple_contact_info_get_menu:
 * @info: The instance.
 *
 * Gets a [class@Birb.ActionMenu] that can be used as a context menu for @info.
 *
 * This will emit the [signal@ContactInfo::populate-menu] signals so that
 * plugins can add additional items. Please note that the order of the menu is
 * not guaranteed.
 *
 * Returns: (transfer full) (nullable): The menu for the contact info or %NULL.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
BirbActionMenu *purple_contact_info_get_menu(PurpleContactInfo *info);

/**
 * purple_contact_info_get_external:
 *
 * Gets whether or not the contact is an external contact.
 *
 * Returns: true if the contact is external to the network.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
gboolean purple_contact_info_get_external(PurpleContactInfo *info);

/**
 * purple_contact_info_set_external:
 * @external: true to make the contact info as external
 *
 * Sets whether or not the contact is considered external.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_external(PurpleContactInfo *info, gboolean external);

/**
 * purple_contact_info_get_created_time:
 *
 * Gets the created time for the contact info.
 *
 * Many protocols expose when an account was created for moderation and other
 * purposes, this field is meant to expose that field, and not when the contact
 * info was added to libpurple.
 *
 * Returns: (transfer none) (nullable): The creation time.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
GDateTime *purple_contact_info_get_created_time(PurpleContactInfo *info);

/**
 * purple_contact_info_set_created_time:
 * @created_time: (transfer none) (nullable): the new creation time
 *
 * Sets the creation time.
 *
 * The creation time is when the contact info was created on the protocol, not
 * when it was added to libpurple.
 *
 * Since: 3.0
 */
PURPLE_AVAILABLE_IN_3_0
void purple_contact_info_set_created_time(PurpleContactInfo *info, GDateTime *created_time);

G_END_DECLS

#endif /* PURPLE_CONTACT_INFO_H */
