/*  Core Wars.
 *  Copyright (C) 1999  Walter Hofmann
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as 
 *  published by the Free Software Foundation.
 *
 *  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.
 */

#include <gtk/gtk.h>
#include <glib.h>
#include <stdlib.h>

#include "main.h"
#include "main-gui.h"
#include "program.h"
#include "execute-cw.h"
#include "tournament.h"
#include "pstatistic.h"

GtkWidget *tournament_window = NULL;
GtkWidget *tournament_all_button;
GtkWidget *tournament_group_button;
GtkWidget *tournament_times_entry;
GtkWidget *tournament_group_entry;
GtkWidget *tournament_clear_button;
GtkWidget *tournament_start_button;

int tournament_running = FALSE;
int tournament_all_mode = TRUE;
int tournament_count;
int tournament_number = 10;
int tournament_group = 5;

void tournament_window_ok (GtkWidget *w, gpointer data)
{
  struct program *p;
  int i;

  tournament_all_mode = GTK_TOGGLE_BUTTON (tournament_all_button)->active;
  tournament_number = MAX (1, atoi (gtk_entry_get_text (GTK_ENTRY (tournament_times_entry))));
  tournament_group = MAX (1, atoi (gtk_entry_get_text (GTK_ENTRY (tournament_group_entry))));
  if (tournament_all_mode)
    {
      tournament_count = 1;
      p = program_list_root;
      while (p)
	{
	  p->tournament_count = p->load_count;
	  p = p->next;
	}
    }
  else
    {
      p = program_list_root;
      i = tournament_group;
      while (p)
	{
	  p->tournament_count = p->load_count;
	  if (p->tournament_count)
	    if (i && p->language==LANGUAGE)
	      i--;
	    else
	      p->load_count = 0;
	  p = p->next;
	}
      tournament_group -= i;
    }
  tournament_running = TRUE;
  if (GTK_TOGGLE_BUTTON (tournament_clear_button)->active)
    pstatistic_clear ();
  gtk_widget_set (GTK_WIDGET (menu_tournament_start), "sensitive", FALSE, NULL);
  gtk_widget_set (GTK_WIDGET (menu_tournament_stop), "sensitive", TRUE, NULL);
  gtk_widget_destroy (tournament_window);
  if (execute_start ()==FAIL)
    tournament_stop (NULL, NULL);
}

void tournament_toggled (GtkToggleButton *togglebutton, gpointer user_data)
{
  if (togglebutton==GTK_TOGGLE_BUTTON (tournament_all_button))
    {
      gtk_widget_set (tournament_group_button, "can_focus", TRUE, NULL);
      gtk_widget_set (tournament_times_entry, "sensitive", TRUE, NULL);
      gtk_widget_grab_focus (tournament_times_entry);
      gtk_widget_set (tournament_all_button, "can_focus", FALSE, NULL);
      gtk_widget_set (tournament_group_entry, "sensitive", FALSE, NULL);
    }
  else
    {
      gtk_widget_set (tournament_all_button, "can_focus", TRUE, NULL);
      gtk_widget_set (tournament_group_entry, "sensitive", TRUE, NULL);
      gtk_widget_grab_focus (tournament_group_entry);
      gtk_widget_set (tournament_group_button, "can_focus", FALSE, NULL);
      gtk_widget_set (tournament_times_entry, "sensitive", FALSE, NULL);
    }
}

