//Little program to test bug710730
//Prints the (name,role) of the current focused/selected object, after each focus/selection change
// "all" because it doesn't filter by app

#include <atspi/atspi.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

static gchar*
get_label(AtspiAccessible *accessible)
{
  GArray *relations;
  AtspiRelation *relation;
  gint i;
  gchar *result = "";

  relations = atspi_accessible_get_relation_set (accessible, NULL);
  if (relations == NULL) {
    return "";
  }

  for (i = 0; i < relations->len; i++) {
    relation = g_array_index (relations, AtspiRelation*, i);

    if (atspi_relation_get_relation_type (relation) == ATSPI_RELATION_LABELLED_BY) {
      result = atspi_accessible_get_name (atspi_relation_get_target (relation, 0), NULL);
    }
  }

  if (relations != NULL) //FIXME: we need to free each relation, ask Mike about how is done at pyatspi, or if there is a bug
    g_array_free (relations, TRUE);

  return result;
}

static void
print_info (AtspiAccessible *accessible)
{
  gchar *name = "NULL";
  gchar *role_name = "NULL";
  AtspiComponent *component_iface = NULL;
  GError *error = NULL;
  gboolean contains = FALSE;

  if (accessible != NULL) {
    name = atspi_accessible_get_name (accessible, NULL);
    if ((name == NULL) || (g_strcmp0 (name, "") == 0))
        name = get_label (accessible);

    role_name = atspi_accessible_get_role_name (accessible, NULL);

    component_iface = atspi_accessible_get_component_iface (accessible);
    if (component_iface != NULL) {
      contains = atspi_component_contains (component_iface, 0, 0, ATSPI_COORD_TYPE_SCREEN, &error);
      if (error != NULL) {
        g_print ("ERROR: %s\n", error->message);
        g_error_free (error);
      }
    }
  }

  g_print ("(%s, %s, %i)\n", name, role_name, contains);
}

static void
on_event (AtspiEvent *event,
          void *data)
{
  if (event->source == NULL)
    return;

  // We care only about focus/selection gain, not lose
  if (!event->detail1)
    return;

  print_info (event->source);
}

int main()
{
  AtspiEventListener *listener;

  atspi_init ();

  listener = atspi_event_listener_new (on_event, NULL, NULL);

  atspi_event_listener_register (listener, "object:state-changed:focused", NULL);
  atspi_event_listener_register (listener, "object:state-changed:selected", NULL);

  atspi_event_main ();

  return 0;
}
