#ifndef _LIBTOUCH_TOUCH_H_
#define _LIBTOUCH_TOUCH_H_

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

#include <touch/structures.h>

#include <sys/types.h>
#include <sys/cdefs.h>

__BEGIN_DECLS

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

typedef void touch_callback_t(void *data, const struct touch_state *ts, const struct touch_state *last);

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

// Opens input devices, sets up filter graph and makes sure calibration is set.
// If <ptab> is not null, opened devices are added for polling.
// This call might block while the user is asked to calibrate the screen.
struct touch_filter *touch_init(struct polltable *ptab, touch_callback_t *callback, void *data);

// Opens serially attached ELO touch device
struct touch_filter *touch_init_elo(struct polltable *ptab, const char *device,
                                    touch_callback_t *callback, void *data);

// Free touch instance, releasing all resources
void touch_free(struct touch_filter *tf);

// Check for touch screen presence. Note: USB devices take about 2s to appear after plug in/startup.
int touch_exists(struct touch_filter *tf);

/****************************************************************************************************************/
//
// Low level access
//

// Create a touch handling instance.
struct touch_filter *touch_alloc(void);

// All calls to touch_open() will add their files to this polltable.
// Files that where open previously are neither added to the new table nor removed from the old.
void touch_set_ptab(struct touch_filter* tf, struct polltable *ptab);

// Set function to be called with processed events
void touch_set_callback(struct touch_filter *tf, touch_callback_t *callback, void *data);

// Reads and processes data from input device.
int touch_read(struct touch_filter *tf, int fd);

// Same as above, but can be used as a callback for polltables, "data" points to a "struct touch_filter".
int touch_poll(int fd, int revents, void *data);

// Set up size of screen (So mouse pointer cannot leave it)
void touch_set_size(struct touch_filter *tf, uint w, uint h);

// Set/get current position of mouse pointer
void touch_set_current_position(struct touch_filter *tf, const struct touch_state *ts);
const struct touch_state *touch_get_current_position(const struct touch_filter *tf);

// Processes one input event
struct input_event;
void touch_process_event(struct touch_filter *tf, const struct input_event *ie, int fd);

// Will receive the raw touch screen data before processing
// Callback may modify the touch_state structure.
void touch_set_raw_callback(struct touch_filter *tf, touch_callback_t *callback, void *data);

// Set up the default processing graph (Filter sequence)
// This call might block while the user is asked to calibrate the screen.
void touch_init_default_graph(struct touch_filter *tf);

// Initialize size of touch screen from system framebuffer
int touch_init_size(struct touch_filter *tf);

// Set/get rotation (This goes along with orientation setting in libraster)
void touch_set_orientation(struct touch_filter *tf, int orientation);
int touch_get_orientation(const struct touch_filter *tf);

/****************************************************************************************************************/
//
// Calibration values are used by calibrate and pressure drivers.
//
void touch_set_calibration(struct touch_filter *tf, const struct touch_calib *cal);
const struct touch_calib *touch_get_calibration(struct touch_filter *tf);
int touch_clear_calibration(struct touch_filter *tf);

// Restore calibration from non-volatile storage.
// If no valid calibration is found, user is asked to calibrate.
int touch_calibrate(struct touch_filter *tf);

// Unconditionally asks user to calibrate.
void touch_force_calibrate(struct touch_filter *tf);

// Restore touch calibration from non-volatile memory into provide structure
int touch_restore_calibration(struct touch_calib *cal);

/****************************************************************************************************************/
//
// Minimum pressure requirement
//
// min_pressure_pen:    Any event with a pressure value below this will be ignored
// min_pressure_finger: This value or higher will be reported as button bit 1.
//
struct touch_pressure_driver;
struct touch_pressure_driver *touch_register_pressure(struct touch_filter *tf);

/****************************************************************************************************************/
//
// Calibration
//
struct touch_calibrate_driver;
struct touch_calibrate_driver *touch_register_calib(struct touch_filter *tf);

/****************************************************************************************************************/
//
// Dejumping
//
struct touch_dejump_driver;
struct touch_dejump_driver *touch_register_dejump(struct touch_filter *tf, uint max_distance);

/****************************************************************************************************************/
//
// Weighted average
//
struct touch_weighted_driver;
struct touch_weighted_driver *touch_register_weighted(struct touch_filter *tf, uint max_distance);

/****************************************************************************************************************/
//
// Normal average
//
struct touch_average_driver;
struct touch_average_driver *touch_register_average(struct touch_filter *tf, uint depth, uint max_distance);
void touch_average_dump(struct touch_average_driver *tad);

/****************************************************************************************************************/
//
// Minimal movement
//
struct touch_minmove_driver;
struct touch_minmove_driver *touch_register_minmove(struct touch_filter *tf, uint min_distance);

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