/***********************************************************************************
 **
 ** Atari++ emulator (c) 2002 THOR-Software, Thomas Richter
 **
 ** $Id: event.hpp,v 1.10 2015/05/21 18:52:39 thor Exp $
 **
 ** In this module: Definition of GUI events
 **********************************************************************************/

#ifndef EVENT_HPP
#define EVENT_HPP

/// Includes
#include "types.h"
#include "types.hpp"
#include "list.hpp"
///

/// Forwards
class Gadget;
class AtariDisplay;
class Keyboard;
class RenderPort;
class MenuItem;
///

/// Struct Event
// An event, as generated by the menu event feeder and as recognized by the
// gadgets. Actually, we could use here a multiple derived hierarchy of
// event types, but I don't. The reason is that I can drill-up the same
// even very easily within the individual handlers and "transmogrify"
// it as required.
struct Event {
  enum {
    // Low level events. These are feed into the event chain, i.e.
    // the gadgets we have.
    Nothing,    // A blank event, used explicity to discard events
    Mouse,      // A mouse position/button update
    Click,      // A mouse button update
    Keyboard,   // A keyboard state/update method
    Wheel,      // A mouse wheel event
    Joystick,   // A joystick movement, X,Y is the relative movement
    // High-Level events. These are generated by the gadgets
    GadgetDown, // A gadget got just activated
    GadgetMove, // The gadget got updated (i.e. slider, string gadget)
    GadgetUp,   // A gadget got released.
    // High-Level events. These are generated by the menus
    MenuPick,   // A menu item has been selected
    MenuAbort,  // A menu has been aborted (no item picked)
    // Even higher level control events for the menu
    Request,    // Pop up a file requester
    Ctrl        // Transmits a defined integer back to the client
  }             Type;
  //
  // If the following flag is set, then the event is re-sent after
  // it is processed. This is used when de-activating one gadget
  // shall enable another.
  bool            Resent;
  //
  // For mouse button events: The position and the button state.
  LONG            X,Y;
  bool            Button;
  //
  // For mouse wheel events: The number of lines scrolled since last time
  // Negative for scrolling up, positive for scrolling down.
  LONG            ScrolledLines;
  //
  // For keyboard events: The character, and the state of the 
  // shift and control key. We don't support any additional
  // qualifiers.
  bool            DownUp;
  char            Key;
  bool            Shift,Control;
  //
  // For gadget events: Which gadget is affected.
  class Gadget   *Object;
  // For menu events: The affected menu item.
  class MenuItem *Menu;
  //
  // For high-level events: The control Id. This is user defined.
  int             ControlId;
  //
  Event(void)
    : Type(Nothing), Resent(false), Object(NULL), Menu(NULL), ControlId(0)
  { }
};
///

/// Class EventFeeder
// This class collects events from various input
// classes.
class EventFeeder {
  //
  // Global actions we need to execute, either driver by the
  // preferences reloader or by the "control topic" directly
  // by the user. This must coincide with the definitions in
  // the menu class.
  enum MenuAction {
    Nothing   = 0, // do nothing special
    Comeback       // high-frequency action required, come again immediately (keyboard)
  };
  // Connection to the outher world.
  class AtariDisplay       *Display;  // get mouse events from here.
  class Keyboard           *Keyboard; // get keyboard events from here.
  class GameController     *Joystick; // optional, if any.
  class RenderPort         *RPort;    // port to draw on
  //
  // The gadgets we have to feed
  List<class Gadget>       *GList;
  //
  // Last state of the button to create up/down button events.
  bool LastButton;
  //
  // Last state of the joystick button.
  bool LastStrig;
  //
  // Last state of the keyboard button(s)
  bool LastDownUp;
  //
  // True if a down event has been found for which an up event is missing.
  bool KeyDownFound;
  //
  // Ditto for a mouse event.
  bool MouseDownFound;
  //
  // Last key that has been pressed.
  char LastKey;
  //
  // Last joystick movement.
  int  LastStick;
  //
  // Event counter for the auto keyboard events.
  LONG AutoCounter;
  //
  // Forward an event to all gadget that are part of the list maintained by
  // this event feeder. Returns true if the event changed the setting of
  // any option.
  int ForwardEvent(struct Event &ev);
  //
  // Re-position the mouse pointer in the dx,dy direction
  void PositionMouse(int dx,int dy);
  //
  // Create a mouse click event/active a gadget. Return the
  // state change.
  int ClickMouse(void);
  //
public:
  EventFeeder(class AtariDisplay *display,class Keyboard *keyboard,class GameController *stick,
	      List<Gadget> *glist,class RenderPort *rp)
    : Display(display), Keyboard(keyboard), Joystick(stick), RPort(rp), GList(glist),
      LastButton(false), LastStrig(false), LastDownUp(false), 
      KeyDownFound(false), MouseDownFound(false),
      LastKey(0), LastStick(0x0f), AutoCounter(0)
  { }
  //
  // Handle the event and return a flag whether any option was changed by
  // this event. If so, we would have to re-parse the stream.
  int PickedOption(struct Event &event);
  //
};
///

///
#endif
