/* GDBus - GLib D-Bus Library
 *
 * Copyright (C) 2008-2010 Red Hat, Inc.
 *
 * 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 <http://www.gnu.org/licenses/>.
 *
 * Author: David Zeuthen <davidz@redhat.com>
 */

#include "config.h"

#include "gdbusobject.h"
#include "gdbusobjectmanager.h"
#include "gdbusinterface.h"
#include "gdbusutils.h"

#include "glibintl.h"
#include "gmarshal-internal.h"

/**
 * SECTION:gdbusobjectmanager
 * @short_description: Base type for D-Bus object managers
 * @include: gio/gio.h
 *
 * The #GDBusObjectManager type is the base type for service- and
 * client-side implementations of the standardized
 * [org.freedesktop.DBus.ObjectManager](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager)
 * interface.
 *
 * See #GDBusObjectManagerClient for the client-side implementation
 * and #GDBusObjectManagerServer for the service-side implementation.
 */

/**
 * GDBusObjectManager:
 *
 * #GDBusObjectManager is an opaque data structure and can only be accessed
 * using the following functions.
 */

typedef GDBusObjectManagerIface GDBusObjectManagerInterface;
G_DEFINE_INTERFACE (GDBusObjectManager, g_dbus_object_manager, G_TYPE_OBJECT)

enum {
  OBJECT_ADDED,
  OBJECT_REMOVED,
  INTERFACE_ADDED,
  INTERFACE_REMOVED,
  N_SIGNALS
};

static guint signals[N_SIGNALS];

static void
g_dbus_object_manager_default_init (GDBusObjectManagerIface *iface)
{
  /**
   * GDBusObjectManager::object-added:
   * @manager: The #GDBusObjectManager emitting the signal.
   * @object: The #GDBusObject that was added.
   *
   * Emitted when @object is added to @manager.
   *
   * Since: 2.30
   */
  signals[OBJECT_ADDED] =
    g_signal_new (I_("object-added"),
                  G_TYPE_FROM_INTERFACE (iface),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GDBusObjectManagerIface, object_added),
                  NULL,
                  NULL,
                  NULL,
                  G_TYPE_NONE,
                  1,
                  G_TYPE_DBUS_OBJECT);

  /**
   * GDBusObjectManager::object-removed:
   * @manager: The #GDBusObjectManager emitting the signal.
   * @object: The #GDBusObject that was removed.
   *
   * Emitted when @object is removed from @manager.
   *
   * Since: 2.30
   */
  signals[OBJECT_REMOVED] =
    g_signal_new (I_("object-removed"),
                  G_TYPE_FROM_INTERFACE (iface),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GDBusObjectManagerIface, object_removed),
                  NULL,
                  NULL,
                  NULL,
                  G_TYPE_NONE,
                  1,
                  G_TYPE_DBUS_OBJECT);

  /**
   * GDBusObjectManager::interface-added:
   * @manager: The #GDBusObjectManager emitting the signal.
   * @object: The #GDBusObject on which an interface was added.
   * @interface: The #GDBusInterface that was added.
   *
   * Emitted when @interface is added to @object.
   *
   * This signal exists purely as a convenience to avoid having to
   * connect signals to all objects managed by @manager.
   *
   * Since: 2.30
   */
  signals[INTERFACE_ADDED] =
    g_signal_new (I_("interface-added"),
                  G_TYPE_FROM_INTERFACE (iface),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GDBusObjectManagerIface, interface_added),
                  NULL,
                  NULL,
                  _g_cclosure_marshal_VOID__OBJECT_OBJECT,
                  G_TYPE_NONE,
                  2,
                  G_TYPE_DBUS_OBJECT,
                  G_TYPE_DBUS_INTERFACE);
  g_signal_set_va_marshaller (signals[INTERFACE_ADDED],
                              G_TYPE_FROM_INTERFACE (iface),
                              _g_cclosure_marshal_VOID__OBJECT_OBJECTv);

  /**
   * GDBusObjectManager::interface-removed:
   * @manager: The #GDBusObjectManager emitting the signal.
   * @object: The #GDBusObject on which an interface was removed.
   * @interface: The #GDBusInterface that was removed.
   *
   * Emitted when @interface has been removed from @object.
   *
   * This signal exists purely as a convenience to avoid having to
   * connect signals to all objects managed by @manager.
   *
   * Since: 2.30
   */
  signals[INTERFACE_REMOVED] =
    g_signal_new (I_("interface-removed"),
                  G_TYPE_FROM_INTERFACE (iface),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GDBusObjectManagerIface, interface_removed),
                  NULL,
                  NULL,
                  _g_cclosure_marshal_VOID__OBJECT_OBJECT,
                  G_TYPE_NONE,
                  2,
                  G_TYPE_DBUS_OBJECT,
                  G_TYPE_DBUS_INTERFACE);
  g_signal_set_va_marshaller (signals[INTERFACE_REMOVED],
                              G_TYPE_FROM_INTERFACE (iface),
                              _g_cclosure_marshal_VOID__OBJECT_OBJECTv);

}

/* ---------------------------------------------------------------------------------------------------- */

/**
 * g_dbus_object_manager_get_object_path:
 * @manager: A #GDBusObjectManager.
 *
 * Gets the object path that @manager is for.
 *
 * Returns: A string owned by @manager. Do not free.
 *
 * Since: 2.30
 */
const gchar *
g_dbus_object_manager_get_object_path (GDBusObjectManager *manager)
{
  GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager);
  return iface->get_object_path (manager);
}

/**
 * g_dbus_object_manager_get_objects:
 * @manager: A #GDBusObjectManager.
 *
 * Gets all #GDBusObject objects known to @manager.
 *
 * Returns: (transfer full) (element-type GDBusObject): A list of
 *   #GDBusObject objects. The returned list should be freed with
 *   g_list_free() after each element has been freed with
 *   g_object_unref().
 *
 * Since: 2.30
 */
GList *
g_dbus_object_manager_get_objects (GDBusObjectManager *manager)
{
  GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager);
  return iface->get_objects (manager);
}

/**
 * g_dbus_object_manager_get_object:
 * @manager: A #GDBusObjectManager.
 * @object_path: Object path to look up.
 *
 * Gets the #GDBusObjectProxy at @object_path, if any.
 *
 * Returns: (transfer full): A #GDBusObject or %NULL. Free with
 *   g_object_unref().
 *
 * Since: 2.30
 */
GDBusObject *
g_dbus_object_manager_get_object (GDBusObjectManager *manager,
                                  const gchar        *object_path)
{
  GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager);
  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
  return iface->get_object (manager, object_path);
}

/**
 * g_dbus_object_manager_get_interface:
 * @manager: A #GDBusObjectManager.
 * @object_path: Object path to look up.
 * @interface_name: D-Bus interface name to look up.
 *
 * Gets the interface proxy for @interface_name at @object_path, if
 * any.
 *
 * Returns: (transfer full): A #GDBusInterface instance or %NULL. Free
 *   with g_object_unref().
 *
 * Since: 2.30
 */
GDBusInterface *
g_dbus_object_manager_get_interface (GDBusObjectManager *manager,
                                     const gchar        *object_path,
                                     const gchar        *interface_name)
{
  GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager);
  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
  g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL);
  return iface->get_interface (manager, object_path, interface_name);
}
