/*
 * Copyright © 2010 Codethink Limited
 *
 * This program 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 licence 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, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Authors: Ryan Lortie <desrt@desrt.ca>
 */

#include "config.h"

#include "gsimpleaction.h"

#include "gaction.h"
#include "glibintl.h"

/**
 * SECTION:gsimpleaction
 * @title: GSimpleAction
 * @short_description: A simple GSimpleAction
 *
 * A #GSimpleAction is the obvious simple implementation of the #GAction
 * interface.  This is the easiest way to create an action for purposes of
 * adding it to a #GSimpleActionGroup.
 *
 * See also #GtkAction.
 **/
struct _GSimpleAction
{
  GObject       parent_instance;

  gchar        *name;
  GVariantType *parameter_type;
  gboolean      enabled;
  GVariant     *state;
};

typedef GObjectClass GSimpleActionClass;

static void g_simple_action_iface_init (GActionInterface *iface);
G_DEFINE_TYPE_WITH_CODE (GSimpleAction, g_simple_action, G_TYPE_OBJECT,
  G_IMPLEMENT_INTERFACE (G_TYPE_ACTION, g_simple_action_iface_init))

enum
{
  PROP_NONE,
  PROP_NAME,
  PROP_PARAMETER_TYPE,
  PROP_ENABLED,
  PROP_STATE_TYPE,
  PROP_STATE
};

enum
{
  SIGNAL_CHANGE_STATE,
  SIGNAL_ACTIVATE,
  NR_SIGNALS
};

static guint g_simple_action_signals[NR_SIGNALS];

static const gchar *
g_simple_action_get_name (GAction *action)
{
  GSimpleAction *simple = G_SIMPLE_ACTION (action);

  return simple->name;
}

const GVariantType *
g_simple_action_get_parameter_type (GAction *action)
{
  GSimpleAction *simple = G_SIMPLE_ACTION (action);

  return simple->parameter_type;
}

static const GVariantType *
g_simple_action_get_state_type (GAction *action)
{
  GSimpleAction *simple = G_SIMPLE_ACTION (action);

  if (simple->state != NULL)
    return g_variant_get_type (simple->state);
  else
    return NULL;
}

static GVariant *
g_simple_action_get_state_hint (GAction *action)
{
  return NULL;
}

static gboolean
g_simple_action_get_enabled (GAction *action)
{
  GSimpleAction *simple = G_SIMPLE_ACTION (action);

  return simple->enabled;
}

static void
g_simple_action_change_state (GAction  *action,
                              GVariant *value)
{
  GSimpleAction *simple = G_SIMPLE_ACTION (action);

  /* If the user connected a signal handler then they are responsible
   * for handling state changes.
   */
  if (g_signal_has_handler_pending (action, g_simple_action_signals[SIGNAL_CHANGE_STATE], 0, TRUE))
    g_signal_emit (action, g_simple_action_signals[SIGNAL_CHANGE_STATE], 0, value);

  /* If not, then the default behaviour is to just set the state. */
  else
    g_simple_action_set_state (simple, value);
}

/**
 * g_simple_action_set_state:
 * @simple: a #GSimpleAction
 * @value: the new #GVariant for the state
 *
 * Sets the state of the action.
 *
 * This directly updates the 'state' property to the given value.
 *
 * This should only be called by the implementor of the action.  Users
 * of the action should not attempt to directly modify the 'state'
 * property.  Instead, they should call g_action_change_state() to
 * request the change.
 *
 * Since: 2.30
 **/
void
g_simple_action_set_state (GSimpleAction *simple,
                           GVariant      *value)
{
  g_return_if_fail (G_IS_SIMPLE_ACTION (simple));
  g_return_if_fail (value != NULL);

  {
    const GVariantType *state_type;

    state_type = simple->state ?
                   g_variant_get_type (simple->state) : NULL;
    g_return_if_fail (state_type != NULL);
    g_return_if_fail (g_variant_is_of_type (value, state_type));
  }

  g_variant_ref_sink (value);

  if (!simple->state || !g_variant_equal (simple->state, value))
    {
      if (simple->state)
        g_variant_unref (simple->state);

      simple->state = g_variant_ref (value);

      g_object_notify (G_OBJECT (simple), "state");
    }

  g_variant_unref (value);
}

static GVariant *
g_simple_action_get_state (GAction *action)
{
  GSimpleAction *simple = G_SIMPLE_ACTION (action);

  return simple->state ? g_variant_ref (simple->state) : NULL;
}

static void
g_simple_action_activate (GAction  *action,
                          GVariant *parameter)
{
  GSimpleAction *simple = G_SIMPLE_ACTION (action);

  g_return_if_fail (simple->parameter_type == NULL ?
                      parameter == NULL :
                    (parameter != NULL &&
                     g_variant_is_of_type (parameter,
                                           simple->parameter_type)));

  if (parameter != NULL)
    g_variant_ref_sink (parameter);

  if (simple->enabled)
    g_signal_emit (simple, g_simple_action_signals[SIGNAL_ACTIVATE], 0, parameter);

  if (parameter != NULL)
    g_variant_unref (parameter);
}

