#ifndef LIBTOUCH_TOUCH_CPP_H /********************************************************************* -*- c++ -*- */
#define LIBTOUCH_TOUCH_CPP_H

/****************************************************************************************************************/

#include <touch/structures.h>

#include <sys/types.h>
#include <emb/object.h>
#include <emb/events.h>

/****************************************************************************************************************/
//
// High level API
//
struct touch_filter;

class Touch : public Object {
public:
  Touch(Object *par = 0, const char *n = 0);
  ~Touch();

public:
  // Initialize touch handling instance.
  // Opens input devices, sets up filter graph and makes sure calibration is set.
  // This call might block while the user is asked to calibrate the screen.
  bool init(void);

  // Add raw input device
  bool openDevice(const char *dev);

public:
  // Enable processing of raw events
  void enableRawEvents(bool flag);

  // Restore calibration from non-volatile storage.
  // If no valid calibration is found, user is asked to calibrate.
  void calibrate(void);

  // Unconditionally asks user to calibrate.
  void forceCalibrate(void);

public: // Callback
  // Can be reimplemented to process touch events.
  // Default implementation sends a touchEvent to parent.
  virtual void touchEvent(const struct touch_state *ts, const struct touch_state *last);

  // Can be reimplemented to process low level events.
  // Default implementation sends a rawTouchEvent to parent.
  virtual void rawEvent(const struct touch_state *ts, const struct touch_state *last);

private:
  struct touch_filter *m_touch;
};

/****************************************************************************************************************/

class TouchEvent : public Event {
public:
  TouchEvent(int type, const struct touch_state *current_state, const struct touch_state *last_state);

public:
  int x(void) const        { return ts->x;        }
  int y(void) const        { return ts->y;        }
  int pressure(void) const { return ts->pressure; }
  uint buttons(void) const { return ts->buttons;  }

public:
  const struct touch_state *state(void) const     { return ts;   }
  const struct touch_state *lastState(void) const { return last; }

private:
  const struct touch_state *ts;
  const struct touch_state *last;
};

/****************************************************************************************************************/
#endif
