#ifndef IOS_ASYNC_H_
#define IOS_ASYNC_H_
/*---------------------------------------------------------------------------*/
/* ios_async.h                                                               */
/* copyright (c) innovaphone 2015                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

NAMESPACE_BEGIN

#ifdef __cplusplus
extern "C" {
#endif

#define IOS_ASYNC_QUEUE_SIZE_EXP    14
#define IOS_ASYNC_QUEUE_SIZE        (1 << IOS_ASYNC_QUEUE_SIZE_EXP)
#define IOS_ASYNC_QUEUE_MASK        (~(0xffffffff << IOS_ASYNC_QUEUE_SIZE_EXP))
#define IOS_ASYNC_MAX_PACKET_SIZE   300000

typedef union tag_ios_async_queue_arg {
    bool z;
    int i;
    char *a;
    byte *b;
#if !defined(PLATFORM_NO_PACKET)
    void *p;
#endif
} t_ios_async_queue_arg;

struct tag_ios_async_handler {
    const char *method;
    const char *format;
    intp selector;
};

typedef struct tag_ios_async_handler t_ios_async_handler;

extern volatile t_ios_async_queue_arg *ios_async_queue;

extern volatile dword ios_async_in_doorbell;
extern dword ios_async_in_doorbell_ack;
extern volatile dword ios_async_out_doorbell;
extern dword ios_async_out_doorbell_ack;

#if !defined(PLATFORM_NO_PACKET)
int ios_async_get_packet (void *packet, byte *buffer, int buffer_len);
#endif
void phone_ios_async_signal_handler();

#ifdef __cplusplus
}
#endif
/*---------------------------------------------------------------------------*/
#if defined(__cplusplus)

class ios_async
{
    t_ios_async_handler *handler_table;
    unsigned int handler_count;
#if !defined(PLATFORM_NO_PACKET)
    const char          * main_module;
    class serial        * main;
#endif

    dword queue_free;

public:
#if !defined(PLATFORM_NO_PACKET)
    bool packet_pending;
    void packet_processed();
#endif

    bool init(t_ios_async_handler *handler_table, unsigned int handler_count, const char *main_module);
    void enqueue(unsigned int method, ...);
    unsigned int lookahead();
#if !defined(PLATFORM_NO_PACKET)
    void set_checked();
#endif
};

#endif /* defined(__cplusplus) */
/*---------------------------------------------------------------------------*/

NAMESPACE_END

/*---------------------------------------------------------------------------*/
#endif /* IOS_ASYNC_H_ */
