#ifndef _LIBKEYBOARD_KEYBOARD_H_
#define _LIBKEYBOARD_KEYBOARD_H_

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

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

#include <keyboard/scancodes.h>
#include <keyboard/event.h>

#include <core/keypad.h>

/****************************************************************************************************************/
//
// High level API
//
__BEGIN_DECLS

struct keyboard;
struct input_event;
struct polltable;

// Create a keyboard handling instance and open input devices.
// If <ptab> is not null, opened devices are added for polling.
typedef void keyboard_callback_t(const struct keyboard_event *ev, void *data);
struct keyboard *keyboard_init(struct polltable *ptab, keyboard_callback_t *callback, void *data);

// Select layout, for country codes, see below.
void keyboard_set_country(struct keyboard *kbd, int country);

// Close keyboard device and all handles
void keyboard_free(struct keyboard *kbd);

// Set LEDs of keyboard to passed value
// If <leds> is -1, then the LEDs are set according to current modifier bits.
void keyboard_set_leds(struct keyboard *kbd, int leds);

// Enable/disable key click
void keyboard_set_click(struct keyboard *kbd, int enabled);

// Discard data already buffered
void keyboard_drain(struct keyboard *kbd);

__END_DECLS

/****************************************************************************************************************/
//
// Low level API
//
__BEGIN_DECLS

// Create a keyboard instance
struct keyboard *keyboard_alloc(void);

// Open an input device for reading keyboard events and return hadle
int keyboard_open(struct keyboard *kbd, const char *device);

// All calls to keyboard_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 keyboard_set_ptab(struct keyboard *kbd, struct polltable *ptab);

// Returns fd of keyboard device, for throwing a poll() call at.
uint keyboard_fd_count(const struct keyboard *kbd);
int keyboard_fd(const struct keyboard *kbd, uint idx);

// Set up callback.
void keyboard_set_callback(struct keyboard *kbd, keyboard_callback_t *handler, void *data);

// Reads data from keyboard device. Calls back handler for each key pressed.
int keyboard_process(struct keyboard *kbd, int fd);

// Same as above, but can be used as a callback for polltables.
int keyboard_poll(int fd, int revents, void *data);

// Set translation map for matrix keypad
struct keyboard_map {
  unsigned int scancode;
  unsigned int unicode;
};

int keyboard_setmap(struct keyboard *kbd, const struct keyboard_map *map, size_t count);

// Set up pins used for matrix and wheel reports
int keyboard_setmatrix(struct keyboard *kbd, const struct keypad_matrix *mx);
int keyboard_setwheel(struct keyboard *kbd, const struct keypad_wheel *wh);
int keyboard_setbutton(struct keyboard *kbd, const struct keypad_button *btn);

__END_DECLS

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

__BEGIN_DECLS

// Manually feed input events to the keyboard processor. Calls back handler for each key pressed.
void keyboard_process_event(struct keyboard *kbd, const struct input_event *ie);

// Manually decode a scancode into unicode
int keyboard_decode(struct keyboard *kbd, uint scancode);

__END_DECLS

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