/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 * unity-webapps-action-invoker.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 <stdlib.h>

#include "unity-webapps-service.h"
#include "unity-webapps-context.h"

#include <glib/gstdio.h>

#include <time.h>

#include <libdbusmenu-glib/menuitem.h>
#include <libdbusmenu-glib/client.h>

static gchar *application = NULL;
const gchar *action = NULL;


typedef enum {
  TRANSPORT_ACTION_PREVIOUS,
  TRANSPORT_ACTION_PLAY_PAUSE,
  TRANSPORT_ACTION_NEXT,
  TRANSPORT_ACTION_REWIND,
  TRANSPORT_ACTION_FORWIND,
  TRANSPORT_ACTION_NO_ACTION
}TransportAction;

static gboolean
quit_and_flush (gpointer user_data)
{
	while (g_main_context_pending (NULL))
		{
			g_main_context_iteration (NULL, TRUE);                                                                                
		}
	g_dbus_connection_flush_sync (g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL), NULL, NULL);
	
	exit (0);
	
	return FALSE;
}

static void
on_property_changed (DbusmenuMenuitem *metadata_item,
					 const gchar *property,
					 GVariant *value,
					 gpointer user_data)
{
  DbusmenuMenuitem *transport_item;
  const gchar *player_name;
  gint i;
  transport_item = user_data ? (DbusmenuMenuitem *)(((GList *)user_data)->data) : NULL;

  if (g_strcmp0 (property, "x-canonical-sound-menu-player-metadata-player-name") != 0)
	{
	  return;
	}
  
  g_variant_get (value, "s", &player_name);
  
  if (g_strcmp0 (player_name, application) != 0)
	{
	  return;
	}
  
  if (action == NULL)
	{
	  i = 0;
	  transport_item = metadata_item;
	}
  else if (g_strcmp0 (action, "playpause") == 0)
	{
	  i = TRANSPORT_ACTION_PLAY_PAUSE;
	}
  else if (g_strcmp0 (action, "previous") == 0)
	{
	  i = TRANSPORT_ACTION_PREVIOUS;
	}
  else if (g_strcmp0 (action, "next") == 0)
	{
	  i = TRANSPORT_ACTION_NEXT;
	}
  else
	{
	  i= 0;
	  transport_item = metadata_item;
	}
  
  dbusmenu_menuitem_handle_event (transport_item, "clicked", g_variant_new ("i", i), time (NULL));
  
  g_timeout_add (500, quit_and_flush, NULL);
}


static gboolean
invoke_item (gpointer user_data)
{
  DbusmenuMenuitem *root;
  const GList *children;
  const GList *walk;
  
  root = (DbusmenuMenuitem *)user_data;

  children = dbusmenu_menuitem_get_children (root);
  
  for (walk = children;
       walk != NULL;
       walk = walk->next)
    {
      DbusmenuMenuitem *child;
      
	  const gchar *child_type;
      
      child = (DbusmenuMenuitem *)walk->data;

	  child_type = dbusmenu_menuitem_property_get (child, "type");
	  
	  if (g_strcmp0 (child_type, "x-canonical-sound-menu-player-metadata-type") != 0)
		{
		  continue;
		}
	  
	  g_signal_connect (child, "property-changed", G_CALLBACK (on_property_changed), walk->next);
	  
    }
  
  return FALSE;
}


static void
on_root_changed (DbusmenuClient *client,
				 DbusmenuMenuitem *newitem,
				 gpointer user_data)
{
	invoke_item(newitem);
}

static void
make_client ()
{
  DbusmenuClient *client;
  
  client = dbusmenu_client_new ("com.canonical.indicator.sound", "/com/canonical/indicator/sound/menu");
  
  g_signal_connect (client, "root-changed",
					G_CALLBACK (on_root_changed),
					NULL);
  
}


gint
main (gint argc, gchar **argv)
{
  if (argc == 2)
	{
	  application = argv[1];
	  action = NULL;
	}
  else if (argc == 3)
	{
	  application = argv[1];
	  action = argv[2];
	}
  else
	{
	  g_printf ("Usage: indicator-action-invoker application (action?)");
	  exit (1);
	}
  
  g_type_init ();
  
  make_client ();
  
  g_main_loop_run (g_main_loop_new (NULL, FALSE));
  
  return 0;  
}
