/**
 * linphonewrap.c
 *
 * Philippe G. Khalaf 2004
 *
 * This program is based on Wang, Zhanglei's linphone wrapper for Gaim
 * brings linphone to the tcl world (tcl bindings for linphone) * 
 * 
 * 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
 */

/*#ifdef HAVE_CONFIG_H
#include "config.h"
#endif*/


#include "linphone_config.h"
#include <linphonecore.h>

#include "linphonewrap.h"


//working around with linphone header files
#define HAVE_GLIB 1

/*static LinphoneCore linphonec;
static int initialized;
*/
void dummy_log_handler (const gchar * log_domain, GLogLevelFlags log_level, const gchar * message, gpointer user_data)
{
      printf("%s:(GLogLevel=%i)** %s\n", log_domain, log_level, message);
}
/*
void sipomatic_log_handler (const gchar * log_domain, GLogLevelFlags log_level, const gchar * message, gpointer user_data)
{
	printf("%s:(GLogLevel=%i)** %s\n", log_domain, log_level, message);
}


void linphonec_display_something (LinphoneCore * lc, char *something)
{
	fprintf (stdout, "%s\n", something);
}

void linphonec_display_warning (LinphoneCore * lc, char *something)
{
	fprintf (stdout, "Warning: %s\n", something);
}

void linphonec_display_url (LinphoneCore * lc, char *something, char *url)
{
	fprintf (stdout, "Warning: %s - %s\n", something, url);
}
*/

void display(struct _LinphoneCore *lc, char * str)
{
	fprintf (stdout, "%s\n", str);
}

void stub(struct _LinphoneCore *lc)
{
}

static gboolean linphone_initialized = FALSE;
static LinphoneCore lc;
static LinphoneCoreVTable vtable =
{
	stub,
	display,
	display,
	display,
	display,
	display,
	display,
	display
};


int linphone_wrap_init(clientData, interp, argc, argv)
	ClientData clientData;	/* Not used. */
	Tcl_Interp *interp;		/* Current interpreter */
	int argc;			/* Number of arguments */
	char *argv[];		/* Argument strings */
{
	fprintf (stdout, "gsfdgfgf\n");

	if (linphone_initialized)
		return -1;
	else
	{
		linphone_initialized = TRUE;
		linphone_core_init(&lc, &vtable, NULL);
		return TCL_OK;
	}

/*	g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, dummy_log_handler, NULL);
	g_log_set_handler ("Linphone", G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION, dummy_log_handler, NULL);
	g_log_set_handler ("MediaStreamer", G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING, dummy_log_handler, NULL);
	g_log_set_handler ("oRTP", G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING, dummy_log_handler, NULL);
	g_log_set_handler ("oRTP-stats", G_LOG_LEVEL_MESSAGE, dummy_log_handler, NULL);*/
}

int linphone_wrap_uninit(clientData, interp, argc, argv)
	ClientData clientData;	/* Not used. */
	Tcl_Interp *interp;		/* Current interpreter */
	int argc;			/* Number of arguments */
	char *argv[];		/* Argument strings */
{
	if (linphone_initialized)
	{
		linphone_initialized = FALSE;
		linphone_core_uninit(&lc);
		return TCL_OK;
	}
	
	return -1;
}

int linphone_wrap_invite(clientData, interp, argc, argv)
	ClientData clientData;	/* Not used. */
	Tcl_Interp *interp;		/* Current interpreter */
	int argc;			/* Number of arguments */
	char *argv[];		/* Argument strings */
{
	char * url = argv[1];
	
	printf("Video is : %d\n", linphone_core_video_enabled(&lc));
	
	if (linphone_core_invite(&lc, url) == 0)
		return TCL_OK;
	else
		return -1;
}

int linphone_wrap_terminate_dialog(clientData, interp, argc, argv)
	ClientData clientData;	/* Not used. */
	Tcl_Interp *interp;		/* Current interpreter */
	int argc;			/* Number of arguments */
	char *argv[];		/* Argument strings */
{
	linphone_core_terminate_dialog(&lc, NULL);
	return TCL_OK;
}

int linphone_wrap_set_primary_contact(clientData, interp, argc, argv)
	ClientData clientData;	/* Not used. */
	Tcl_Interp *interp;		/* Current interpreter */
	int argc;			/* Number of arguments */
	char *argv[];		/* Argument strings */
{
	char * sipurl = argv[1];

	linphone_core_set_primary_contact(&lc, sipurl);
	return TCL_OK;
}


int linphone_wrap_set_sip_port(clientData, interp, argc, argv)
	ClientData clientData;	/* Not used. */
	Tcl_Interp *interp;		/* Current interpreter */
	int argc;			/* Number of arguments */
	char *argv[];		/* Argument strings */
{
	int port = (int)strtol (argv[1], NULL , 10);

	printf("sip port is %d\n", port);

	linphone_core_set_sip_port(&lc, port);

	printf("sip port is %d\n", linphone_core_get_sip_port(&lc));
	return TCL_OK;
}


int linphone_wrap_set_audio_port(clientData, interp, argc, argv)
	ClientData clientData;	/* Not used. */
	Tcl_Interp *interp;		/* Current interpreter */
	int argc;			/* Number of arguments */
	char *argv[];		/* Argument strings */
{
	int port = (int)strtol (argv[1], NULL , 10);

	printf("a port is %d\n", port);
	linphone_core_set_audio_port(&lc, port);
	printf("a port is %d\n", linphone_core_get_audio_port(&lc));
	return TCL_OK;
}