void tournament_start (GtkWidget *w, gpointer data)
{
  GtkWidget *cancelbutton; 
  GtkWidget *label;
  GtkWidget *vbox;
  GtkWidget *hbox;

  if (!tournament_window)
    {
      tournament_window = gtk_dialog_new ();
      gtk_signal_connect (GTK_OBJECT (tournament_window), "destroy", 
			  GTK_SIGNAL_FUNC (gtk_widget_destroyed), &tournament_window);
      gtk_window_set_title (GTK_WINDOW (tournament_window), "Tournament");

      vbox = GTK_DIALOG (tournament_window)->vbox;
      tournament_all_button = gtk_radio_button_new (NULL);
      hbox = gtk_hbox_new (FALSE, 0);
      label = gtk_label_new ("all against all ");
      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
      gtk_widget_show (label);
      tournament_times_entry = gtk_entry_new_with_max_length (3);
      gtk_entry_set_text (GTK_ENTRY (tournament_times_entry), itos (tournament_number));
      gtk_widget_set (tournament_times_entry, "width", TOURNAMENT_ENTRY_WIDTH, NULL);
      gtk_box_pack_start (GTK_BOX (hbox), tournament_times_entry, FALSE, FALSE, 0);
      gtk_widget_show (tournament_times_entry);
      label = gtk_label_new (" times");
      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
      gtk_widget_show (label);
      gtk_container_add (GTK_CONTAINER (tournament_all_button), hbox);
      gtk_widget_show (hbox);
      gtk_box_pack_start (GTK_BOX (vbox), tournament_all_button, TRUE, TRUE, 0);
      gtk_widget_show (tournament_all_button);
      gtk_signal_connect (GTK_OBJECT (tournament_all_button), "toggled", 
			  GTK_SIGNAL_FUNC (tournament_toggled), NULL);
      tournament_group_button = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (tournament_all_button));
      hbox = gtk_hbox_new (FALSE, 0);
      label = gtk_label_new ("in groups of ");
      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
      gtk_widget_show (label);
      tournament_group_entry = gtk_entry_new_with_max_length (3);
      gtk_entry_set_text (GTK_ENTRY (tournament_group_entry), itos (tournament_group));
      gtk_widget_set (tournament_group_entry, "width", TOURNAMENT_ENTRY_WIDTH, NULL);
      gtk_box_pack_start (GTK_BOX (hbox), tournament_group_entry, FALSE, FALSE, 0);
      gtk_widget_show (tournament_group_entry);
      gtk_container_add (GTK_CONTAINER (tournament_group_button), hbox);
      gtk_widget_show (hbox);
      gtk_box_pack_start (GTK_BOX (vbox), tournament_group_button, TRUE, TRUE, 0);
      gtk_widget_show (tournament_group_button);
      gtk_signal_connect (GTK_OBJECT (tournament_group_button), "toggled", 
			  GTK_SIGNAL_FUNC (tournament_toggled), NULL);
      if (tournament_all_mode)
	{
	  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tournament_all_button), TRUE);
	  tournament_toggled (GTK_TOGGLE_BUTTON (tournament_all_button), NULL);
	}
      else
	{
	  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (tournament_group_button), TRUE);
	  tournament_toggled (GTK_TOGGLE_BUTTON (tournament_group_button), NULL);
	}

      tournament_clear_button = gtk_check_button_new_with_label ("Clear program statistic");
      gtk_box_pack_start (GTK_BOX (vbox), tournament_clear_button, TRUE, TRUE, 0);
      gtk_widget_show (tournament_clear_button);

      tournament_start_button = gtk_button_new_with_label( "Start" );
      gtk_signal_connect (GTK_OBJECT (tournament_start_button), "clicked", 
			  GTK_SIGNAL_FUNC (tournament_window_ok), NULL);
      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (tournament_window)->action_area),
			  tournament_start_button, TRUE, TRUE, 0);
      gtk_widget_show (tournament_start_button);
      cancelbutton = gtk_button_new_with_label( "Cancel" );
      gtk_signal_connect_object (GTK_OBJECT (cancelbutton), "clicked", 
				 GTK_SIGNAL_FUNC (gtk_widget_destroy),
				 GTK_OBJECT (tournament_window)); 
      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (tournament_window)->action_area),
			  cancelbutton, TRUE, TRUE, 0);
      gtk_widget_show (cancelbutton);
      gtk_widget_show (tournament_window);
      tournament_update ();
    }
  else
    gdk_window_raise (tournament_window->window);
}

void tournament_cleanup ()
{
  struct program *p;

  if (tournament_all_mode)
    {
    }
  else
    {
      p = program_list_root;
      while (p)
	{
	  p->load_count = p->tournament_count;
	  p = p->next;
	}
    }
  tournament_running = FALSE;
  gtk_widget_set (GTK_WIDGET (menu_tournament_start), "sensitive", TRUE, NULL);
  gtk_widget_set (GTK_WIDGET (menu_tournament_stop), "sensitive", FALSE, NULL);
}

void tournament_stop (GtkWidget *w, gpointer data)
{
  execute_stop ();
  tournament_cleanup ();
}

int tournament_next_group ()
{
  struct program *p, *q, *r;
  int i, j;

  p = program_list_root;
  while (p && (!p->tournament_count || p->language!=LANGUAGE))
    p = p->next;
  if (!p)
    return FALSE;
  i = 0;
  r = NULL;
  while (p)
    {
      q = p->next;
      while (q && (!q->tournament_count || q->language!=LANGUAGE))
	q = q->next;
      if (q && p->load_count && !q->load_count)
	{
	  r = p;
	  j = i;
	}
      if (p->load_count)
	i++;
      p = q;
    }
  if (r)
    {
      r->load_count = 0;
      r = r->next;
      while (!r->tournament_count || r->language!=LANGUAGE)
	r = r->next;
      j = tournament_group-j;
      while (r)
	{
	  if (j)
	    {
	      r->load_count = r->tournament_count;
	      j--;
	    }
	  else
	    r->load_count = 0;
	  r = r->next;
	  while (r && (!r->tournament_count || r->language!=LANGUAGE))
	    r = r->next;
	}
      return TRUE;
    }
  else
    return FALSE;
}

void tournament_finished_game ()
{
  int finished;

  execute_stop ();

  if (tournament_all_mode)
    {
      tournament_count++;
      finished = (tournament_count>tournament_number);
    }
  else
    {
      finished = !tournament_next_group ();
    }

  if (finished)
    tournament_cleanup ();
  else
    if (execute_start ()==FAIL)
      tournament_stop (NULL, NULL);
}

void tournament_update ()
{
  if (tournament_window)
    if (running)
      gtk_widget_set (tournament_start_button, "sensitive", FALSE, NULL);
    else
      gtk_widget_set (tournament_start_button, "sensitive", TRUE, NULL);
}
