/*
  libuta - a C++ widget library based on SDL (Simple Direct Layer)
  Copyright (C) 1999-2002  Karsten Laux

  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.1 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, write to the
  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  Boston, MA  02111-1307, SA.
*/

#ifndef _EVENT_H
#define _EVENT_H

#include <SDL/SDL.h>
#include "keysym.h"
#include "point.h"


namespace uta {

///event baseclass
class Event
{
 public:
  ///
  enum {
    MOUSE            = 1 << 0, 
    BUTTON           = 1 << 1,
    KEY              = 1 << 2,
    TIMER            = 1 << 3,
    QUIT             = 1 << 4,
    ICONIFIED        = 1 << 5,
    RESTORED         = 1 << 6,
    LOSTFOCUS        = 1 << 7,
    GOTFOCUS         = 1 << 8,
    RESIZED          = 1 << 9,
    EXPOSED          = 1 << 10,
    NKNOWN          = 1 << 15     
  };
  ///
  Event(int eventType) : type_(eventType) {};
  ///
  int type() const { return type_; };

 protected:
  ///
  int type_;
  
};


/**TimerEvent.
   NOT USED !
*/
class TimerEvent : public Event
{
 public:
  ///ID=0 is the "system-timer"
  TimerEvent(int timerID=0) : Event(Event::TIMER), id_(timerID) {} ;
  ///
  int id()  const { return id_; };
 protected:
  ///
  int id_;
};

///
class ButtonEvent : public Event
{
 public:
  ///
  enum ButtonType 
  { 
    BUTTON_LEFT   = 1 << 0, 
    BUTTON_RIGHT  = 1 << 1,
    BUTTON_MIDDLE = 1 << 2,
    BUTTON_WHEEL_UP = 1 << 3,
    BUTTON_WHEEL_DOWN = 1 << 4
  };
  
  ///
  enum StateType
  {
    PRESSED,
    RELEASED
  };
  
  ///
  ButtonEvent(int state, int buttons, Point pos) :
    Event(Event::BUTTON),
    state_(state), 
    buttons_(buttons), 
    pos_(pos) {};
  
  ///
  int state()  const { return state_;};
  ///
  int buttons()  const { return buttons_;};
  ///
  Point position()  const { return pos_;};

 protected:
  ///
  int state_;
  ///
  int buttons_;
  ///
  Point pos_;
};



///
class KeyEvent : public Event
{
 public:  
  ///
  enum StateType
  {
    PRESSED,
    RELEASED
  };
  ///
  KeyEvent(int key, int mod, int state) :
    Event(Event::KEY), 
    key_(key), mod_(mod), state_(state), unicode_(0) {};
  ///
  KeyEvent(int key, int mod, int state, unsigned int unicode):
    Event(Event::KEY), 
    key_(key), mod_(mod), state_(state), unicode_(unicode) {};
  ///
  int key()  const { return key_;};
  ///
  int modifier()  const { return mod_;};
  ///PRESSED or RELEASED
  int state()  const { return state_; };
  /// return the lower 7 bits of unicode_
  char ascii()  const;
  ///
  unsigned int unicode() const { return unicode_; };
 protected:
  ///
  int key_;
  ///
  int mod_;
  ///
  int state_;
  ///
  unsigned int unicode_;

};


///
class MouseEvent : public Event
{
 public:
  ///
  MouseEvent(Point pos) : Event(Event::MOUSE), pos_(pos) {};
  ///
  Point position()  const { return pos_; };

 protected:
  ///
  Point pos_;

};

///
class ResizeEvent : public Event
{
 public:
    ///
    ResizeEvent(int w, int h) : Event(Event::RESIZED), w_(w), h_(h) {};
    ///
    int width() const { return w_; };
    ///
    int height() const { return h_; };

 protected:
    /// 
    int w_;
    ///
    int h_;
};

/**convert SDL_Event to Event.
   SDL_KEYDOWN || SDL_KEYUP is mapped to KeyEvent.
   SDL_MOUSEMOTION is mapped to MouseEvent. SDL_MOUSEBUTTON* becomes
   an ButtonEvent.
*/
Event *createUEvent(const SDL_Event* event);

}

#endif // !_EVENT_H