static void
g_simple_action_get_property (GObject    *object,
                              guint       prop_id,
                              GValue     *value,
                              GParamSpec *pspec)
{
  GAction *action = G_ACTION (object);

  switch (prop_id)
    {
    case PROP_NAME:
      g_value_set_string (value, g_simple_action_get_name (action));
      break;

    case PROP_PARAMETER_TYPE:
      g_value_set_boxed (value, g_simple_action_get_parameter_type (action));
      break;

    case PROP_ENABLED:
      g_value_set_boolean (value, g_simple_action_get_enabled (action));
      break;

    case PROP_STATE_TYPE:
      g_value_set_boxed (value, g_simple_action_get_state_type (action));
      break;

    case PROP_STATE:
      g_value_take_variant (value, g_simple_action_get_state (action));
      break;

    default:
      g_assert_not_reached ();
    }
}

static void
g_simple_action_finalize (GObject *object)
{
  GSimpleAction *simple = G_SIMPLE_ACTION (object);

  g_free (simple->name);
  if (simple->parameter_type)
    g_variant_type_free (simple->parameter_type);
  if (simple->state)
    g_variant_unref (simple->state);

  G_OBJECT_CLASS (g_simple_action_parent_class)
    ->finalize (object);
}

void
g_simple_action_init (GSimpleAction *simple)
{
}

void
g_simple_action_iface_init (GActionInterface *iface)
{
  iface->get_name = g_simple_action_get_name;
  iface->get_parameter_type = g_simple_action_get_parameter_type;
  iface->get_state_type = g_simple_action_get_state_type;
  iface->get_state_hint = g_simple_action_get_state_hint;
  iface->get_enabled = g_simple_action_get_enabled;
  iface->get_state = g_simple_action_get_state;
  iface->change_state = g_simple_action_change_state;
  iface->activate = g_simple_action_activate;
}

void
g_simple_action_class_init (GSimpleActionClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);

  object_class->get_property = g_simple_action_get_property;
  object_class->finalize = g_simple_action_finalize;

  /**
   * GSimpleAction::activate:
   * @simple: the #GSimpleAction
   * @parameter: (allow-none): the parameter to the activation
   *
   * Indicates that the action was just activated.
   *
   * @parameter will always be of the expected type.  In the event that
   * an incorrect type was given, no signal will be emitted.
   *
   * Since: 2.28
   */
  g_simple_action_signals[SIGNAL_ACTIVATE] =
    g_signal_new (I_("activate"),
                  G_TYPE_SIMPLE_ACTION,
                  G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
                  0, NULL, NULL,
                  g_cclosure_marshal_VOID__VARIANT,
                  G_TYPE_NONE, 1,
                  G_TYPE_VARIANT);

  /**
   * GSimpleAction::change-state:
   * @simple: the #GSimpleAction
   * @value: (allow-none): the requested value for the state
   *
   * Indicates that the action just received a request to change its
   * state.
   *
   * @value will always be of the correct state type.  In the event that
   * an incorrect type was given, no signal will be emitted.
   *
   * If no handler is connected to this signal then the default
   * behaviour is to call g_simple_action_set_state() to set the state
   * to the requested value.  If you connect a signal handler then no
   * default action is taken.  If the state should change then you must
   * call g_simple_action_set_state() from the handler.
   *
   * <example>
   * <title>Example 'change-state' handler</title>
   * <programlisting>
   * static void
   * change_volume_state (GSimpleAction *action,
   *                      GVariant      *value,
   *                      gpointer       user_data)
   * {
   *   gint requested;
   *
   *   requested = g_variant_get_int32 (value);
   *
   *   // Volume only goes from 0 to 10
   *   if (0 <= requested && requested <= 10)
   *     g_simple_action_set_state (action, value);
   * }
   * </programlisting>
   * </example>
   *
   * The handler need not set the state to the requested value.  It
   * could set it to any value at all, or take some other action.
   *
   * Since: 2.30
   */
  g_simple_action_signals[SIGNAL_CHANGE_STATE] =
    g_signal_new (I_("change-state"),
                  G_TYPE_SIMPLE_ACTION,
                  G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
                  0, NULL, NULL,
                  g_cclosure_marshal_VOID__VARIANT,
                  G_TYPE_NONE, 1,
                  G_TYPE_VARIANT);

  /**
   * GSimpleAction:name:
   *
   * The name of the action.  This is mostly meaningful for identifying
   * the action once it has been added to a #GSimpleActionGroup.
   *
   * Since: 2.28
   **/
  g_object_class_install_property (object_class, PROP_NAME,
                                   g_param_spec_string ("name",
                                                        P_("Action Name"),
                                                        P_("The name used to invoke the action"),
                                                        NULL,
                                                        G_PARAM_READABLE |
                                                        G_PARAM_STATIC_STRINGS));

  /**
   * GSimpleAction:parameter-type:
   *
   * The type of the parameter that must be given when activating the
   * action.
   *
   * Since: 2.28
   **/
  g_object_class_install_property (object_class, PROP_PARAMETER_TYPE,
                                   g_param_spec_boxed ("parameter-type",
                                                       P_("Parameter Type"),
                                                       P_("The type of GVariant passed to activate()"),
                                                       G_TYPE_VARIANT_TYPE,
                                                       G_PARAM_READABLE |
                                                       G_PARAM_STATIC_STRINGS));

  /**
   * GSimpleAction:enabled:
   *
   * If @action is currently enabled.
   *
   * If the action is disabled then calls to g_simple_action_activate() and
   * g_simple_action_change_state() have no effect.
   *
   * Since: 2.28
   **/
  g_object_class_install_property (object_class, PROP_ENABLED,
                                   g_param_spec_boolean ("enabled",
                                                         P_("Enabled"),
                                                         P_("If the action can be activated"),
                                                         TRUE,
                                                         G_PARAM_READABLE |
                                                         G_PARAM_STATIC_STRINGS));

  /**
   * GSimpleAction:state-type:
   *
   * The #GVariantType of the state that the action has, or %NULL if the
   * action is stateless.
   *
   * Since: 2.28
   **/
  g_object_class_install_property (object_class, PROP_STATE_TYPE,
                                   g_param_spec_boxed ("state-type",
                                                       P_("State Type"),
                                                       P_("The type of the state kept by the action"),
                                                       G_TYPE_VARIANT_TYPE,
                                                       G_PARAM_READABLE |
                                                       G_PARAM_STATIC_STRINGS));

  /**
   * GSimpleAction:state:
   *
   * The state of the action, or %NULL if the action is stateless.
   *
   * Since: 2.28
   **/
  g_object_class_install_property (object_class, PROP_STATE,
                                   g_param_spec_variant ("state",
                                                         P_("State"),
                                                         P_("The state the action is in"),
                                                         G_VARIANT_TYPE_ANY,
                                                         NULL,
                                                         G_PARAM_READABLE |
                                                         G_PARAM_STATIC_STRINGS));
}

