/*
linphone
Copyright (C) 2000  Simon MORLAT (simon.morlat@free.fr)

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#ifndef LINPHONECORE_H
#define LINPHONECORE_H

#include <sndcard.h>
#undef PACKAGE
#undef VERSION
#include <osipua.h>
#undef PACKAGE
#undef VERSION

#include <config.h>

#include <libintl.h>
#ifndef _
#define _(String) gettext(String)
#endif

#ifdef HAVE_GLIB
#include <glib.h>
#else
#include <uglib.h>
#endif




#ifdef __cplusplus
extern "C" {
#endif

#ifndef PayloadType_defined
#define PayloadType_defined
typedef struct _PayloadType PayloadType;
#endif

gboolean payload_type_enabled(struct _PayloadType *pt);
gboolean payload_type_usable(struct _PayloadType *pt);
void payload_type_set_enable(struct _PayloadType *pt,gint value);
void payload_type_set_usable(struct _PayloadType *pt,gint value);
gchar *payload_type_get_description(struct _PayloadType *pt);
gint payload_type_get_bitrate(PayloadType *pt);
const gchar *payload_type_get_mime(PayloadType *pt);
gint payload_type_get_rate(PayloadType *pt);



#define CONNECTION_TYPE_28KMODEM 0
#define CONNECTION_TYPE_56KMODEM 1
#define CONNECTION_TYPE_NUMERIS 2
#define CONNECTION_TYPE_ADSL 3
#define CONNECTION_TYPE_ETHERNET 4

extern const double bandwidths[5];

typedef struct registrar_config
{
	char *registrar;	/*or proxy */
	char *passwd;
	char *addr_of_rec;
	guint expires;
	GTimer *timer;
	guint32 use_registrar:1;		/* general flag */
	guint32 as_proxy:1;			/* is the registrar also an outbound proxy */
	guint32 padding:30;
} registrar_config_t;

typedef struct sip_config
{
	char *contact;
	char *username;
	char *hostname;
	registrar_config_t reg_conf;
	gint sip_port;
} sip_config_t;

typedef struct rtp_config
{
	guint16 audio_rtp_port;
	guint16 video_rtp_port;
	gint audio_jitt_comp;  /*jitter compensation*/
	gint video_jitt_comp;  /*jitter compensation*/
}rtp_config_t;

typedef struct _interface_t
{
	char name[20];
#ifdef INET6
	int  family;
	char ipaddr[40];
#else
	char ip4addr[20];
#endif
	int index;
} interface_t;

typedef struct net_config
{
	GList *interfaces;	/* list of interface_t */
	interface_t *sel_if;
	double bandwidth; 		/* the bandwidth in bit/s of the selected interface*/ /*unused*/
	gchar *nat_address;
	gboolean use_nat;
	gint con_type;			/* type of connection 28k 56k 128k adsl ...*/
}net_config_t;


typedef struct sound_config
{
	SndCard *sndcard;	/* the sndcard currently used */
	gint dev_id;		/* sound device id */
	gint latency;	/* latency in samples of the current used sound device */
	char rec_lev;
	char play_lev;
	char source;
	char pad;
	char *local_ring;
	char *remote_ring;
	int autokill:1;  /* 1= automatically free access to sound device by killing artsd and esd*/
} sound_config_t;

typedef struct codecs_config
{
	GList *audio_codecs;  /* list of audio codecs in order of preference*/
	GList *video_codecs;	/* for later use*/
}codecs_config_t;

typedef struct video_config{
	int enabled:1;
	int show_local:1;
	int pad:30;
}video_config_t;

typedef struct ui_config
{
	GList *address_list;
	int is_daemon;
	int is_applet;
	guint timer_id;  /* the timer id for registration */
}ui_config_t;



typedef struct autoreplier_config
{
	gint enabled;
	gint after_seconds;		/* accept the call after x seconds*/
	gint max_users;			/* maximum number of user that can call simultaneously */
	gint max_rec_time;  	/* the max time of incoming voice recorded */
	gint max_rec_msg;		/* maximum number of recorded messages */
	gchar *message;		/* the path of the file to be played */
}autoreplier_config_t;

typedef struct _StreamParams
{
	int initialized;
	int line;
	int localport;
	int remoteport;
	char *remoteaddr;
	int pt;
} StreamParams;

