/*
 * Clutter.
 *
 * An OpenGL based 'interactive canvas' library.
 *
 * Copyright (C) 2010  Intel Corporation.
 * Copyright (C) 2011  Robert Bosch Car Multimedia GmbH.
 * Copyright (C) 2012  Collabora Ltd.
 *
 * 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 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:
 *   Emanuele Aina <emanuele.aina@collabora.com>
 *
 * Based on ClutterPanAction
 * Based on ClutterDragAction, ClutterSwipeAction, and MxKineticScrollView,
 * written by:
 *   Emmanuele Bassi <ebassi@linux.intel.com>
 *   Tomeu Vizoso <tomeu.vizoso@collabora.co.uk>
 *   Chris Lord <chris@linux.intel.com>
 */

/**
 * ClutterTapAction:
 * 
 * Action for tap gestures
 *
 * #ClutterTapAction is a sub-class of [class@GestureAction] that implements
 * the logic for recognizing mouse clicks and touch tap gestures.
 *
 * The simplest usage of #ClutterTapAction consists in adding it to
 * a [class@Actor], setting it as reactive and connecting a
 * callback for the [signal@TapAction::tap] signal, along the lines of the
 * following code:
 *
 * ```c
 *   clutter_actor_add_action (actor, clutter_tap_action_new ());
 *   clutter_actor_set_reactive (actor, TRUE);
 *   g_signal_connect (action, "tap", G_CALLBACK (on_tap_callback), NULL);
 * ```
 */

#include "config.h"

#include "clutter/clutter-tap-action.h"

#include "clutter/clutter-debug.h"
#include "clutter/clutter-enum-types.h"
#include "clutter/clutter-marshal.h"
#include "clutter/clutter-private.h"

enum
{
  TAP,

  LAST_SIGNAL
};

static guint tap_signals[LAST_SIGNAL] = { 0, };

G_DEFINE_TYPE (ClutterTapAction, clutter_tap_action,
               CLUTTER_TYPE_GESTURE_ACTION);

static void
emit_tap (ClutterTapAction *self,
          ClutterActor     *actor)
{
  g_signal_emit (self, tap_signals[TAP], 0, actor);
}

static void
gesture_end (ClutterGestureAction *gesture,
             ClutterActor         *actor)
{
  emit_tap (CLUTTER_TAP_ACTION (gesture), actor);
}

static void
clutter_tap_action_constructed (GObject *object)
{
  clutter_gesture_action_set_threshold_trigger_edge (CLUTTER_GESTURE_ACTION (object),
                                                     CLUTTER_GESTURE_TRIGGER_EDGE_BEFORE);
}

static void
clutter_tap_action_class_init (ClutterTapActionClass *klass)
{
  ClutterGestureActionClass *gesture_class =
      CLUTTER_GESTURE_ACTION_CLASS (klass);
  GObjectClass *object_class =
      G_OBJECT_CLASS (klass);

  object_class->constructed = clutter_tap_action_constructed;

  gesture_class->gesture_end = gesture_end;

  /**
   * ClutterTapAction::tap:
   * @action: the #ClutterTapAction that emitted the signal
   * @actor: the #ClutterActor attached to the @action
   *
   * The signal is emitted when the tap gesture is complete.
   */
  tap_signals[TAP] =
    g_signal_new (I_("tap"),
                  G_TYPE_FROM_CLASS (klass),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (ClutterTapActionClass, tap),
                  NULL, NULL, NULL,
                  G_TYPE_NONE, 1,
                  CLUTTER_TYPE_ACTOR);
}

static void
clutter_tap_action_init (ClutterTapAction *self)
{
}

/**
 * clutter_tap_action_new:
 *
 * Creates a new #ClutterTapAction instance
 *
 * Return value: the newly created #ClutterTapAction
 */
ClutterAction *
clutter_tap_action_new (void)
{
  return g_object_new (CLUTTER_TYPE_TAP_ACTION, NULL);
}
