/* LIBPIKA - The PIKA Library
 * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
 *
 * pikacontroller.h
 * Copyright (C) 2004 Michael Natterer <mitch@gimp.org>
 *
 * 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 3 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
 * <https://www.gnu.org/licenses/>.
 */

#ifndef PIKA_ENABLE_CONTROLLER_UNDER_CONSTRUCTION
#error PikaController is unstable API under construction
#endif

#ifndef __PIKA_CONTROLLER_H__
#define __PIKA_CONTROLLER_H__

G_BEGIN_DECLS

/* For information look at the html documentation */


/**
 * PikaControllerEventType:
 * @PIKA_CONTROLLER_EVENT_TRIGGER: the event is a simple trigger
 * @PIKA_CONTROLLER_EVENT_VALUE:   the event carries a double value
 *
 * Event types for #PikaController.
 **/
typedef enum
{
  PIKA_CONTROLLER_EVENT_TRIGGER,
  PIKA_CONTROLLER_EVENT_VALUE
} PikaControllerEventType;


typedef struct _PikaControllerEventAny     PikaControllerEventAny;
typedef struct _PikaControllerEventTrigger PikaControllerEventTrigger;
typedef struct _PikaControllerEventValue   PikaControllerEventValue;
typedef union  _PikaControllerEvent        PikaControllerEvent;

/**
 * PikaControllerEventAny:
 * @type:     The event's #PikaControllerEventType
 * @source:   The event's source #PikaController
 * @event_id: The event's ID
 *
 * Generic controller event. Every event has these three members at the
 * beginning of its struct
 **/
struct _PikaControllerEventAny
{
  PikaControllerEventType  type;
  PikaController          *source;
  gint                     event_id;
};

/**
 * PikaControllerEventTrigger:
 * @type:     The event's #PikaControllerEventType
 * @source:   The event's source #PikaController
 * @event_id: The event's ID
 *
 * Trigger controller event.
 **/
struct _PikaControllerEventTrigger
{
  PikaControllerEventType  type;
  PikaController          *source;
  gint                     event_id;
};

/**
 * PikaControllerEventValue:
 * @type:     The event's #PikaControllerEventType
 * @source:   The event's source #PikaController
 * @event_id: The event's ID
 * @value:    The event's value
 *
 * Value controller event.
 **/
struct _PikaControllerEventValue
{
  PikaControllerEventType  type;
  PikaController          *source;
  gint                     event_id;
  GValue                   value;
};

/**
 * PikaControllerEvent:
 * @type:    The event type
 * @any:     PikaControllerEventAny
 * @trigger: PikaControllerEventTrigger
 * @value:   PikaControllerEventValue
 *
 * A union to hjold all event event types
 **/
union _PikaControllerEvent
{
  PikaControllerEventType    type;
  PikaControllerEventAny     any;
  PikaControllerEventTrigger trigger;
  PikaControllerEventValue   value;
};


#define PIKA_TYPE_CONTROLLER            (pika_controller_get_type ())
#define PIKA_CONTROLLER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIKA_TYPE_CONTROLLER, PikaController))
#define PIKA_CONTROLLER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), PIKA_TYPE_CONTROLLER, PikaControllerClass))
#define PIKA_IS_CONTROLLER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIKA_TYPE_CONTROLLER))
#define PIKA_IS_CONTROLLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIKA_TYPE_CONTROLLER))
#define PIKA_CONTROLLER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), PIKA_TYPE_CONTROLLER, PikaControllerClass))


typedef struct _PikaControllerPrivate PikaControllerPrivate;
typedef struct _PikaControllerClass   PikaControllerClass;

struct _PikaController
{
  GObject                parent_instance;

  PikaControllerPrivate *priv;

  /* FIXME MOVE TO PRIVATE */
  gchar    *name;
  gchar    *state;
};

struct _PikaControllerClass
{
  GObjectClass  parent_class;

  const gchar  *name;
  const gchar  *help_domain;
  const gchar  *help_id;
  const gchar  *icon_name;

  /*  virtual functions  */
  gint          (* get_n_events)    (PikaController            *controller);
  const gchar * (* get_event_name)  (PikaController            *controller,
                                     gint                       event_id);
  const gchar * (* get_event_blurb) (PikaController            *controller,
                                     gint                       event_id);

  /*  signals  */
  gboolean      (* event)           (PikaController            *controller,
                                     const PikaControllerEvent *event);

  /* Padding for future expansion */
  void (* _pika_reserved1) (void);
  void (* _pika_reserved2) (void);
  void (* _pika_reserved3) (void);
  void (* _pika_reserved4) (void);
  void (* _pika_reserved5) (void);
  void (* _pika_reserved6) (void);
  void (* _pika_reserved7) (void);
  void (* _pika_reserved8) (void);
};


GType            pika_controller_get_type        (void) G_GNUC_CONST;
PikaController * pika_controller_new             (GType           controller_type);

gint             pika_controller_get_n_events    (PikaController *controller);
const gchar    * pika_controller_get_event_name  (PikaController *controller,
                                                  gint            event_id);
const gchar    * pika_controller_get_event_blurb (PikaController *controller,
                                                  gint            event_id);


/*  protected  */

gboolean         pika_controller_event (PikaController            *controller,
                                        const PikaControllerEvent *event);


G_END_DECLS

#endif /* __PIKA_CONTROLLER_H__ */