typedef struct _LinphoneDialogParams
{
	StreamParams audio_params;
	StreamParams video_params;
	struct _RtpProfile *profile;	/*points to the local_profile or to the remote "guessed" profile*/
} LinphoneDialogParams;

LinphoneDialogParams * linphone_dialog_params_new();
void linphone_dialog_params_destroy(LinphoneDialogParams *obj);
struct _LinphoneCore;

typedef void (*ShowInterfaceCb)(struct _LinphoneCore *lc);
typedef void (*InviteReceivedCb)(struct _LinphoneCore *lc, char *from);
typedef void (*ByeReceivedCb)(struct _LinphoneCore *lc, char *from);
typedef void (*DisplayStatusCb)(struct _LinphoneCore *lc, char *message);
typedef void (*DisplayMessageCb)(struct _LinphoneCore *lc, char *message);
typedef void (*DisplayUrlCb)(struct _LinphoneCore *lc, char *message,char *url);
typedef void (*DisplayQuestionCb)(struct _LinphoneCore *lc, char *message);
typedef void (*LinphoneCoreCbFunc)(struct _LinphoneCore *lc,gpointer user_data);
typedef void (*NotifyReceivedCb)(struct _LinphoneCore *lc, const char *url, const char *status);

typedef struct _LinphoneVTable
{
	ShowInterfaceCb show;
	InviteReceivedCb inv_recv;
	ByeReceivedCb bye_recv;
	NotifyReceivedCb notify_recv;
	DisplayStatusCb display_status;
	DisplayMessageCb display_message;
	DisplayMessageCb display_warning;
	DisplayUrlCb display_url;
	DisplayQuestionCb display_question;
} LinphoneCoreVTable;

typedef struct _LCCallbackObj
{
  LinphoneCoreCbFunc _func;
  gpointer _user_data;
}LCCallbackObj;


typedef struct _LinphoneCore
{
	LinphoneCoreVTable vtable;
	net_config_t net_conf;
	sip_config_t sip_conf;
	rtp_config_t rtp_conf;
	sound_config_t sound_conf;
	video_config_t video_conf;
	codecs_config_t codecs_conf;
	ui_config_t ui_conf;
	autoreplier_config_t autoreplier_conf;
	struct _RingStream *ringstream;
	LCCallbackObj preview_finished_cb;
	gboolean preview_finished;
	OsipUA *ua;			/* the osip user agent*/
	OsipDialog *call;   /* the current dialog, in the future it will be a list of dialog (conferencing)*/
	GList *queued_calls;	/* used by the autoreplier */
	BodyHandler *sdph;	/* the sdp handler */
	struct _AudioStream *audiostream;  /**/
	transaction_t *current_trn;	/* REVISIT LATER */
	struct _RtpProfile *local_profile;
	int in_main_thread;
	void *data;
	GMutex *lock;
} LinphoneCore;


LinphoneCore *linphone_core_new(LinphoneCoreVTable *vtable,
						gchar *config_path, gpointer userdata);

void linphone_core_init(LinphoneCore *lc,LinphoneCoreVTable *vtable,
						gchar *config_path, gpointer userdata);

int linphone_core_set_primary_contact(LinphoneCore *lc, gchar *contact);

gchar *linphone_core_get_primary_contact(LinphoneCore *lc);

from_t *linphone_core_get_primary_contact_parsed(LinphoneCore *lc);


#ifdef LINPHONE_DEPRECATED
GList * linphone_core_get_net_interfaces(LinphoneCore *lc);

interface_t * linphone_core_get_selected_interface(LinphoneCore *lc);

#ifdef INET6
void linphone_core_select_net_interface(LinphoneCore *lc, gint index);
#else
void linphone_core_select_net_interface(LinphoneCore *lc, gchar *ifname);
#endif

#endif

void linphone_core_set_connection_type(LinphoneCore *lc, int type);

int linphone_core_get_connection_type(LinphoneCore *lc);

int linphone_core_invite(LinphoneCore *lc, char *url);

gboolean linphone_core_inc_invite_pending(LinphoneCore*lc);

int linphone_core_accept_dialog(LinphoneCore *lc, const char *url);

int linphone_core_terminate_dialog(LinphoneCore *lc, const char *url);

