/* -*- c++ -*- */
#ifndef _sigc_events_h_
#define _sigc_events_h_
#include <gdk/gdk.h>
#include <vdk/vdkstring.h>
class VDKObject;

/** Baseclass for all VDKEvents, not instantied itself. */
class VDKAnyEvent
{
 protected:
     VDKObject* _obj;
     GdkEventType _type;
     VDKAnyEvent(const GdkEvent* ,VDKObject*);
 public:
     virtual ~VDKAnyEvent(){}
     VDKObject* Sender() const;
     GdkEventType GDKType() const{return _type;}
};

/** Baseclass for FocusEvents. This class only specifies the 
 *  interface, so you can easily switch between different 
 *  focus-strategies. 
 *  @see VDKMouseFocusEvent
 *  @see VDKKeyFocusEvent */
class VDKFocusEvent
{
protected:
     VDKFocusEvent(bool focus)
	  : Focus(focus){}
public:
     /** Tells you if the object hast lost or got the focus */
     const bool Focus;
     bool hasFocus()const{return Focus;}
};

/** This class represents the data associated with a keypress or keyrelease
 *  event.    
 */
class VDKKeyEvent : public VDKAnyEvent
{
 private:
     unsigned int _state;
     guint _keyval;
     gchar* _string;
 public:
     VDKKeyEvent(const GdkEventKey* , VDKObject*);
     VDKKeyEvent(VDKKeyEvent const&);
     ~VDKKeyEvent();
     VDKKeyEvent& operator=(VDKKeyEvent const&);
     /** Returns the corresponding id for this key as defined in 
      *	 gdkkeysyms.h. Usefull for keys which don't have a string 
      * representation. For example, when key 'a' is pressed you get
      * the string "a" and the id Gdk_a, but when you press on backspace
      * you get the string "" (as there is no such representation) and
      * id Gdk_BackSpace.
      * Note that modifiers are handled by Modifier
      * @see Modifier()
      */
     unsigned int Key() const;
     /** Tells you what modifier was pressed when this event was generated.
      * The modifiers are defined in enum GdkModifierType in gdktypes.h.
      * You will get the or-ed vaule of all pressed modifiers.
      */
     unsigned int Modifier() const;
     /** Gives you the string-representation of pressed key if possible.
      * @see Key() */
     VDKString String() const;
     /** Basically the same as @see Modifier() */
     const char* CString() const;
};

/** This provides you the baseinformation about the mousepointer.
 *  These event can be directly instantiated with different GdkEvents,
 *  which will not allways provide all information this events provides.
 */

class VDKMouseEvent : public VDKAnyEvent
{
protected:
     VDKPoint _pos; //! conversion from gdouble to int -> loose data
     unsigned int _state;
     guint _button;
     GdkWindow* _gwin;
     // to bring the (non) gdk-hierachy in this hierachy ...
     VDKMouseEvent(const GdkEventCrossing *, VDKObject*);
public:
     VDKMouseEvent(const GdkEventButton *, VDKObject*);
     VDKMouseEvent(const GdkEventMotion *, VDKObject*);
     /*! The position of the pointer when event occured. */
     VDKPoint const& Position() const;
     /*! The absolute position of the pointer when event occured. */
     VDKPoint AbsPosition() const;
     /*! The pressed button (int gtk enumeration) */
     unsigned int Button() const;
     /*! Reports the modifiers active at the moment the event occured */
     unsigned int Modifier() const;
};

/** This event tells you if an VDKObject has lost or got the
 *  mousefocus. In GDK-Terms this would be a GdkEventCrossing.
 *  @see VDKMouseEvent
 *  @see VDKFocusEvent */

class VDKMouseFocusEvent : public VDKMouseEvent,
			   public VDKFocusEvent
{
 public:
     VDKMouseFocusEvent(const GdkEventCrossing * eve, VDKObject* obj)
	  : VDKMouseEvent(eve,obj)
	  , VDKFocusEvent(eve->focus) {}
};

/** This event tells you if an VDKObject has lost or got the
 *  keyboradfocus. In GDK-Terms this would be a GdkEventFocus.
 *  @see VDKFocusEvent */
class VDKKeyFocusEvent : public VDKAnyEvent, public VDKFocusEvent
{
public:
     VDKKeyFocusEvent(const GdkEventFocus* eve, VDKObject* obj)
	  : VDKAnyEvent((const GdkEvent*) eve,obj)
	  , VDKFocusEvent((eve->in==TRUE) ? true : false){}
};

/** This event telles you which area of an object has to be
    redrawn. Normaly it will be emited when a region of an object
    has to be redrawn (in this case GdkEventExpose is the source of
    information) or when the entire Object has to be redrawn (so an
    underlying GDK_UNMAP was responsible for this). This event is also
    emited when you resize an object. */
class VDKPaintEvent : public VDKAnyEvent
{
     VDKRect _area;
public:
     VDKPaintEvent(const GdkEventExpose* eve, VDKObject* sender)
	  : VDKAnyEvent((const GdkEvent*) eve,sender)
	  , _area(eve->area.x, eve->area.y, 
		  eve->area.width, eve->area.height){}
     /** Returns area to be repainted */
     const VDKRect& Area() const{return _area;}
};

/** Indicates a change of the widgets geometry. So typical situations
    this event comes into play are a resize-operation or a translation
    on the desktop. */
class VDKGeometryEvent : public VDKAnyEvent
{
     VDKRect _area;
public:
     VDKGeometryEvent(const GdkEventConfigure* eve, VDKObject* sender)
	  : VDKAnyEvent((const GdkEvent*) eve,sender)
	  , _area(eve->x, eve->y,eve->width, eve->height){}
     const VDKRect& Area() const{return _area;}
};

/** To differ between different states of visibility of an object. */
typedef enum {
     FULLY_VISIBLE,
     PARTIAL_VISIBLE,
     NOT_VISIBLE
} VDKMapState;

/** This event is emitted whenever the widget toggels it's state from
    being hidden or unhidden or partial hidden. This information is stored
    with the help of VDKVisibilityState. */
class VDKMapEvent : public VDKAnyEvent
{
     VDKMapState _state;
public:
     VDKMapEvent(const GdkEventVisibility* eve, VDKObject* sender);
     VDKMapState State() const{return _state;}
};

/** For textselections as usual. */
// class VDKSelectionEvent : public VDKAnyEvent
// {
//      GdkAtom _id_sel;
//      GdkAtom _id_prop;
//      VDKString* _str_sel; // perform lookup only when needed
//      VDKString* _str_prop;
// public:
//      VDKSelectionEvent(const GdkEventSelection* sel, VDKObject* sender)
// 	  : VDKAnyEvent(eve,sender), _id_sel(eve->selection)
// 	  , _id_prop(eve->property), _str_sel(NULL), _str_prop(NULL) {}
//      ~VDKSelectionEvent();
//      VDKString Selection() const;
//      const char* CSelection() const;
//      VDKString Property() const;
//      const char* CProperty() const;
// };

// class VDKDnDEvent : public VDKAnyEvent
// {
// };

#endif /* !_sigc_events_h_ */

