#ifndef _SmsLib_Header
#define _SmsLib_Header

#ifndef FALSE
#	define FALSE 0
#endif
#ifndef TRUE
#	define TRUE !FALSE
#endif
#ifndef myfree
#	define myfree(x) {free(x); x = NULL;}
#endif

#ifndef SMS_MESSAGE_SIZE
#	define SMS_MESSAGE_SIZE 160
#endif

/* Struct declarations */
struct sms;
typedef struct sms Sms;
typedef void SmsMessage;

/* Different SMS Protocals */
/* Update SMSMODE_MAX below, and add *before SMS_NONE */
/* If this order changes the sms_mode_fn_pointers array in smslib.c needs to change too */
typedef enum sms_mode { SMS_GSM, SMS_SMPP, SMS_XML, SMS_SMTP, SMS_ROBOT, SMS_NONE } SMSMODE;
#define SMSMODE_MAX SMS_NONE-1

/* Callback fn states */
typedef enum sms_state { SMS_WAITING, SMS_INCOMING, SMS_ERRORCODE } SMSSTATE;

/* After calling init ALWAYS check errcode is not SMS_NO_ERROR */
Sms *sms_init(SMSMODE x, void *data, int *errcode);

/* Call this when done */
void sms_free(Sms **sms);

/* To check what mode it's in */
SMSMODE sms_mode(Sms *sms);

/* Dont call this directly */
void sms_wait_incoming(Sms *sms, SmsMessage *msg);

/* Call this to wait for incoming messages - does not return till callback returns FALSE to
   SMS_WAITING or SMS_ERRCODE */
/* WARNING: DO NOT call this fn on the same 'sms' from two DIFFERENT threads with DIFFERENT cb
   and/or cb_data params */
int sms_wait(Sms *sms, long timeout_msec, int (*cb)(Sms *, SMSSTATE, void *, void *), void *cb_data);

/* Call these to send/recv messages */
int sms_send(Sms *sms, void *data, char *from, char *to, char *message);
int sms_msg_recv(Sms *sms, SmsMessage *msg);
int sms_msg_accept(Sms *sms, SmsMessage *msg, int code, char *reason);
int sms_msg_reject(Sms *sms, SmsMessage *msg, int code, char *reason);

/* Call these to get info on messages, they return NULL on error */
/* Available before sms_msg_recv */
char *sms_msg_fromip(Sms *sms, SmsMessage *msg);
/* Available after sms_msg_recv */
char *sms_msg_from(Sms *sms, SmsMessage *msg);
char *sms_msg_to(Sms *sms, SmsMessage *msg);
char *sms_msg_body(Sms *sms, SmsMessage *msg);

/* After you are thru with the message */
void sms_msg_free(Sms *sms, SmsMessage **msg);

/* Error codes */
#define SMS_NO_ERROR		0
/* Add new smslib specific error codes here */
#define SMS_PARAM_ERROR		SMS_NO_ERROR-1
/* Each module may define errors as SMS_NO_ERROR + x */

char *sms_error(Sms *sms, int err, char *bf, int bfsz);

/* These headers all include this one (to find out about Sms struct) so these have to go at
   the bottom, well at least after the Sms struct declaration above */
#include "sms_smpp.h"
#include "sms_xml.h"
#include "sms_smtp.h"
#include "sms_gsm.h"
#include "sms_robot.h"

#endif
