
#ifndef EVENT_LOG_H_
#define EVENT_LOG_H_

#include <stdint.h>
#include "pstorage.h"
#include "event_clock.h"

#define EVENT_MAX_ENTRIES       4000

// The magic number defines the format of the event structure. 
// The number should be increased by one, whenever the structure 
// changes.
#define EVENT_MAGIC_NUMBER      1
#define EVENT_ATTR_MAGIC_NUMBER (0x12345678  | EVENT_MAGIC_NUMBER)

#define EVENT_TYPE_TURN_ON      0
#define EVENT_TYPE_TURN_OFF     1
#define EVENT_TYPE_ADJUST       2
#define EVENT_TYPE_CONNECT      3
#define EVENT_TYPE_DISCONNECT   4
#define EVENT_TYPE_LINK_LOSS    5
#define EVENT_TYPE_WDT_RESET    6

#define EVENT_ORIGIN_TOUCH      0
#define EVENT_ORIGIN_APP        1

#define EVENT_SLAVE_DISCONNECTED 0
#define EVENT_SLAVE_CONNECTED   1

#define EVENT_OLD_EVENT         0
#define EVENT_CURRENT_CYCLE     1

typedef struct {
    // Remember to take structure alignment into
    // consideration when changing the format of this struct.
    // http://stackoverflow.com/a/119128/1137383
    
    // Byte 1
	uint32_t magic_number       : 3;   // Bit: 0..2     Magic number / format of this event structure
    uint32_t origin             : 1;   // Bit: 3        Origin of the event - see EVENT_ORIGIN_*
    uint32_t type               : 3;   // Bit: 4..6     Type of event - see EVENT_TYPE_*
    uint32_t current_cycle      : 1;   // Bit: 7        From current cycle flag
    // Byte 2
    uint32_t brightness         : 7;   // Bit: 8..14    Brightness value - 0-100
    uint32_t slave_connected    : 1;   // Bit: 15       Slave connected flag
    // Byte 3-4
    //uint32_t power_cycle        : 16;  // Bit: 16..31   Power cycle number    
    uint16_t event_id           : 16;
    // Byte 5-8
    uint32_t timestamp          : 32;  // Bit: 32..63   Timestamp 
} event_log_entry_t;


typedef struct {
    // Counter for number of WDT resets
    uint32_t watchdog_counter;
    // Counter for number of power cycles.
    // Incremented on each startup
    uint32_t power_cycle_counter;   
    uint32_t event_id_counter;
    uint32_t buffer_index;
} event_log_attr_t;

typedef struct {
    pstorage_handle_t attrs_handle;
    pstorage_handle_t entries_handle;
    event_log_attr_t attrs;
    uint8_t verbose;
    // ID of the first event in the current power cycle
    uint16_t power_cycle_start_event;
} event_log_t;

// The packet format broadcasted over Bluetooth.
// The timestamp (now) is included to make the calculation
// of absolute time easier.
typedef struct {
    event_log_entry_t entry;
    uint32_t now;
} event_log_packet_t;


// Init the event logging module
uint32_t event_log_init(uint8_t reset_by_wdt);

// Stores a single event log entry in the flash
// The current index of writing is determined by
// a global index also stored in flash
void event_log_add(uint8_t origin, uint8_t type, 
    uint8_t brightness, uint8_t slave_connected);

// Returns NRF_SUCCESS when an entry has been read, or 
// NRF_ERROR_NOT_FOUND if no entry has been read
uint32_t event_log_get_next(event_log_entry_t * entry);

// Returns one if the the requested events still hasn't been sent
uint8_t event_log_has_pending_events(void);

// Send pending events (fill the transmit buffer for 
// highest possible throughput)
void event_log_send_pending_events(void);

// Stop sending events
void event_log_stop_sending(void);

// Request the lamp to send all event since the event
// with the given id
void event_log_request_events_since(uint16_t id);

#endif

