
#ifndef _SIC_COMM_H_
#define _SIC_COMM_H_

/**
 * @file
 * @see sic_comm.c
 */

/***************************************************************************** 
 *                              Dependencies                                 * 
 *****************************************************************************/

#ifndef WIN32
#if !defined(linux)
#define _XOPEN_SOURCE 600
#endif
#include "sys/types.h"
#else
#include <pthread.h>
#include "gsys/win32.h"
#endif
#include <signal.h>
#include <stdarg.h>

#include "gcommand_line.h"
#include "gwidget.h"

/***************************************************************************** 
 *                          Macros & Definitions                             * 
 *****************************************************************************/

/** platform independant definition of signal handler */
#if defined(cygwin)
typedef _sig_func_ptr sic_sighandler_t;
#elif defined(darwin) || defined(WIN32)
typedef void (* sic_sighandler_t)(int);
#else
typedef __sighandler_t sic_sighandler_t;
#endif

/** platform independant definition of task */
//#ifndef WIN32
#define _SIC_USE_PTHREAD
typedef pthread_t sic_task_t;
typedef int task_id_t;
//#else
//typedef HANDLE sic_task_t;
//typedef DWORD task_id_t;
//#endif
#define SIC_TASK_NULL ((sic_task_t)0)
#define SIC_TASK_NOT_NULL ((sic_task_t)1)

typedef global_struct sic_widget_def_t;
/** Listener type for modified_variable event */
typedef void (*sic_modified_variable_listener_t)( int widget_index, sic_widget_def_t *widget, void *data);
/** Listener type for redraw_prompt event */
typedef void (*sic_redraw_prompt_listener_t)( command_line_t *command_line);
/** Listener type for exit event */
typedef void (*sic_exit_listener_t)( void);

/** Enum to identify the type of caller which post a command */
typedef enum {
    /** command sent by an undefined caller */
    SIC_DEFAULT,
    /** command sent by the keyboard */
    SIC_KEYBOARD,
    /** command sent in silent mode (without echo) */
    SIC_SILENT_MODE,
    /** command sent from a child exiting on error */
    SIC_CHILD_EXIT,
    /** command sent in synchronous and silent mode (without echo) */
    SIC_SYNCHRONOUS_MODE,
} sic_command_from_t;

/***************************************************************************** 
 *                           Function prototypes                             * 
 *****************************************************************************/

void sic_create_comm_board( void);
void sic_destroy_comm_board( void);
sic_task_t sic_create_thread( int (*start_entry)( void *), void *data);
char **sic_get_static_argv( void);
int sic_execvp( char *argv[]);
sic_task_t sic_launch( int (*start_entry)( void *), void *data);
int sic_terminate( sic_task_t task);
void sic_on_exit( void);
void sic_do_exit( int status);
int sic_get_comm_id( void);
int sic_open_comm_board( int comm_board_id);
void sic_close_comm_board( void);
task_id_t sic_get_task_id( sic_task_t task);
sic_task_t sic_get_master_task( void);
task_id_t sic_get_master_task_id( void);
sic_task_t sic_get_current_task( void);
task_id_t sic_get_current_task_id( void);
void sic_send_ctrlc( void);
void sic_kill_master_task( void);
void sic_enable_prompt( void);
void sic_disable_prompt( void);
void sic_post_prompt( const command_line_t *command_line);
void sic_post_prompt_text( const char *prompt);
int sic_wait_prompt( command_line_t *command_line, int timeout);
void sic_get_current_prompt( char prompt[]);
int sic_push_command_text( const char *text);
int sic_post_command_from( const command_line_t *command_line, sic_command_from_t from);
int sic_post_command( const command_line_t *command_line);
void sic_post_command_from_prompt( const command_line_t *command_line);
int sic_post_command_text_from( const char *text, sic_command_from_t from);
int sic_post_command_text( const char *text);
int sic_post_command_va( const char *args, va_list l);
int sic_post_command_args( const char *args, ...);
void sic_wait_command( command_line_t *command_line, sic_command_from_t *from);
void sic_create_widget_board( void);
void sic_set_widget_global_infos( const char window_title[], const char help_filename[], const char returned_command[]);
void sic_set_widget_returned_command( const char returned_command[]);
void sic_get_widget_returned_command( char returned_command[]);
void sic_set_widget_returned_code( int code);
int sic_get_widget_returned_code( void);
void sic_add_modified_variable_listener( sic_modified_variable_listener_t l, void *data);
void sic_fire_modified_variable_event( int index, const sic_widget_def_t *widget);
void sic_add_redraw_prompt_listener( sic_redraw_prompt_listener_t l);
void sic_fire_redraw_prompt_event( const command_line_t *command_line);
void sic_add_exit_listener( sic_exit_listener_t l);
void sic_fire_exit_event( void);
void sic_suspend_prompt( sic_command_from_t from);
int sic_add_widget_def( sic_widget_def_t *def);
void sic_set_widget_def( int index, const sic_widget_def_t *widget);
void sic_destroy_widget_board( void);
int sic_open_widget_board( void);
void sic_get_widget_global_infos( char window_title[], char help_filename[], char returned_command[]);
void sic_get_widget_def( int index, sic_widget_def_t *widget);
void sic_close_widget_board( void);
void sic_post_widget_created( void);
void sic_wait_widget_created( void);
void sic_open_event_stack( void);
void sic_close_event_stack( void);
int sic_sem_create_index( unsigned int initial_value);
void sic_sem_post_index( int index);
void sic_sem_wait_index( int index);
void sic_get_alarm( char *alarm);
void sic_set_alarm( char *alarm);

#endif /* _SIC_COMM_H_ */
