/*  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.
*/

#ifndef __EXECUTE_H__
#define __EXECUTE_H__

#include "options.h"
#include "program-rc.h"

#ifndef CMD_LINE

#define MEMORY_CHANGE_OWNER_INDEX(i, p) \
  { \
    if (memory[(i)].owner) \
      memory[(i)].owner->cell_count--; \
    memory[(i)].owner = (p); \
    (p)->cell_count++; \
  }

#define MEMORY_CHANGE_OWNER_POINTER(m, p) \
  { \
    if ((m)->owner) \
      (m)->owner->cell_count--; \
    (m)->owner = (p); \
    (p)->cell_count++; \
  }

#else

#define MEMORY_CHANGE_OWNER_INDEX(i, p) \
  { \
    memory[(i)].owner = (p); \
  }

#define MEMORY_CHANGE_OWNER_POINTER(m, p) \
  { \
    (m)->owner = (p); \
  }

#endif

struct cell {
  struct process *owner;
  int contains_code;
  union {
    struct cw_line *code;
    int data;
    struct rc_command command;
  } content;   
} ;

struct thread {
  struct thread *next, *prev;
  int pc;
} ;

struct process {
  struct program *program;
  struct thread *thread;
  int thread_count;
  int cell_count;
  int kill_count;
  int death_time;
  int killing;
#ifndef CMD_LINE
  GdkColor color;
  GdkPixmap *bullet;
#endif
} ;

#ifndef CMD_LINE
extern GdkGC* execute_gc;
extern GdkColor black;
extern gint execute_timeout, statistic_timeout;
extern GdkColormap *execute_colormap;
#endif

extern struct process *process_array;
extern int process_count;
extern int process_alive;
extern int running;
extern struct process *marked_process;
extern int elapsed_time;
extern int thread_count;
extern struct cell memory[SIZE_MAX];

extern int cleanup_needed;
extern int paused;

#ifndef CMD_LINE
void execute_init ();
void mark (int i, int force);
void mark_active (int i, struct process* active);
void mark_inactive (int i);
void execute_mark (struct process *p);
int execute_start ();
void execute_stop ();
void execute_pause ();
void execute_continue ();
gint execute_step_handler (gpointer data);
gint statistic_handler (gpointer data);
#else

#define mark(x,y) 
#define mark_active(x,y)
#define mark_inactive(x)

#endif

int execute_start_cmd ();
void execute_stop_cmd ();
void execute_cleanup ();

#endif
