/*	$Id: g_connect.c,v 1.3 2002/04/19 02:28:52 riq Exp $	*/
/* Tenes Empanadas Graciela
 *
 * Copyright (C) 2000 Ricardo Quesada
 *
 * Author: Ricardo Calixto Quesada <rquesada@core-sdi.com>
 *
 * 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.
 */
/**
 * @file conectar.c
 * Tiene los dialogos de coneccion y de seleccion de color y game type
 */
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <assert.h>
#include <gnome.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>

#include "common.h"
#include "support.h"
#include "protocol.h"
#include "cliente.h"
#include "proceso.h"
#include "g_interface.h"
#include "pantalla.h"
#include "gbnclient.h"
#include "sendmsg.h"
#include "configure.h"
#include "bnwrite.h"
#include "version.h"
#include "g_connect.h"

static GtkWidget *conectar_window = NULL;
static GtkWidget *con_entry_name=NULL;
static GtkWidget *con_spinner_port=NULL;
static GtkWidget *con_entry_server=NULL;

static GtkWidget *gametype_dialog=NULL;
static GtkWidget *gametype_button_secret=NULL;
static GtkWidget *gametype_button_conqworld=NULL;

static GtkWidget *button_launch=NULL;


static void close_descriptors( void )
{
	int i, open_max;

	/* force manually the close of the socket */
	if( usuario.sock >0 )
		close( usuario.sock );

	open_max = sysconf (_SC_OPEN_MAX);
	for( i = 3; i < open_max; i++ )
		fcntl (i, F_SETFD, FD_CLOEXEC);
}

static BATNAV_STATUS launch_server( int port )
{
	pid_t pid;
	char *args[4];

	if ( (pid = fork()) < 0) {
		perror("gbnclient:");
		return BATNAV_STATUS_ERROR;
	} else if (pid == 0) {

		char buffer[100];
		close_descriptors();
		args[0] = BINDIR"/gbnserver";
		args[1] = "--port";
		snprintf(buffer, sizeof(buffer)-1, "%d", port); 
		buffer[ sizeof(buffer)-1 ] = 0;
		args[2] = buffer;
		args[3] = NULL;

		if( execvp(args[0], args) < 0) {
			fprintf(stderr,"Launching server failed. Does the file '%s' exists ?\n",args[0]);
			perror("exe:");

			/* This saves a crash */
			args[0] = "/bin/true";
			args[1] = NULL;
			execv(args[0],args);
			exit(1);
		}

		return BATNAV_STATUS_ERROR;
	} else {
		/* wait util server is launched */
		sleep(2);
	}
	return BATNAV_STATUS_SUCCESS;
}

static BATNAV_STATUS conectar_real()
{
	if( send_connect() == 0 ) {
		if( conectar_window )
			destroy_window( conectar_window, &conectar_window );
		return BATNAV_STATUS_SUCCESS;
	}
	return BATNAV_STATUS_ERROR;
}

static gint conectar_button_con_cb(GtkWidget *area, GdkEventExpose *event, gpointer user_data)
{
	strncpy(usuario.nombre,gtk_entry_get_text(GTK_ENTRY(con_entry_name)),sizeof(usuario.nombre)-1);
	usuario.nombre[sizeof(usuario.nombre)-1]=0;
	strncpy(usuario.server,gtk_entry_get_text(GTK_ENTRY(con_entry_server)),sizeof(usuario.server)-1);
	usuario.server[sizeof(usuario.server)-1]=0;
	usuario.port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(con_spinner_port));


	/* if you checked "start local server" we'll copy "localhost" to g_juego.sername */
	if( GTK_TOGGLE_BUTTON(button_launch)->active ) {
		launch_server( usuario.port );
	}

	gnome_config_set_int   ("/gbnclient/data/port",  usuario.port);
	gnome_config_set_string("/gbnclient/data/servername",usuario.server);
	gnome_config_set_string("/gbnclient/data/playername",usuario.nombre);
	gnome_config_sync();

	conectar_real();

	return FALSE;
}

/*
 * Called when something has changed on the properybox
 */