void linphone_core_send_dtmf(LinphoneCore *lc,gchar dtmf);

/* returns a GList of MSCodecInfo */
GList *linphone_core_get_audio_codecs(LinphoneCore *lc);

int linphone_core_set_audio_codecs(LinphoneCore *lc, GList *codecs);

/* returns a GList of MSCodecInfo */
GList *linphone_core_get_video_codecs(LinphoneCore *lc);

int linphone_core_set_video_codecs(LinphoneCore *lc, GList *codecs);

GList * linphone_core_get_address_list(LinphoneCore *lc);

int linphone_core_set_address_list(LinphoneCore *lc, GList *addresses);

char *linphone_core_get_registrar_addr(LinphoneCore *lc);

char *linphone_core_get_registrar_passwd(LinphoneCore *lc);

void linphone_core_set_registrar_passwd(LinphoneCore *lc, gchar *passwd);

char *linphone_core_get_addr_of_rec(LinphoneCore *lc);

int linphone_core_set_registrar_addr(LinphoneCore *lc, char *url,char*addr_of_rec);

int linphone_core_register(LinphoneCore *lc, char *url);

void linphone_core_get_registrar_usage(LinphoneCore *lc, gboolean *enabled, gboolean *as_proxy, gint*expires);

void linphone_core_set_registrar_usage(LinphoneCore *lc, gboolean enabled, gboolean as_proxy, gint expires);

int linphone_core_get_audio_jittcomp(LinphoneCore *lc);

int linphone_core_get_audio_port(LinphoneCore *lc);

void linphone_core_set_audio_jittcomp(LinphoneCore *lc, int value);

void linphone_core_set_audio_port(LinphoneCore *lc, int port);

int linphone_core_get_sip_port(LinphoneCore *lc);

void linphone_core_set_sip_port(LinphoneCore *lc,int port);

void linphone_core_set_nat_address(LinphoneCore *lc, gchar *addr, gboolean use);

gchar *linphone_core_get_nat_address(LinphoneCore *lc, gboolean *use);

void linphone_core_force_ip_address(LinphoneCore *lc, gchar *ipaddr);

/* function to be periodically called in a main loop */
void linphone_core_iterate(LinphoneCore *lc);

/* sound functions */
SndCardManager * linphone_core_get_card_manager(LinphoneCore *lc);
gint linphone_core_get_play_level(LinphoneCore *lc);
gint linphone_core_get_rec_level(LinphoneCore *lc);
void linphone_core_set_play_level(LinphoneCore *lc, gint level);
void linphone_core_set_rec_level(LinphoneCore *lc, gint level);
gint linphone_core_get_sound_device(LinphoneCore *lc);
gint linphone_core_set_sound_device(LinphoneCore *lc, gint devid);
gint linphone_core_set_sound_device_from_name(LinphoneCore *lc,gchar *name);
gchar linphone_core_get_sound_source(LinphoneCore *lc);
void linphone_core_set_sound_source(LinphoneCore *lc, gchar source);
void linphone_core_set_ring(LinphoneCore *lc,gchar *path);
gchar *linphone_core_get_ring(LinphoneCore *lc);
gint linphone_core_preview_ring(LinphoneCore *lc, const gchar *ring,LinphoneCoreCbFunc func,gpointer userdata);
typedef enum {RINGBACK_TYPE_FR,RINGBACK_TYPE_US} RingBackType;
void linphone_core_set_ringback(LinphoneCore *lc,RingBackType type);
RingBackType linphone_core_get_ringback(LinphoneCore *lc);

void linphone_core_set_presence_info(LinphoneCore *lc,gint minutes_away,
													gchar *contact,
													int presence_mode);

#define linphone_core_is_in_main_thread(lc)	((lc)->in_main_thread)

void linphone_core_uninit(LinphoneCore *lc);
void linphone_core_destroy(LinphoneCore *lc);

/*internal use only */
#define linphone_core_thread_enter(lc) (lc)->in_main_thread=0
#define linphone_core_thread_leave(lc) (lc)->in_main_thread=1
#define linphone_core_lock(lc)	g_mutex_lock((lc)->lock)
#define linphone_core_unlock(lc)	g_mutex_unlock((lc)->lock)

#ifdef __cplusplus
}
#endif

#endif