int linphone_wrap_set_video_port(clientData, interp, argc, argv)
	ClientData clientData;	/* Not used. */
	Tcl_Interp *interp;		/* Current interpreter */
	int argc;			/* Number of arguments */
	char *argv[];		/* Argument strings */
{
	int port = (int)strtol (argv[1], NULL , 10);

	printf("v port is %d\n", port);
	
	linphone_core_set_video_port(&lc, port);
	printf("v port is %d\n", linphone_core_get_video_port(&lc));
	return TCL_OK;
}


int linphone_wrap_set_nat_address(clientData, interp, argc, argv)
	ClientData clientData;	/* Not used. */
	Tcl_Interp *interp;		/* Current interpreter */
	int argc;			/* Number of arguments */
	char *argv[];		/* Argument strings */
{
	gchar *addr = argv[1];
	
	linphone_core_set_nat_address(&lc, addr, 1);
	return TCL_OK;

}


// int linphone_wrap_set_play_level(clientData, interp, argc, argv)
// 	ClientData clientData;	/* Not used. */
// 	Tcl_Interp *interp;		/* Current interpreter */
// 	int argc;			/* Number of arguments */
// 	char *argv[];		/* Argument strings */
// {
// 	int level = (int)argv[1];
// 	
// 	linphone_core_set_play_level(&lc, level);
// 	return TCL_OK;
// }
// 
// 
// int linphone_wrap_set_rec_level(clientData, interp, argc, argv)
// 	ClientData clientData;	/* Not used. */
// 	Tcl_Interp *interp;		/* Current interpreter */
// 	int argc;			/* Number of arguments */
// 	char *argv[];		/* Argument strings */
// {
// 	int level = (int)argv[1];
// 	
// 	linphone_core_set_rec_level(&lc, level);
// 	return TCL_OK;
// }


int linphone_enable_video(clientData, interp, argc, argv)
	ClientData clientData;	/* Not used. */
	Tcl_Interp *interp;		/* Current interpreter */
	int argc;			/* Number of arguments */
	char *argv[];		/* Argument strings */
{
//	int enable = (int)strtol (argv[1], NULL , 10);
	
//	linphone_core_enable_video(&lc, enable);
	lc.video_conf.enabled = 1;

	return TCL_OK;
}

int linphone_disable_video(clientData, interp, argc, argv)
	ClientData clientData;	/* Not used. */
	Tcl_Interp *interp;		/* Current interpreter */
	int argc;			/* Number of arguments */
	char *argv[];		/* Argument strings */
{
//	int enable = (int)strtol (argv[1], NULL , 10);
	
//	linphone_core_enable_video(&lc, enable);
	lc.video_conf.enabled = 0;

	return TCL_OK;
}


int linphone_show_local_video(clientData, interp, argc, argv)
	ClientData clientData;	/* Not used. */
	Tcl_Interp *interp;		/* Current interpreter */
	int argc;			/* Number of arguments */
	char *argv[];		/* Argument strings */
{
	gboolean enable = (gboolean)strtol (argv[1], NULL , 10);
	
	lc.video_conf.show_local = enable;
	return TCL_OK;
}


int Linphone_Init(Tcl_Interp *interp)
{
	if (Tcl_InitStubs(interp, "8.0", 0) == NULL) {
		return TCL_ERROR;
	}
	
	if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 0) == NULL) {
		if (TCL_VERSION[0] == '7') {
			if (Tcl_PkgRequire(interp, "Tcl", "8.0", 0) == NULL) {
				return TCL_ERROR;
			}
		}
	}
	
//	if (Tcl_PkgProvide(interp, "Linphone", VERSION) != TCL_OK) {
//		return TCL_ERROR;
//	}

	Tcl_CreateCommand(interp, "lp_init", linphone_wrap_init, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
	Tcl_CreateCommand(interp, "lp_uninit", linphone_wrap_uninit, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
	Tcl_CreateCommand(interp, "lp_invite", linphone_wrap_invite, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
	Tcl_CreateCommand(interp, "lp_terminate_dialog", linphone_wrap_terminate_dialog, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
	Tcl_CreateCommand(interp, "lp_set_primary_contact", linphone_wrap_set_primary_contact, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
	Tcl_CreateCommand(interp, "lp_set_sip_port", linphone_wrap_set_sip_port, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
	Tcl_CreateCommand(interp, "lp_set_audio_port", linphone_wrap_set_audio_port, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
	Tcl_CreateCommand(interp, "lp_set_video_port", linphone_wrap_set_video_port, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
	Tcl_CreateCommand(interp, "lp_set_nat_address", linphone_wrap_set_nat_address, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
//	Tcl_CreateCommand(interp, "lp_set_play_level", linphone_wrap_set_play_level, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
//	Tcl_CreateCommand(interp, "lp_set_rec_level", linphone_wrap_set_rec_level, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
	Tcl_CreateCommand(interp, "lp_enable_video", linphone_enable_video, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
	Tcl_CreateCommand(interp, "lp_disable_video", linphone_disable_video, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
	Tcl_CreateCommand(interp, "lp_show_local_video", linphone_show_local_video, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
	
	return TCL_OK;
}
