/*
 * unity-webapps-telepathy-presence-manager.c
 * Copyright (C) Canonical LTD 2011
 *
 * Author: Robert Carr <racarr@canonical.com>
 * 
 unity-webapps 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 3 of the License, or
 * (at your option) any later version.
 * 
 * unity-webapps 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 program.  If not, see <http://www.gnu.org/licenses/>.";
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib/gstdio.h>
#include <gio/gio.h>

#include "unity-webapps-telepathy-presence-manager.h"

#include "../unity-webapps-debug.h"

#include <telepathy-glib/account-manager.h>

struct _UnityWebappsTelepathyPresenceManagerPrivate {
  TpAccountManager *account_manager;
};


G_DEFINE_TYPE(UnityWebappsTelepathyPresenceManager, unity_webapps_telepathy_presence_manager, UNITY_WEBAPPS_TYPE_PRESENCE_MANAGER)

#define UNITY_WEBAPPS_TELEPATHY_PRESENCE_MANAGER_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), UNITY_WEBAPPS_TYPE_TELEPATHY_PRESENCE_MANAGER, UnityWebappsTelepathyPresenceManagerPrivate))

static gboolean
telepathy_presence_manager_get_presence (UnityWebappsPresenceManager *presence_manager,
					     gchar **status, 
					     gchar **message)
{
  UnityWebappsTelepathyPresenceManager *manager;
  
  manager = UNITY_WEBAPPS_TELEPATHY_PRESENCE_MANAGER (presence_manager);

  if (manager->priv->account_manager == NULL)
    {
      *status = NULL;
      *message = NULL;
      
      return FALSE;
    }
  
  tp_account_manager_get_most_available_presence (manager->priv->account_manager,
						  status, message);
  
  if (*status == NULL)
    {
      *status = g_strdup ("available");
    }
  
  return TRUE;  
}

static void
unity_webapps_telepathy_presence_manager_finalize (GObject *object)
{
  UnityWebappsTelepathyPresenceManager *manager;
  
  manager = UNITY_WEBAPPS_TELEPATHY_PRESENCE_MANAGER (object);

  if (manager->priv->account_manager)
    {
      g_object_unref (G_OBJECT (manager->priv->account_manager));
    }
}

static void
unity_webapps_telepathy_presence_manager_class_init (UnityWebappsTelepathyPresenceManagerClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  UnityWebappsPresenceManagerClass *presence_class = UNITY_WEBAPPS_PRESENCE_MANAGER_CLASS (klass);
  
  object_class->finalize = unity_webapps_telepathy_presence_manager_finalize;

  presence_class->get_presence = telepathy_presence_manager_get_presence;
  
  g_type_class_add_private (object_class, sizeof(UnityWebappsTelepathyPresenceManagerPrivate));
 
}

static void
on_most_available_presence_changed (TpAccountManager *manager,
				    guint presence,
				    gchar *status,
				    gchar *message,
				    gpointer user_data)
{
  UnityWebappsTelepathyPresenceManager *presence_manager;
  
  presence_manager = (UnityWebappsTelepathyPresenceManager *)user_data;
  
  g_signal_emit_by_name (presence_manager, "presence-changed", status, message);
}

static void
account_manager_prepared (GObject *source_object,
			  GAsyncResult *res,
			  gpointer user_data)
{
  UnityWebappsTelepathyPresenceManager *manager;
  gchar *status, *message;
  GError *error;
  
  manager = (UnityWebappsTelepathyPresenceManager *)user_data;
  
  error = NULL;
  
  tp_proxy_prepare_finish (manager->priv->account_manager,
			   res,
			   &error);
  
  if (error != NULL)
    {
      g_warning ("Error preparing Telepathy Account Manager object for Presence Tracking: %s", error->message);
      
      g_error_free (error);
      
      return;
    }
  
  telepathy_presence_manager_get_presence (UNITY_WEBAPPS_PRESENCE_MANAGER (manager), &status, &message);

  g_signal_emit_by_name (manager, "presence-changed", status, message);
  
  
  g_signal_connect (manager->priv->account_manager, "most-available-presence-changed",
		    G_CALLBACK (on_most_available_presence_changed), manager);
  
  g_free (status);
  g_free (message);
}

static void
unity_webapps_telepathy_presence_manager_init (UnityWebappsTelepathyPresenceManager *manager)
{
  manager->priv = UNITY_WEBAPPS_TELEPATHY_PRESENCE_MANAGER_GET_PRIVATE (manager);
  
  manager->priv->account_manager = tp_account_manager_dup ();
  
  tp_proxy_prepare_async (manager->priv->account_manager,
			  NULL,
			  account_manager_prepared,
			  manager);
}



UnityWebappsPresenceManager *
unity_webapps_telepathy_presence_manager_new ()
{
  return UNITY_WEBAPPS_PRESENCE_MANAGER (g_object_new (UNITY_WEBAPPS_TYPE_TELEPATHY_PRESENCE_MANAGER, NULL));
}