/**
 * g_simple_action_set_enabled:
 * @simple: a #GSimpleAction
 * @enabled: whether the action is enabled
 *
 * Sets the action as enabled or not.
 *
 * An action must be enabled in order to be activated or in order to
 * have its state changed from outside callers.
 *
 * This should only be called by the implementor of the action.  Users
 * of the action should not attempt to modify its enabled flag.
 *
 * Since: 2.28
 **/
void
g_simple_action_set_enabled (GSimpleAction *simple,
                             gboolean       enabled)
{
  g_return_if_fail (G_IS_SIMPLE_ACTION (simple));

  enabled = !!enabled;

  if (simple->enabled != enabled)
    {
      simple->enabled = enabled;
      g_object_notify (G_OBJECT (simple), "enabled");
    }
}
/**
 * g_simple_action_new:
 * @name: the name of the action
 * @parameter_type: (allow-none): the type of parameter to the activate function
 *
 * Creates a new action.
 *
 * The created action is stateless.  See g_simple_action_new_stateful().
 *
 * Returns: a new #GSimpleAction
 *
 * Since: 2.28
 **/
GSimpleAction *
g_simple_action_new (const gchar        *name,
                     const GVariantType *parameter_type)
{
  GSimpleAction *simple;

  g_return_val_if_fail (name != NULL, NULL);

  simple = g_object_new (G_TYPE_SIMPLE_ACTION, NULL);
  simple->name = g_strdup (name);

  if (parameter_type)
    simple->parameter_type = g_variant_type_copy (parameter_type);

  simple->enabled = TRUE;

  return simple;
}

/**
 * g_simple_action_new_stateful:
 * @name: the name of the action
 * @parameter_type: (allow-none): the type of the parameter to the activate function
 * @state: the initial state of the action
 *
 * Creates a new stateful action.
 *
 * @state is the initial state of the action.  All future state values
 * must have the same #GVariantType as the initial state.
 *
 * If the @state GVariant is floating, it is consumed.
 *
 * Returns: a new #GSimpleAction
 *
 * Since: 2.28
 **/
GSimpleAction *
g_simple_action_new_stateful (const gchar        *name,
                              const GVariantType *parameter_type,
                              GVariant           *state)
{
  GSimpleAction *simple;

  g_return_val_if_fail (name != NULL, NULL);
  g_return_val_if_fail (state != NULL, NULL);

  simple = g_object_new (G_TYPE_SIMPLE_ACTION, NULL);
  simple->name = g_strdup (name);

  if (parameter_type)
    simple->parameter_type = g_variant_type_copy (parameter_type);

  simple->state = g_variant_ref_sink (state);

  simple->enabled = TRUE;

  return simple;
}
