#ifndef _SERVER_H_
#define _SERVER_H_

#include "myc_buf.h"

void CocVarList(void **varlist);
/*
  instal a variable list
*/

void CocFreeVarList(void);
/*
  free variable list
*/

void *CocFindVar(const char *name, void **adr);
/*
  find a variable. returns NULL if not found.
*/

int CocPutVar(const char *name, StrBuf *buf, int separator);
/*
  put a variable named <name> of variable list <varList> to the buffer <buf>
*/

int CocGetVar(const char *name, StrBuf *buf, int separator);
/*
  get a variable named <name> of variable list <varList> from the buffer <buf>
*/

char *CocReadVars(char *str, char stop);
/*
  read variables from the string str until a word starts with the stop character
  the string has the form [ whitespace var=value ] whitespace stop-character
  any text between an exclamation character and the next line break is treated as comment
*/

void CocHdl(int (*handler)(int, void *, int));
/*
  define handler for last defined item
*/

int *CocSizePtr(void);
/*
  get size pointer from last defined item (only valid when an array)
*/

void *CocIntPtr(int *ptr);
void *CocFltPtr(float *ptr);
void *CocChrPtr(char *ptr);
void *CocDefVar(const char *name, void *var, int type, int size, int access);
void CocDefVarS(const char *name, const char *tname, void *var, int type);
/*
  Define variables. Call this routines not directly, but through
  one of the macros below.
*/

#define CocDefInt(V,A)      CocDefVar(#V,CocIntPtr(&V),COC_INT,0,A)
#define CocDefFlt(V,A)      CocDefVar(#V,CocFltPtr(&V),COC_FLT,0,A)
#define CocDefStr(V,A)      CocDefVar(#V,CocChrPtr(V),COC_CHAR,sizeof(V),A)
#define CocDefArr(V,A)      CocDefVar(#V,CocFltPtr(V),COC_ARRAY,sizeof(V)/sizeof(float),A)
#define CocDefPtr(V,S)      CocDefVarS(#V,#S,&V,((V!=(S *)NULL)*0+COC_PTR));
#define CocDefStruct(V,S)   CocDefVarS(#V,#S,&V,((&V!=(S *)NULL)*0+COC_STRUCT));
#define CocIntFld(S,V,A)    CocDefVar(#S":"#V,CocIntPtr(&((S *)NULL)->V),COC_INT,0,A);
#define CocFltFld(S,V,A)    CocDefVar(#S":"#V,CocFltPtr(&((S *)NULL)->V),COC_FLT,0,A);
#define CocStrFld(S,V,A)    CocDefVar(#S":"#V,CocChrPtr(((S *)NULL)->V),COC_CHAR,sizeof(((S *)NULL)->V),A);
#define CocArrFld(S,V,A)    CocDefVar(#S":"#V,CocFltPtr(((S *)NULL)->V),COC_FLT,sizeof(((S *)NULL)->V)/sizeof(float),A);
#define CocAlias(A,V)       CocDefVar(#A, #V, COC_ALIAS,0,0);

#define COC_RDONLY 3
#define COC_RDWR 2
#define COC_RDWRALL 1

#define COC_WR 1
#define COC_RD 2
#define COC_DWR 3
#define COC_DRD 4
#define COC_SHOW 5

#define COC_CHAR 1
#define COC_INT 2
#define COC_FLT 3
#define COC_ARRAY 4
#define COC_PTR 5
#define COC_STRUCT 6
#define COC_TYPE 7
#define COC_ALIAS 8

int CocInitServer(void *(*setDataRtn)(void *), int port);

int CocHandleRequests(int tmo_msec, int fd);
int CocHandle1Request(int tmo_msec, int fd);
/*
  handle hetwork requests.

  return value: <0: error
                =0: timeout
                =1: event on fd
                =2: variable was changed
                =3: other network request treated

  CocHandle1Request handles only one network request

  For CocHandleRequests:

  if fd=0: returns when a network request has changed a variable,
           or when timeout has expired (result is 0 or 2)

  if fd>0: returns when an read event is pending on fd
           or when timeout has expired (result is 0 or 1)

*/

/* server handlers removed
int CocPushHandler(const char *name);
*/

int CocCallHandlers(void);
void CocShowHandlers(char *buf, int buf_len);

void CocCloseServer(void);

#endif /* _SERVER_H_ */
