/*
    select.h - Main application loop
    Copyright (C) 2011 Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/

#ifndef __ZSELECT_H
#define __ZSELECT_H

#include <libziaint.h>

#ifdef Z_HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif

#ifdef Z_HAVE_SIGNAL_H
#include <signal.h>
#endif

#ifdef Z_HAVE_SYS_TIME_H
#include <sys/time.h>
#endif

#ifdef Z_HAVE_WINSOCK2_H
#include <winsock2.h>
#endif

#ifndef FD_SETSIZE
#define FD_SETSIZE 1024
#endif

#include <zsock.h>


typedef long ztime;
struct zselect;

struct zselect *zselect_init(void (*redraw)(void));
void zselect_free(struct zselect *zsel);

ztime zselect_time(void);
int zselect_bh_new(struct zselect *zsel, void (*fce)(void *arg), void *arg);
void zselect_bh_check(struct zselect *zsel);
/*#ifdef LEAK_DEBUG_LIST
int debug_install_timer(char *file, int line, ttime, void (*)(void *), void *arg, char *fname); 
#define install_timer(x, y, z) debug_install_timer(__FILE__, __LINE__, x, y, z, #y)
void debug_kill_timer(char *file, int line, int timer_id);
#define kill_timer(x) debug_kill_timer(__FILE__, __LINE__, x)
void debug_set_handlers(char *file, int line, 
        int, 
        void (*)(void *), void (*)(void *), void (*)(void *), 
        void *arg, 
        char *read_fname, char *write_fname, char *error_fname);
#define set_handlers(n, r, w, x, a) debug_set_handlers(__FILE__, __LINE__, n, r, w, x, a, #r, #w, #x);
#else                       */
#define zselect_timer_new(zsel, ztime, fn, arg) zselect_timer_new_dbg((zsel), (ztime), (fn), (#fn), arg) 
int zselect_timer_new_dbg(struct zselect *zsel, ztime, void (*)(void *), char *fname, void *arg); /* todo argument callbacku */
int zselect_timer_new_at(struct zselect *zsel, struct timeval *at, void (*)(void *), void *arg);
void zselect_timer_kill(struct zselect *zsel, int);
#define zselect_set(zsel, fd, read_fn, write_fn, error_fn, arg) zselect_set_dbg((zsel), (fd), (read_fn), (#read_fn), (write_fn), (#write_fn), (error_fn), (#error_fn), (arg))
void zselect_set_dbg(struct zselect *zsel, int, void (*)(void *), char *, void (*)(void *), char *, void (*)(void *), char *, void *arg);
void zselect_set_read(struct zselect *zsel, int fd, void (*write_func)(void *), void *arg);
void zselect_set_write(struct zselect *zsel, int fd, void (*write_func)(void *), void *arg);
//#enndif
ztime zselect_timer_get(struct zselect *zsel, int id);
void zselect_loop(struct zselect *zsel);
void zselect_terminate(struct zselect *zsel);
int zselect_terminating(struct zselect *zsel);
//void zselect_check_heap(void);

//tODO
//void debug_set_handlers(char *file, int line, int, void (*)(void *), void (*)(void *), void (*)(void *), void *arg);
//#define set_handlers(n, r, w, x, a) debug_set_handlers(__FILE__, __LINE__, n, r, w, x, a);

#define H_READ  0
#define H_WRITE 1
#define H_ERROR 2
#define H_DATA  3

typedef void (*ZSELECT_HANDLER)(void *);

void *zselect_get(struct zselect *zsel, int fd, int typ);
#ifdef Z_UNIX_ANDROID
void zselect_signal_set(int, void (*)(void *, siginfo_t *, void *), void *, int);
#endif


int zselect_msg_send(struct zselect *zsel, char *fmt, ...);
int zselect_msg_set(struct zselect *zsel, void (*handler)(struct zselect *, int n, char **items));
int zselect_msg_send_raw(struct zselect *zsel, char *s);


void zselect_start_profile(struct zselect *zsel, double limit);                      
void zselect_hint(struct zselect *zsel, const char *fmt, ...);
void zselect_handle_profile(struct zselect *zsel, struct timeval *start, void *fce, char *fname); 
int zselect_profiling(struct zselect *zsel);

void zselect_abort_exception(void *arg);
#ifdef Z_UNIX_ANDROID
void zselect_sigterm(void *arg, siginfo_t *siginfo, void *ctx);
#endif

void zselect_signal_init(void);
                                                                                  
/*struct zselect_profile{                                                            
void *fce;                                                                        
int calls;                                                                        
double maxtime;                                                                   
double tottime;                                                                   
};*/                                                                                 





#endif