static void
prop_changed (GtkWidget *w, void *n)
{
	if( GTK_TOGGLE_BUTTON(button_launch)->active )
		gtk_entry_set_text( GTK_ENTRY( con_entry_server ), "localhost");
}

/**
 * @fn void conectar_view()
 * Muestra la ventana de coneccion
 */
void conectar_view()
{
	GtkWidget *label;
	GtkWidget *table;
	GtkWidget *frame;
        GtkAdjustment *adj;

	if( usuario.with_ggz ) {
		conectar_real();
		return;
	}

	if( conectar_window != NULL ) {
		gtk_widget_show_all(conectar_window);
		raise_and_focus(conectar_window);
		return ;
	}

	conectar_window = teg_dialog_new(_("Connect to server"),_("Connect to server")); 
	gnome_dialog_append_buttons(GNOME_DIALOG(conectar_window),
		GNOME_STOCK_BUTTON_OK,
		GNOME_STOCK_BUTTON_CANCEL,
		NULL );
	gnome_dialog_set_default(GNOME_DIALOG(conectar_window),0);

	gnome_dialog_button_connect (GNOME_DIALOG(conectar_window),
		1, GTK_SIGNAL_FUNC(destroy_window),&conectar_window);

	gnome_dialog_button_connect (GNOME_DIALOG(conectar_window),
		0, GTK_SIGNAL_FUNC(conectar_button_con_cb),conectar_window);

	gtk_signal_connect( GTK_OBJECT(conectar_window),
			"delete_event", GTK_SIGNAL_FUNC(destroy_window),
			&conectar_window);

	gtk_signal_connect( GTK_OBJECT(conectar_window),
			"destroy", GTK_SIGNAL_FUNC(destroy_window),
			&conectar_window);

	/* server options */
	table = gtk_table_new (3, 2, TRUE);
	gtk_container_border_width (GTK_CONTAINER (table), GNOME_PAD_SMALL);
	gtk_table_set_row_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
	gtk_table_set_col_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);

	frame = gtk_frame_new (_("Server Options"));
	gtk_container_border_width (GTK_CONTAINER (frame), 1);
	gtk_container_add(GTK_CONTAINER(GNOME_DIALOG(conectar_window)->vbox), frame);

	/* server port */
	label = gtk_label_new(_("Server port:"));
	gtk_table_attach_defaults( GTK_TABLE(table), label, 0, 1, 0, 1 );
	adj = (GtkAdjustment *) gtk_adjustment_new( usuario.port, 1.0, 65536.0, 1.0, 5.0, 1.0 );
	con_spinner_port = gtk_spin_button_new( adj, 0.0, 0);
	gtk_table_attach_defaults( GTK_TABLE(table), con_spinner_port, 1, 2, 0, 1 );

	/* server name */
	label = gtk_label_new(_("Server name:"));
	gtk_table_attach_defaults( GTK_TABLE(table), label, 0, 1, 1, 2 );
	con_entry_server = gtk_entry_new( );
	gtk_entry_set_text( GTK_ENTRY( con_entry_server ), usuario.server);
	gtk_table_attach_defaults( GTK_TABLE(table), con_entry_server, 1, 2, 1, 2 );
	

	/* player name */
	label = gtk_label_new(_("Name:"));
	gtk_table_attach_defaults( GTK_TABLE(table), label, 0, 1, 2, 3 );
	con_entry_name = gtk_entry_new( );
	gtk_entry_set_text( GTK_ENTRY( con_entry_name ), usuario.nombre);
	gtk_table_attach_defaults( GTK_TABLE(table), con_entry_name, 1, 2, 2, 3 );


	gtk_container_add(GTK_CONTAINER(frame), table);

	/* launch localhost server */
	button_launch = gtk_check_button_new_with_label(_("Start server locally"));
	gtk_container_add(GTK_CONTAINER(GNOME_DIALOG(conectar_window)->vbox), button_launch);
	gtk_signal_connect (GTK_OBJECT (button_launch), "toggled",
	    	GTK_SIGNAL_FUNC (prop_changed), NULL);


	/* fin */

	gtk_widget_show (GTK_WIDGET(table));
	gtk_widget_show_all(conectar_window);
	raise_and_focus(conectar_window);
}
