/*  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 <stdlib.h>
#include <string.h>

#ifndef CMD_LINE
#include <gtk/gtk.h>
#endif

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

#ifndef CMD_LINE
GtkWidget *pstatistic_window = NULL;
GtkWidget *pstatistic_clist;

void pstatistic_clear_handler (GtkCList *clist, gint row, gint column,
			       GdkEventButton *event, gpointer user_data)
{
  pstatistic_clear ();
}

void pstatistic_view ()
{
  gchar *clist_titles[] = { " Rank ", "  Score  ", " Games ", " Title", "Author" };
  GtkWidget *scrolled_window;
  GtkWidget *clearbutton;
  GtkWidget *okbutton;
  
  if (!pstatistic_window)
    {
      pstatistic_window = gtk_dialog_new ();
      gtk_signal_connect (GTK_OBJECT (pstatistic_window), "destroy", 
			  GTK_SIGNAL_FUNC (gtk_widget_destroyed), &pstatistic_window);
      gtk_window_set_title (GTK_WINDOW (pstatistic_window), "Program Statistic");
      scrolled_window = gtk_scrolled_window_new (NULL, NULL);
      gtk_widget_set (GTK_WIDGET (scrolled_window), "height", PSTATISTIC_WINDOW_HEIGHT, NULL);
      gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), 
				      GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC ); 
      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pstatistic_window)->vbox),
			  scrolled_window, TRUE, TRUE, 0);
      pstatistic_clist = gtk_clist_new_with_titles (5, clist_titles);
      gtk_clist_set_selection_mode (GTK_CLIST (pstatistic_clist), GTK_SELECTION_BROWSE);
      gtk_clist_set_shadow_type (GTK_CLIST (pstatistic_clist), GTK_SHADOW_OUT);
      gtk_clist_set_column_justification (GTK_CLIST (pstatistic_clist), 0, GTK_JUSTIFY_CENTER);
      gtk_clist_set_column_justification (GTK_CLIST (pstatistic_clist), 1, GTK_JUSTIFY_CENTER);
      gtk_clist_set_column_justification (GTK_CLIST (pstatistic_clist), 2, GTK_JUSTIFY_CENTER);
      gtk_clist_set_column_width (GTK_CLIST (pstatistic_clist), 3, PSTATISTIC_TITLE_WIDTH);
      gtk_clist_set_column_width (GTK_CLIST (pstatistic_clist), 4, PSTATISTIC_AUTHOR_WIDTH);
      gtk_container_add (GTK_CONTAINER (scrolled_window), 
			 pstatistic_clist);
      gtk_widget_show (pstatistic_clist);
      gtk_widget_show (scrolled_window);
      clearbutton = gtk_button_new_with_label( "Clear" );
      gtk_signal_connect (GTK_OBJECT (clearbutton), "clicked", 
			  GTK_SIGNAL_FUNC (pstatistic_clear_handler), NULL); 
      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pstatistic_window)->action_area),
			  clearbutton, TRUE, TRUE, 0);
      gtk_widget_show (clearbutton);
      okbutton = gtk_button_new_with_label( "Close" );
      gtk_signal_connect_object (GTK_OBJECT (okbutton), "clicked", 
				 GTK_SIGNAL_FUNC (gtk_widget_destroy),
				 GTK_OBJECT (pstatistic_window)); 
      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (pstatistic_window)->action_area),
			  okbutton, TRUE, TRUE, 0);
      gtk_widget_show (okbutton);
      gtk_widget_show (pstatistic_window);
      pstatistic_update ();
    }
  else
    gdk_window_raise (pstatistic_window->window);
}

void pstatistic_clear ()
{
  struct program *p;

  if (pstatistic_window)
    {
      p = program_list_root;
      while (p)
	{
	  p->tournament_score = 0;
	  p->tournament_games = 0;
	  p = p->next;
	}
      pstatistic_update ();
    }
}

void pstatistic_update ()
{
  int n, i, r;
  struct program *p;
  gchar *row[] = {"", "", "", ""};
  struct program **table;
  
  if (pstatistic_window)
    {
      gtk_clist_freeze (GTK_CLIST (pstatistic_clist));
      gtk_clist_clear (GTK_CLIST (pstatistic_clist));
      p = program_list_root;
      n = 0;
      while (p)
	{
	  if (p->language==LANGUAGE && (p->load_count || 
					tournament_running && p->tournament_count || 
					p->tournament_score))
	    n++;
	  p = p->next;
	}
      if (!n)
	{
	  gtk_clist_thaw (GTK_CLIST (pstatistic_clist));
	  return;
	}
      table = malloc (sizeof (struct program *)*n);
      p = program_list_root;
      i = 0;
      while (p)
	{
	  if (p->language==LANGUAGE && (p->load_count || 
					tournament_running && p->tournament_count || 
					p->tournament_score))
	    *(table+i++) = p;
	  p = p->next;
	}
      qsort (table, n, sizeof (struct program *), &program_compare);
      r = TRUE;
      for (i=0; i<n; i++)
	{
	  p = *(table+i);
	  gtk_clist_append (GTK_CLIST (pstatistic_clist), row);
	  if (r)
	    gtk_clist_set_text (GTK_CLIST (pstatistic_clist), i, 0, itos (i+1));
	  gtk_clist_set_text (GTK_CLIST (pstatistic_clist), i, 1, itos (p->tournament_score));
	  gtk_clist_set_text (GTK_CLIST (pstatistic_clist), i, 2, itos (p->tournament_games));
	  gtk_clist_set_text (GTK_CLIST (pstatistic_clist), i, 3, p->title);
	  gtk_clist_set_text (GTK_CLIST (pstatistic_clist), i, 4, p->author);
	  if (i<n-1)
	    r = (*(table+i+1))->tournament_score!=p->tournament_score;
	}
      gtk_clist_thaw (GTK_CLIST (pstatistic_clist));
      free (table);
    }
}
#endif

int struct_process_compare (const void *a, const void *b)
{
  return process_score ((struct process *)b) - process_score ((struct process *)a);
}

int program_compare (const void *a, const void *b)
{
  return (*(struct program **)b)->tournament_score-(*(struct program **)a)->tournament_score;
}

void pstatistic_add ()
{
  struct program *p;
  int i, j;
  struct process *pa;

  pa = malloc (sizeof (struct process)*process_count);
  memcpy (pa, process_array, sizeof (struct process)*process_count);
  qsort (pa, process_count, sizeof (struct process), &struct_process_compare);
  
  if (SCORE_BEST)
    {
      p = program_list_root;
      while (p)
	{
	  for (i=0; i<process_count && (pa+i)->program!=p; i++) ;
	  if (i!=process_count)
	    {
	      if (SCORE_RANK)
		{
		  j = i;
		  while (j && process_score (pa+j)==process_score (pa+j-1))
		    j--;
		  p->tournament_score += process_count-j-1;
		}
	      else
		p->tournament_score += process_score (pa+i);
	      p->tournament_games++;
	    }
	  p = p->next;
	}
    }
  else
    {
      for (i=0; i<process_count; i++)
	if (SCORE_RANK)
	  {
	    j = i;
	    while (j && process_score (pa+j)==process_score (pa+j-1))
	      j--;
	    (pa+i)->program->tournament_score += process_count-j-1;
	  }
	else
	  (pa+i)->program->tournament_score += process_score (pa+i);
      p = program_list_root;
      while (p)
	{
	  for (i=0; i<process_count && (pa+i)->program!=p; i++) ;
	  if (i!=process_count)
	    p->tournament_games++;
	  p = p->next;
	}
    }
  free (pa);
#ifndef CMD_LINE
  pstatistic_update ();
#endif
}

