/*
 * C
 *
 * Copyright 2023 MicroEJ Corp. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be found with this software.
 */
#ifndef LLEVENT_IMPL
#define LLEVENT_IMPL

#include <intern/LLEVENT_impl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include "sni.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Initializes the event queue.
 */
void LLEVENT_IMPL_initialize(void);

/**
 * Offers an event to the queue.
 *
 * @param type the type of the event.
 * @param data the data of the event.
 * @return true if the message has been sent, false otherwise.
 */
bool LLEVENT_IMPL_offer_event(uint32_t type, uint32_t data);

/**
 * Offers an extended event to the queue.
 *
 * @param type the type of the event.
 * @param data the data of the event.
 * @return true if the message has been sent, false otherwise.
 */
bool LLEVENT_IMPL_offer_extended_event(uint32_t type, const void* data, uint32_t data_length);

/**
 * Waits for an event from the queue and returns it.
 *
 * @return the read event.
 */
uint32_t LLEVENT_IMPL_wait_event(void);

/**
 * Starts to read an extended data. Set the data_length_extended_data to the data_length and reset the offset_extended_data_read.
 */
void LLEVENT_IMPL_start_read_extended_data(uint32_t data_length);

/**
 * The Java listener finished to read the data from the event queue.
 * If there is any left data left in the queue, purge it.
 */
void LLEVENT_IMPL_end_read_extended_data(void);

/**
 * Returns the next boolean of data.
 * Throws IOException if there is no boolean remaining in the extended data.
 */
jboolean LLEVENT_IMPL_read_boolean(void);

/**
 * Returns the next byte of data.
 * Throws IOException if there is no byte remaining in the extended data.
 */
jbyte LLEVENT_IMPL_read_byte(void);

/**
 * Returns the next char of data.
 * Throws IOException if there is no char remaining in the extended data.
 */
jchar LLEVENT_IMPL_read_char(void);

/**
 * Returns the next double of data.
 * Throws IOException if there is no double remaining in the extended data.
 */
jdouble LLEVENT_IMPL_read_double(void);

/**
 * Returns the next float of data.
 * Throws IOException if there is no float remaining in the extended data.
 */
jfloat LLEVENT_IMPL_read_float(void);

/**
 * Reads len bytes of data from the event queue and store it into the buffer at the offset off.
 * Returns the total number of bytes read into the buffer.
 * Throws IOException if there are not enough bytes available or if the buffer is too small.
 */
jint LLEVENT_IMPL_read(uint8_t* b, uint32_t off, uint32_t len);

/**
 * Returns the next integer of data.
 * Throws IOException if there is no integer remaining in the extended data.
 */
jint LLEVENT_IMPL_read_int(void);

/**
 * Returns the next long of data.
 * Throws IOException if there is no long remaining in the extended data.
 */
jlong LLEVENT_IMPL_read_long(void);

/**
 * Returns the next short of data.
 * Throws IOException if there is no short remaining in the extended data.
 */
jshort LLEVENT_IMPL_read_short(void);

/**
 * Returns the next unsigned byte of data.
 * Throws IOException if there is no unsigned byte remaining in the extended data.
 */
jboolean LLEVENT_IMPL_read_unsigned_byte(void);

/**
 * Returns the next unsigned short of data.
 * Throws IOException if there is no unsigned short remaining in the extended data.
 */
jchar LLEVENT_IMPL_read_unsigned_short(void);

/**
 * Skips n bytes.
 * Returns -1 if it did not work.
 */
jint LLEVENT_IMPL_skip_bytes(uint32_t n);

/**
 * Gets the number of available data bytes.
 * Returns the number of available data bytes.
 */
uint32_t LLEVENT_IMPL_available(void);

#ifdef __cplusplus
}
#endif

#endif // LLEVENT_IMPL
