[Avida-SVN] r1964 - in development/source: classification targets/viewer-fltk targets/viewer-text tools viewer-core viewer-coreGUI

ofria at myxo.css.msu.edu ofria at myxo.css.msu.edu
Mon Aug 20 10:27:17 PDT 2007


Author: ofria
Date: 2007-08-20 13:27:17 -0400 (Mon, 20 Aug 2007)
New Revision: 1964

Added:
   development/source/targets/viewer-fltk/cFLTKBaseDraw.h
   development/source/targets/viewer-fltk/cFLTKGridView.cc
   development/source/targets/viewer-fltk/cFLTKGridView.h
   development/source/targets/viewer-fltk/cFLTKWidget.h
   development/source/targets/viewer-fltk/tFLTKMenu.h
   development/source/targets/viewer-text/cScreen_Map.cc
   development/source/targets/viewer-text/cScreen_Map.h
   development/source/targets/viewer-text/cTextScreen.h
   development/source/tools/cBitArray.cc
   development/source/tools/cBitArray.h
   development/source/viewer-core/cCoreView_Map.cc
   development/source/viewer-core/cCoreView_Map.h
   development/source/viewer-coreGUI/cColor.cc
   development/source/viewer-coreGUI/cColor.h
   development/source/viewer-coreGUI/cGUIBaseDraw.h
   development/source/viewer-coreGUI/cGUIMenu.h
   development/source/viewer-coreGUI/cGUIMenuItem.h
   development/source/viewer-coreGUI/tGUIMenu.h
   development/source/viewer-coreGUI/tGUIMenuItem.h
Removed:
   development/source/targets/viewer-text/cTextViewerManager.cc
   development/source/targets/viewer-text/cTextViewerManager.h
Modified:
   development/source/classification/cGenotype.cc
   development/source/classification/cGenotype.h
   development/source/targets/viewer-fltk/cDriver_FLTKViewer.cc
   development/source/targets/viewer-fltk/cDriver_FLTKViewer.h
   development/source/targets/viewer-fltk/cFLTKBox.h
   development/source/targets/viewer-fltk/cFLTKWindow.h
   development/source/targets/viewer-fltk/fltk-defs.cc
   development/source/targets/viewer-fltk/fltk-defs.h
   development/source/targets/viewer-fltk/tFLTKButton.h
   development/source/targets/viewer-fltk/viewer-fltk.cc
   development/source/targets/viewer-text/cDriver_TextViewer.cc
   development/source/targets/viewer-text/cDriver_TextViewer.h
   development/source/viewer-core/cCoreView_Info.cc
   development/source/viewer-core/cCoreView_Info.h
   development/source/viewer-coreGUI/cGUIWidget.h
   development/source/viewer-coreGUI/tGUIButton.h
Log:
Next update of the new GUI interface.  Map modes are starting to work...


Modified: development/source/classification/cGenotype.cc
===================================================================
--- development/source/classification/cGenotype.cc	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/classification/cGenotype.cc	2007-08-20 17:27:17 UTC (rev 1964)
@@ -46,7 +46,7 @@
   , defer_adjust(0)
   , id_num(in_id)
   , symbol(0)
-  , map_id(-1)
+  , map_color_id(-2)
   , birth_data(in_update_born)
   , num_organisms(0)
   , last_num_organisms(0)
@@ -63,7 +63,7 @@
   // Reset some of the variables to make sure program will crash if a deleted
   // cell is read!
   symbol = '!';
-  map_id = -1;
+  map_color_id = -5;
 
   num_organisms = -1;
   total_organisms = -1;

Modified: development/source/classification/cGenotype.h
===================================================================
--- development/source/classification/cGenotype.h	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/classification/cGenotype.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -61,7 +61,7 @@
 
   int id_num;
   char symbol;
-  int map_id;
+  int map_color_id;
 
   mutable cGenotype_TestData test_data;
   cGenotype_BirthData birth_data;
@@ -138,7 +138,7 @@
   void SetNext(cGenotype* in_next) { next = in_next; }
   void SetPrev(cGenotype* in_prev) { prev = in_prev; }
   void SetSymbol(char in_symbol) { symbol = in_symbol; }
-  void SetMapID(int in_id) { map_id = in_id; }
+  void SetMapColor(int in_id) { map_color_id = in_id; }
   inline void SetThreshold();
   void IncDeferAdjust() { defer_adjust++; }
   void DecDeferAdjust() { defer_adjust--; assert(defer_adjust >= 0); }
@@ -220,7 +220,7 @@
   bool GetThreshold() const     { return flag_threshold; }
   int GetID() const             { return id_num; }
   char GetSymbol() const        { return symbol; }
-  int GetMapID() const          { return map_id; }
+  int GetMapColor() const          { return map_color_id; }
 
   // Calculate a crude phylogentic distance based off of tracking parents
   // and grand-parents, including sexual tracking.
@@ -264,7 +264,7 @@
 {
   flag_threshold = true;
   if (symbol == '.') symbol = '+';
-  if (map_id == 0) map_id = 1;
+  if (map_color_id == -2) map_color_id = -1;
 }
 
 inline void cGenotype::SetBreedStats(cGenotype & daughter)

Modified: development/source/targets/viewer-fltk/cDriver_FLTKViewer.cc
===================================================================
--- development/source/targets/viewer-fltk/cDriver_FLTKViewer.cc	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/targets/viewer-fltk/cDriver_FLTKViewer.cc	2007-08-20 17:27:17 UTC (rev 1964)
@@ -45,10 +45,7 @@
 #include <cstdlib>
 
 #include <FL/Fl.H>
-// #include <FL/Fl_Window.H>
-// #include <FL/Fl_Box.H>
 
-
 using namespace std;
 
 #define FLTK_MAINWIN_WIDTH  800
@@ -60,15 +57,18 @@
 
 cDriver_FLTKViewer::cDriver_FLTKViewer(cWorld* world)
   : m_world(world)
-  , m_info(world->GetPopulation(), 12)
+  , m_info(world, 18)
   , m_done(false)
   , m_main_window(FLTK_MAINWIN_WIDTH, FLTK_MAINWIN_HEIGHT, "Avida")
-  , m_menu_box(m_main_window, 0, 0, FLTK_MAINWIN_WIDTH, FLTK_MENUBAR_HEIGHT)
   , m_body_box(m_main_window, 0, FLTK_MENUBAR_HEIGHT, FLTK_MAINWIN_WIDTH, FLTK_BODY_HEIGHT)
   , m_update_box(m_main_window, 0, 0, 200, FLTK_MENUBAR_HEIGHT, "Update 0")
   , m_title_box(m_main_window, 600, 0, 200, FLTK_MENUBAR_HEIGHT, "Avida")
-  , m_quit_button(m_main_window, 200, 0, 200, FLTK_MENUBAR_HEIGHT, "Quit")
-  , m_pause_button(m_main_window, 400, 0, 200, FLTK_MENUBAR_HEIGHT, "Pause", cGUIButton::BUTTON_LIGHT)
+  , m_grid_view(m_info, m_main_window, 10, FLTK_MENUBAR_HEIGHT+10, FLTK_MAINWIN_WIDTH-20, FLTK_BODY_HEIGHT-60)
+  , m_grid_view_menu(m_main_window,    50, FLTK_MAINWIN_HEIGHT-45, 80, 30, "View:")
+  , m_grid_tags_menu(m_main_window,   180, FLTK_MAINWIN_HEIGHT-45, 80, 30, "Tags:")
+  , m_grid_symbol_menu(m_main_window, 310, FLTK_MAINWIN_HEIGHT-45, 80, 30, "Shape:")
+  , m_pause_button(m_main_window, 600, FLTK_MAINWIN_HEIGHT - 45, 80, 30, "Pause", cGUIButton::BUTTON_LIGHT)
+  , m_quit_button(m_main_window,  700, FLTK_MAINWIN_HEIGHT - 45, 80, 30, "&Quit")
 {
   // Setup the initial view mode (loaded from avida.cfg)
   m_info.SetViewMode(world->GetConfig().VIEW_MODE.Get());
@@ -77,28 +77,37 @@
   world->SetDriver(this);
 
   m_main_window.SetSizeRange(FLTK_MAINWIN_WIDTH, FLTK_MAINWIN_HEIGHT);
+  m_main_window.SetBackgroundColor(cColor(0xDD, 0xDD, 0xFF));
+  m_main_window.Resizable(m_body_box);
 
-  m_menu_box.SetType(cGUIBox::BOX_RAISED_FRAME);
-  m_menu_box.Refresh();
-
-  m_update_box.SetType(cGUIBox::BOX_RAISED);
+  m_update_box.SetType(cGUIBox::BOX_NONE);
   m_update_box.SetFontSize(FLTK_MENU_FONT_SIZE);
   m_update_box.Refresh();
  
-  m_title_box.SetType(cGUIBox::BOX_RAISED);
+  m_title_box.SetType(cGUIBox::BOX_NONE);
   m_title_box.SetFontSize(FLTK_MENU_FONT_SIZE);
   m_title_box.Refresh();
 
-  m_main_window.Resizable(m_body_box);
+  cCoreView_Map & map_info = m_grid_view.GetMapInfo();
+  int num_modes = map_info.GetNumModes();
+  for (int i = 0; i < num_modes; i++) {
+    const cString & cur_name = map_info.GetModeName(i);
+    const int cur_type = map_info.GetModeType(i);
+    if (cur_type == cCoreView_Map::VIEW_COLOR) {
+      m_grid_view_menu.AddOption(cur_name, this, &cDriver_FLTKViewer::MenuCallback_View, i);
+    } else if (cur_type == cCoreView_Map::VIEW_TAGS) {
+      m_grid_tags_menu.AddOption(cur_name, this, &cDriver_FLTKViewer::MenuCallback_View, i);
+    } else if (cur_type == cCoreView_Map::VIEW_SYMBOLS) {
+      m_grid_symbol_menu.AddOption(cur_name, this, &cDriver_FLTKViewer::MenuCallback_View, i);
+    }
+  }
+  m_grid_view_menu.SetActive(0);
+  m_grid_tags_menu.SetActive(0);
+  m_grid_symbol_menu.SetActive(0);
 
+  m_pause_button.SetCallback(this, &cDriver_FLTKViewer::ButtonCallback_Pause);
   m_quit_button.SetCallback(this, &cDriver_FLTKViewer::ButtonCallback_Quit);
-  m_quit_button.SetFontSize(FLTK_MENU_FONT_SIZE);
-  m_quit_button.Refresh();
 
-  m_pause_button.SetCallback(this, &cDriver_FLTKViewer::ButtonCallback_Pause);
-  m_pause_button.SetFontSize(FLTK_MENU_FONT_SIZE);
-  m_pause_button.Refresh();
-
   m_main_window.Finalize();
 }
 
@@ -343,11 +352,14 @@
 {
   bool error = Fl::check();
 
+  m_info.SetupUpdate();
+
   cString update_string;
   update_string.Set("Update: %d", m_world->GetStats().GetUpdate());
   m_update_box.SetName(update_string);
   m_update_box.Refresh();
   
+  m_grid_view.Redraw();
 
   const int pause_level = m_info.GetPauseLevel();
 
@@ -420,8 +432,13 @@
 }
 
 
+void cDriver_FLTKViewer::MenuCallback_View(int new_mode)
+{
+  m_grid_view.GetMapInfo().SetMode(new_mode);
+}
 
 
+
 void ExitFLTKViewer(int exit_code)
 {
   signal(SIGINT, SIG_IGN);           // Ignore all future interupts.

Modified: development/source/targets/viewer-fltk/cDriver_FLTKViewer.h
===================================================================
--- development/source/targets/viewer-fltk/cDriver_FLTKViewer.h	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/targets/viewer-fltk/cDriver_FLTKViewer.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -38,8 +38,10 @@
 #endif
 
 #include "cFLTKBox.h"
+#include "cFLTKGridView.h"
 #include "cFLTKWindow.h"
 #include "tFLTKButton.h"
+#include "tFLTKMenu.h"
 
 #include <sstream>
 #include <iostream>
@@ -60,14 +62,18 @@
   // Graphics components...
   cFLTKWindow m_main_window;
 
-  cFLTKBox m_menu_box;
+  //  cFLTKBox m_menu_box;
   cFLTKBox m_body_box;
+
   cFLTKBox m_update_box;
   cFLTKBox m_title_box;
 
+  cFLTKGridView m_grid_view;
+  tFLTKMenu<cDriver_FLTKViewer> m_grid_view_menu;
+  tFLTKMenu<cDriver_FLTKViewer> m_grid_tags_menu;
+  tFLTKMenu<cDriver_FLTKViewer> m_grid_symbol_menu;
+  tFLTKButton<cDriver_FLTKViewer> m_pause_button;
   tFLTKButton<cDriver_FLTKViewer> m_quit_button;
-  tFLTKButton<cDriver_FLTKViewer> m_pause_button;
-
 public:
   cDriver_FLTKViewer(cWorld* world);
   ~cDriver_FLTKViewer();
@@ -105,6 +111,9 @@
   // Button Callbacks...
   void ButtonCallback_Quit(double ignore);
   void ButtonCallback_Pause(double ignore);
+
+  // Menu Callbacks
+  void MenuCallback_View(int new_mode);
 };
 
 

Added: development/source/targets/viewer-fltk/cFLTKBaseDraw.h
===================================================================
--- development/source/targets/viewer-fltk/cFLTKBaseDraw.h	                        (rev 0)
+++ development/source/targets/viewer-fltk/cFLTKBaseDraw.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,84 @@
+/*
+ *  cFLTKBaseDraw.h
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+// This is a base class for the main GUI canvases...
+
+#ifndef cFLTKBaseDraw_h
+#define cFLTKBaseDraw_h
+
+#include <FL/Fl.H>
+#include <FL/Fl_Widget.H>
+#include <FL/fl_draw.H>
+
+#ifndef cColor_h
+#include "cColor.h"
+#endif
+
+#ifndef cGUIBaseDraw_h
+#include "cGUIBaseDraw.h"
+#endif
+
+class cFLTKBaseDraw : public cGUIBaseDraw {
+protected:
+  class mDerivedWidget : public Fl_Widget {
+  protected:
+    cGUIBaseDraw & m_widget;
+    
+    void draw() { m_widget.Draw(); }
+    int handle(int event) { return m_widget.Handle(event); }
+
+  public:
+    mDerivedWidget(cGUIBaseDraw & widget, int x, int y, int w, int h)
+      : Fl_Widget(x, y, w, h), m_widget(widget) { ; }
+  };
+
+  mDerivedWidget m_widget;
+
+  int x() { return m_widget.x(); }
+  int y() { return m_widget.y(); }
+  int w() { return m_widget.w(); }
+  int h() { return m_widget.h(); }
+
+  void DrawLine(int x1, int y1, int x2, int y2) { fl_line(x1+x(), y1+y(), x2+x(), y2+y()); }
+  void DrawBox(int x1, int y1, int _w, int _h, bool fill=false) {
+    if (fill == false) fl_rect(x1+x(), y1+y(), _w, _h);
+    else fl_rectf(x1+x(), y1+y(), _w, _h);
+  }
+  void DrawCircle(int _x, int _y, int _r, bool fill=false) {
+    if (fill == false) fl_circle(_x+x(), _y+y(), _r);
+    //    else fl_circlef(_x+x(), _y+y(), _r);
+  }
+
+  void SetColor(const cColor & color) { fl_color(color.Red(), color.Green(), color.Blue()); }
+
+public:
+  cFLTKBaseDraw(cGUIContainer & parent, int x, int y, int width, int height, const cString & name="") 
+    : cGUIBaseDraw(parent, x, y, width, height, name), m_widget(*this, x, y, width, height)
+  { ; }
+  ~cFLTKBaseDraw() { ; }
+
+  void Redraw() { m_widget.redraw(); }
+};
+
+#endif

Modified: development/source/targets/viewer-fltk/cFLTKBox.h
===================================================================
--- development/source/targets/viewer-fltk/cFLTKBox.h	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/targets/viewer-fltk/cFLTKBox.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -27,19 +27,23 @@
 #ifndef cFLTKBox_h
 #define cFLTKBox_h
 
+#include "cColor.h"
 #include "cGUIBox.h"
+#include "cFLTKWidget.h"
 
 #include <FL/Fl_Box.H>
 
-class cFLTKBox : public cGUIBox {
+class cFLTKBox : public cGUIBox, public cFLTKWidget {
 protected:
   Fl_Box * m_box;
   
 public:
   cFLTKBox(cGUIContainer & parent, int x, int y, int width, int height, const cString & name="")
     : cGUIBox(parent, x, y, width, height, name)
+    , cFLTKWidget(this)
   {
     m_box = new Fl_Box(x, y, width, height, name);
+    SetWidget(m_box);
   }
   ~cFLTKBox() { delete m_box; }
 
@@ -53,14 +57,7 @@
     else if (m_type == BOX_RAISED_FRAME) m_box->box(FL_UP_FRAME);
     else if (m_type == BOX_LOWERED_FRAME) m_box->box(FL_DOWN_FRAME);
   }
-  
 
-  void Refresh() {
-    m_box->copy_label(m_name);
-    m_box->labelsize(m_font_size);
-    m_box->redraw();
-  }
-
   Fl_Box * GetFLTKPtr() { return m_box; }
 };
 

Added: development/source/targets/viewer-fltk/cFLTKGridView.cc
===================================================================
--- development/source/targets/viewer-fltk/cFLTKGridView.cc	                        (rev 0)
+++ development/source/targets/viewer-fltk/cFLTKGridView.cc	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,111 @@
+/*
+ *  cFLTKGridView.cc
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include "cFLTKGridView.h"
+
+#include "cCoreView_Info.h"
+#include "cPopulation.h"
+
+void cFLTKGridView::SetGenotypeColor(int color_id)
+{
+  switch (color_id) {
+  case -4: SetColor(cColor::BLACK); break;
+  case -3: SetColor(cColor::DARK_GRAY); break;
+  case -2: SetColor(cColor::GRAY); break;
+  case -1: SetColor(cColor::WHITE); break;
+  case 0:  SetColor(cColor::GREEN); break;
+  case 1:  SetColor(cColor::RED); break;
+  case 2:  SetColor(cColor::BLUE); break;
+  case 3:  SetColor(cColor::CYAN); break;
+  case 4:  SetColor(cColor::YELLOW); break;
+  case 5:  SetColor(cColor::MAGENTA); break;
+  case 6:  SetColor(cColor::LT_GREEN); break;
+  case 7:  SetColor(cColor::LT_RED); break;
+  case 8:  SetColor(cColor::LT_BLUE); break;
+  case 9:  SetColor(cColor::LT_CYAN); break;
+  case 10: SetColor(cColor::LT_YELLOW); break;
+  case 11: SetColor(cColor::LT_MAGENTA); break;
+  case 12: SetColor(cColor::DARK_GREEN); break;
+  case 13: SetColor(cColor::DARK_RED); break;
+  case 14: SetColor(cColor::DARK_BLUE); break;
+  case 15: SetColor(cColor::DARK_CYAN); break;
+  case 16: SetColor(cColor::DARK_YELLOW); break;
+  case 17: SetColor(cColor::DARK_MAGENTA); break;
+  };
+}
+
+void cFLTKGridView::Draw()
+{
+  Resize(w(), h());
+  cColor::Setup();
+
+  const int world_x = m_info.GetPopulation().GetWorldX();
+  const int world_y = m_info.GetPopulation().GetWorldY();
+
+  // Determine how large each cell can be and still fit in the window.
+  int cell_w = (w() - 2) / world_x;
+  int cell_h = (h() - 2) / world_y;
+  
+  // Make sure the cells are square.
+  if (cell_w < cell_h) cell_h = cell_w;
+  else cell_w = cell_h;
+
+//   const int grid_offset_x = 10;
+//   const int grid_offset_y = 10;
+
+//   SetColor(cColor::WHITE);
+//   DrawBox(0,0,GetWidth(), GetHeight(), true);
+  
+  SetColor(cColor::BLACK);
+  // DrawBox(0,0,GetWidth(), GetHeight(), false);
+  // DrawBox(grid_offset_x, grid_offset_y, world_x*10+10, world_y*10+10, true);
+  DrawBox(0, 0, world_x*cell_w+2, world_y*cell_h+2, true);
+
+  m_map_info.UpdateMaps();
+  const tArray<int> & color_map( m_map_info.GetColors() );
+  const tArray<int> & tag_map( m_map_info.GetTags() );
+  const int color_method = m_map_info.GetModeArg( m_map_info.GetColorMode() );
+  
+  int id = 0;
+  for (int y = 0; y < world_y; y++) {
+    for (int x = 0; x < world_x; x++) {
+      if (color_method == cCoreView_Map::COLORS_SCALE) {
+	if (color_map[id] < 0) SetColor(cColor::BLACK);
+	else SetColor(cColor::SET_BRIGHT[color_map[id]]);
+      } else {
+	SetGenotypeColor(color_map[id]);
+      }
+      //      DrawCircle(x*10, y*10, 4);
+      DrawBox(x*cell_w+2, y*cell_h+2, cell_w-2, cell_h-2, true);
+
+      //SetTagColor(tag_map[id]);
+      if (tag_map[id] > 0) {
+	SetColor(cColor::GREEN);
+	DrawBox(x*cell_w+1, y*cell_h+1, cell_w, cell_h, false);
+      }
+
+      id++;
+    }
+  }
+}

Added: development/source/targets/viewer-fltk/cFLTKGridView.h
===================================================================
--- development/source/targets/viewer-fltk/cFLTKGridView.h	                        (rev 0)
+++ development/source/targets/viewer-fltk/cFLTKGridView.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,59 @@
+/*
+ *  cFLTKGridView.h
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+// This is a class for managing Avida grids in the viewer.
+
+#ifndef cFLTKGridView_h
+#define cFLTKGridView_h
+
+#ifndef cFLTKBaseDraw_h
+#include "cFLTKBaseDraw.h"
+#endif
+
+#ifndef cCoreView_Map_h
+#include "cCoreView_Map.h"
+#endif
+
+class cFLTKGridView : public cFLTKBaseDraw {
+private:
+  cCoreView_Info & m_info;
+  cCoreView_Map m_map_info;
+
+  void SetGenotypeColor(int color_id);
+public:
+  cFLTKGridView(cCoreView_Info & info, cGUIContainer & parent,
+		int x, int y, int w, int h, const cString & name="")
+    : cFLTKBaseDraw(parent, x, y, w, h, name), m_info(info), m_map_info(info) { ; }
+  ~cFLTKGridView() { ; }
+
+  cCoreView_Map & GetMapInfo() { return m_map_info; }
+
+  void Draw();
+
+  int Handle(int event) {
+    return 0;
+  }
+};
+
+#endif

Added: development/source/targets/viewer-fltk/cFLTKWidget.h
===================================================================
--- development/source/targets/viewer-fltk/cFLTKWidget.h	                        (rev 0)
+++ development/source/targets/viewer-fltk/cFLTKWidget.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,61 @@
+/*
+ *  cFLTKWidget.h
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+// This is a base class for all FLTK widgets
+
+#ifndef cFLTKWidget_h
+#define cFLTKWidget_h
+
+#include "cColor.h"
+#include "cGUIWidget.h"
+
+#include <FL/Fl_Widget.H>
+#include <FL/fl_draw.H>
+
+class cFLTKWidget {
+protected:
+  Fl_Widget * m_widget;
+  cGUIWidget * m_gui_widget;
+
+public:
+  cFLTKWidget(cGUIWidget * gui_widget) : m_widget(NULL), m_gui_widget(gui_widget) { ; }
+  ~cFLTKWidget() { ; }
+
+  void SetWidget(Fl_Widget * widget) { m_widget = widget; }
+
+  void SetBackgroundColor(const cColor & color) {
+    assert(m_widget != NULL);
+    fl_color(color.Red(), color.Green(), color.Blue());
+    m_widget->color(fl_color());
+  }
+
+  void Refresh() {
+    m_widget->copy_label(m_gui_widget->GetName());
+    m_widget->labelsize(m_gui_widget->GetFontSize());
+    m_widget->redraw();
+  }
+
+};
+
+#endif

Modified: development/source/targets/viewer-fltk/cFLTKWindow.h
===================================================================
--- development/source/targets/viewer-fltk/cFLTKWindow.h	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/targets/viewer-fltk/cFLTKWindow.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -33,16 +33,17 @@
 
 #include "cFLTKBox.h"
 
-class cFLTKWindow : public cGUIWindow {
+class cFLTKWindow : public cGUIWindow, public cFLTKWidget {
 protected:
   Fl_Window * m_window;
   
 public:
-  cFLTKWindow() { ; }
   cFLTKWindow(int width, int height, const cString & name="")
     : cGUIWindow(width, height, name)
+    , cFLTKWidget(this)
   {
     m_window = new Fl_Window(width, height);
+    SetWidget(m_window);
   }
   ~cFLTKWindow() { delete m_window; }
 

Modified: development/source/targets/viewer-fltk/fltk-defs.cc
===================================================================
--- development/source/targets/viewer-fltk/fltk-defs.cc	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/targets/viewer-fltk/fltk-defs.cc	2007-08-20 17:27:17 UTC (rev 1964)
@@ -25,8 +25,14 @@
 #include "fltk-defs.h"
 
 #include "cGUIButton.h"
+#include "cGUIMenuItem.h"
 
 void GenericButtonCallback(void *, cGUIButton * button)
 {
   button->Press();
 }
+
+void GenericMenuCallback(void *, cGUIMenuItem * menu_item)
+{
+  menu_item->Trigger();
+}

Modified: development/source/targets/viewer-fltk/fltk-defs.h
===================================================================
--- development/source/targets/viewer-fltk/fltk-defs.h	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/targets/viewer-fltk/fltk-defs.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -28,7 +28,9 @@
 #define fltk_defs_h
 
 class cGUIButton;
+class cGUIMenuItem;
 
 void GenericButtonCallback(void *, cGUIButton * button);
+void GenericMenuCallback(void *, cGUIMenuItem * menu_item);
 
 #endif

Modified: development/source/targets/viewer-fltk/tFLTKButton.h
===================================================================
--- development/source/targets/viewer-fltk/tFLTKButton.h	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/targets/viewer-fltk/tFLTKButton.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -60,9 +60,4 @@
 };
 
 
-#include <FL/Fl_Button.H>
-
-
-
-
 #endif

Added: development/source/targets/viewer-fltk/tFLTKMenu.h
===================================================================
--- development/source/targets/viewer-fltk/tFLTKMenu.h	                        (rev 0)
+++ development/source/targets/viewer-fltk/tFLTKMenu.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,60 @@
+/*
+ *  tFLTKMenu.h
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+// This is a class to manage the FLTK GUI menus...
+
+#ifndef tFLTKMenu_h
+#define tFLTKMenu_h
+
+#include "tGUIMenu.h"
+#include "fltk-defs.h"
+
+#include "FL/Fl_Choice.H"
+
+template <class T> class tFLTKMenu : public tGUIMenu<T, int> {
+protected:
+  Fl_Choice * m_menu;
+
+  void SetupOption(int opt_id) {
+    tGUIMenuItem<T,int> * menu_item = tGUIMenu<T,int>::m_menu_options[opt_id];
+    m_menu->add(menu_item->GetName(), 0, (Fl_Callback*) GenericMenuCallback, menu_item);
+  }
+
+public:
+  tFLTKMenu(cGUIContainer & parent, int x, int y, int width, int height, const cString & name="")
+    : tGUIMenu<T, int>(parent, x, y, width, height, name)
+    , m_menu(new Fl_Choice(x, y, width, height, name))
+  {
+    m_menu = new Fl_Choice(x, y, width, height, name);
+    // m_menu->callback((Fl_Callback*) GenericMenuCallback, (void*)(this));
+  }
+  ~tFLTKMenu() { delete m_menu; }
+
+  void SetActive(int id) { m_menu->value(id); }
+
+  void BindKey(int key) { (void) key; }
+};
+
+
+#endif

Modified: development/source/targets/viewer-fltk/viewer-fltk.cc
===================================================================
--- development/source/targets/viewer-fltk/viewer-fltk.cc	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/targets/viewer-fltk/viewer-fltk.cc	2007-08-20 17:27:17 UTC (rev 1964)
@@ -40,10 +40,13 @@
 {
   PlatformExpert::Initialize();
   
-  printVersionBanner();
+  Avida::PrintVersionBanner();
   
   // Initialize the configuration data...
-  cWorld* world = new cWorld(cAvidaConfig::LoadWithCmdLineArgs(argc, argv));
+  cAvidaConfig* cfg = new cAvidaConfig();
+  Avida::ProcessCmdLineArgs(argc, argv, cfg);
+
+  cWorld* world = new cWorld(cfg);
   cAvidaDriver* driver = NULL;
   
   // Test to see if we should be in analyze mode only...
@@ -54,7 +57,7 @@
   driver->Run();
   
   // Exit Nicely
-  ExitAvida(0);
+  Avida::Exit(0);
   
   return 0;
 }

Modified: development/source/targets/viewer-text/cDriver_TextViewer.cc
===================================================================
--- development/source/targets/viewer-text/cDriver_TextViewer.cc	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/targets/viewer-text/cDriver_TextViewer.cc	2007-08-20 17:27:17 UTC (rev 1964)
@@ -38,7 +38,6 @@
 #include "cWorld.h"
 
 #include "cDriverManager.h"
-#include "cTextViewerManager.h"
 #include "cTextWindow.h"
 
 #include <cstdlib>
@@ -47,9 +46,11 @@
 
 cDriver_TextViewer::cDriver_TextViewer(cWorld* world)
   : m_world(world)
-  , m_info(m_world->GetPopulation(), 12)
+  , m_info(m_world, 12)
   , m_main_window(NULL, m_info)
   , m_bar_window(NULL, m_info)
+  , m_screen_map(m_info, m_main_window)
+  , m_cur_screen(NULL)
   , m_done(false)
 {
   // Setup the initial view mode (loaded from avida.cfg)
@@ -92,9 +93,6 @@
   wrefresh(stdscr);
   m_bar_window.Redraw();
   m_main_window.Redraw();
-
-//   getch();
-//   exit(0);
 }
 
 cDriver_TextViewer::~cDriver_TextViewer()
@@ -154,7 +152,6 @@
         const int next_id = population.ScheduleOrganism();
         if (next_id == m_info.GetStepOrganism()) {
           DoUpdate();
-//          m_view.NewUpdate();
           
           // This is needed to have the top bar drawn properly; I'm not sure why...
           static bool first_update = true;
@@ -178,7 +175,6 @@
     // Setup the viewer for the new update.
     if (m_info.GetStepOrganism() == -1) {
       DoUpdate();
-//      NewUpdate();
       
       // This is needed to have the top bar drawn properly; I'm not sure why...
       static bool first_update = true;
@@ -239,14 +235,8 @@
 //     break;
   case 'b':
   case 'B':
-//    ChangeCurScreen(NULL);
+    ChangeCurScreen(NULL);
     break;
-//   case 'C':
-//   case 'c':
-//     NavigateMapWindow();
-//     // Now we need to restore the proper window mode (already cleared)
-//     ChangeCurScreen(cur_screen);
-//     break;
 //   case 'e':
 //   case 'E':
 //     ChangeCurScreen(environment_screen);
@@ -255,10 +245,10 @@
 //   case 'H':
 //     ChangeCurScreen(hist_screen);
 //     break;
-//   case 'm':
-//   case 'M':
-//     ChangeCurScreen(map_screen);
-//     break;
+  case 'm':
+  case 'M':
+    ChangeCurScreen(&m_screen_map);
+    break;
 //   case 'n':
 //   case 'N':
 //     if (info.GetPauseLevel() == PAUSE_ON) {
@@ -389,12 +379,16 @@
 
 //   const int update = m_world->GetStats().GetUpdate();
 //   if (update % 10 == 0) clog << update << endl;
+
+  m_info.SetupUpdate();
   
   m_bar_window.SetBoldColor(COLOR_WHITE);
   m_bar_window.Print(1, 11, "%d", m_world->GetStats().GetUpdate());
   m_bar_window.SetColor(COLOR_WHITE);
 
   m_bar_window.Refresh();
+
+  if (m_cur_screen != NULL) m_cur_screen->Update();
   m_main_window.Refresh();
 
   const int pause_level = m_info.GetPauseLevel();
@@ -510,7 +504,14 @@
 }
 
 
+void cDriver_TextViewer::ChangeCurScreen(cTextScreen * new_screen)
+{
+  m_main_window.Clear();                       // Make sure contents of previous screen are cleared.
+  if (new_screen != NULL) new_screen->Draw();  // Draw new information on this screen.
+  m_cur_screen = new_screen;                   // Keep note of the current screen.
+}
 
+
 void ExitTextViewer(int exit_code)
 {
   signal(SIGINT, SIG_IGN);           // Ignore all future interupts.

Modified: development/source/targets/viewer-text/cDriver_TextViewer.h
===================================================================
--- development/source/targets/viewer-text/cDriver_TextViewer.h	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/targets/viewer-text/cDriver_TextViewer.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -32,6 +32,10 @@
 #ifndef cCoreView_Info_h
 #include "cCoreView_Info.h"
 #endif
+
+#ifndef cScreen_Map_h
+#include "cScreen_Map.h"
+#endif
  
 #ifndef cTextWindow_h
 #include "cTextWindow.h"
@@ -60,8 +64,13 @@
   cTextWindow m_main_window;
   cTextWindow m_bar_window;
 
+  cScreen_Map m_screen_map;
+
+  cTextScreen * m_cur_screen;
+
   bool m_done;           // This is set to true when run should finish.
 
+  void ChangeCurScreen(cTextScreen * new_screen);
 public:
   cDriver_TextViewer(cWorld* world);
   ~cDriver_TextViewer();

Added: development/source/targets/viewer-text/cScreen_Map.cc
===================================================================
--- development/source/targets/viewer-text/cScreen_Map.cc	                        (rev 0)
+++ development/source/targets/viewer-text/cScreen_Map.cc	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,88 @@
+/*
+ *  cScreen_Map.cc
+ *  Avida
+ *
+ *  Created by Charles on 7-1-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include "cScreen_Map.h"
+
+#include "cPopulation.h"
+
+cScreen_Map::cScreen_Map(cCoreView_Info & info, cTextWindow & window)
+  : cTextScreen(info, window)
+  , m_map_info(info)
+{
+}
+
+cScreen_Map::~cScreen_Map()
+{
+}
+
+void cScreen_Map::Draw()
+{
+  m_window.Box();
+  Update();
+}
+
+void cScreen_Map::Update()
+{
+  m_map_info.UpdateMaps();
+  const tArray<int> & color_map( m_map_info.GetColors() );
+
+  const int world_x = m_info.GetPopulation().GetWorldX();
+  const int world_y = m_info.GetPopulation().GetWorldY();
+  
+  int id = 0;
+  for (int y = 1; y <= world_y; y++) {
+    for (int x = 1; x <= world_x; x++) {
+      SetGenotypeColor(color_map[id]);
+      m_window.Print(y, 2*x, CHAR_BULLET);
+      id++;
+    }
+  }
+}
+
+bool cScreen_Map::DoInput(int input)
+{
+}
+
+
+void cScreen_Map::SetGenotypeColor(int color_id)
+{
+  switch (color_id) {
+  case -4: m_window.SetColor(COLOR_OFF); break;
+  case -3: m_window.SetBoldColor(COLOR_OFF); break;
+  case -2: m_window.SetColor(COLOR_WHITE); break;
+  case -1: m_window.SetBoldColor(COLOR_WHITE); break;
+  case 0:  m_window.SetBoldColor(COLOR_GREEN); break;
+  case 1:  m_window.SetBoldColor(COLOR_RED); break;
+  case 2:  m_window.SetBoldColor(COLOR_BLUE); break;
+  case 3:  m_window.SetBoldColor(COLOR_CYAN); break;
+  case 4:  m_window.SetBoldColor(COLOR_YELLOW); break;
+  case 5:  m_window.SetBoldColor(COLOR_MAGENTA); break;
+  case 6:  m_window.SetColor(COLOR_GREEN); break;
+  case 7:  m_window.SetColor(COLOR_RED); break;
+  case 8:  m_window.SetColor(COLOR_BLUE); break;
+  case 9:  m_window.SetColor(COLOR_CYAN); break;
+  case 10: m_window.SetColor(COLOR_YELLOW); break;
+  case 11: m_window.SetColor(COLOR_MAGENTA); break;
+  };
+}

Added: development/source/targets/viewer-text/cScreen_Map.h
===================================================================
--- development/source/targets/viewer-text/cScreen_Map.h	                        (rev 0)
+++ development/source/targets/viewer-text/cScreen_Map.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,50 @@
+/*
+ *  cScreen_Map.h
+ *  Avida
+ *
+ *  Created by Charles on 7-1-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef cScreen_Map_h
+#define cScreen_Map_h
+
+#ifndef cCoreView_Map_h
+#include "cCoreView_Map.h"
+#endif
+
+#ifndef cTextScreen_h
+#include "cTextScreen.h"
+#endif
+
+class cScreen_Map : public cTextScreen {
+private:
+  cCoreView_Map m_map_info;
+
+  void SetGenotypeColor(int color_id);
+public:
+  cScreen_Map(cCoreView_Info & info, cTextWindow & window);
+  ~cScreen_Map();
+
+  void Draw();
+  void Update();
+  bool DoInput(int input);
+};
+
+#endif

Added: development/source/targets/viewer-text/cTextScreen.h
===================================================================
--- development/source/targets/viewer-text/cTextScreen.h	                        (rev 0)
+++ development/source/targets/viewer-text/cTextScreen.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,50 @@
+/*
+ *  cTextScreen.h
+ *  Avida
+ *
+ *  Created by Charles on 7-1-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#ifndef cTextScreen_h
+#define cTextScreen_h
+
+#ifndef cCoreView_Info_h
+#include "cCoreView_Info.h"
+#endif
+
+#ifndef cTextWindow_h
+#include "cTextWindow.h"
+#endif
+
+class cTextScreen  {
+protected:
+  cCoreView_Info & m_info;
+  cTextWindow & m_window;
+
+public:
+  cTextScreen(cCoreView_Info & info, cTextWindow & window) : m_info(info), m_window(window) { ; }
+  virtual ~cTextScreen() { ; }
+
+  virtual void Draw() = 0;
+  virtual void Update() = 0;
+  virtual bool DoInput(int input) = 0;
+};
+
+#endif

Deleted: development/source/targets/viewer-text/cTextViewerManager.cc
===================================================================
--- development/source/targets/viewer-text/cTextViewerManager.cc	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/targets/viewer-text/cTextViewerManager.cc	2007-08-20 17:27:17 UTC (rev 1964)
@@ -1,534 +0,0 @@
-/*
- *  cTextViewerManager.cc
- *  Avida
- *
- *  Created by Charles on 7-1-07
- *  Copyright 1999-2007 Michigan State University. All rights reserved.
- *
- *
- *  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; version 2
- *  of the License.
- *
- *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- */
-
-#include "cTextViewerManager.h"
-
-#include "cEnvironment.h"
-#include "cGenotype.h"
-#include "cHardwareManager.h"
-#include "cOrganism.h"
-#include "cPhenotype.h"
-#include "cPopulation.h"
-#include "cPopulationCell.h"
-#include "cStats.h"
-#include "cTestCPU.h"
-#include "cHardwareBase.h"
-
-// #include "cMenuWindow.h"
-// #include "cTextWindow.h"
-// #include "cBarScreen.h"
-// #include "cMapScreen.h"
-// #include "cStatsScreen.h"
-// #include "cHistScreen.h"
-// #include "cOptionsScreen.h"
-// #include "cZoomScreen.h"
-// #include "cEnvironmentScreen.h"
-// #include "cAnalyzeScreen.h"
-
-#include "platform.h"
-
-#include <csignal>
-#include <fstream>
-
-#if AVIDA_PLATFORM(WINDOWS)
-# include <process.h>
-# define kill(x, y)
-#else
-# include <unistd.h>
-#endif
-
-using namespace std;
-
-
-cTextViewerManager::cTextViewerManager(cWorld* world) : info(world, this)
-{
-  Setup("Avida");
-
-//   map_screen     = new cMapScreen     (0,0,3,0,info, world->GetPopulation());
-//   stats_screen   = new cStatsScreen   (world, 0, 0, 3, 0, info);
-//   hist_screen    = new cHistScreen    (0,0,3,0,info, world->GetPopulation());
-//   options_screen = new cOptionsScreen (0,0,3,0,info);
-//   zoom_screen    = new cZoomScreen    (0,0,3,0,info, world->GetPopulation());
-//   environment_screen = new cEnvironmentScreen (world, 0, 0, 3, 0, info);
-//   analyze_screen = new cAnalyzeScreen(world, 0, 0, 3, 0, info);
-
-  info.SetActiveCell( &( world->GetPopulation().GetCell(0) ) );
-}
-
-cTextViewerManager::~cTextViewerManager()
-{
-//   if (map_screen) delete map_screen;
-//   if (stats_screen) delete stats_screen;
-//   if (hist_screen) delete hist_screen;
-//   if (options_screen) delete options_screen;
-//   if (zoom_screen) delete zoom_screen;
-//   if (environment_screen) delete environment_screen;
-//   if (analyze_screen) delete analyze_screen;
-
-  EndProg(0);
-}
-
-void cTextViewerManager::Setup(const cString & in_name)
-{
-  cur_screen = NULL;
-
-  // Setup text-interface
-
-  StartProg();
-
-//   bar_screen = new cBarScreen(&info.GetWorld(), 3, 0, 0, 0, info, in_name);
-//   base_window = new cTextWindow(0,0,3,0);
-//   bar_screen->Draw();
-}
-
-void cTextViewerManager::SetViewMode(int in_mode)
-{
-  if (in_mode == MODE_BLANK) {
-    cur_screen = NULL;
-//   } else if (in_mode == MODE_MAP) {
-//     cur_screen = map_screen;
-//   } else if (in_mode == MODE_STATS) {
-//     cur_screen = stats_screen;
-//   } else if (in_mode == MODE_HIST) {
-//     cur_screen = hist_screen;
-//   } else if (in_mode == MODE_OPTIONS) {
-//     cur_screen = options_screen;
-//   } else if (in_mode == MODE_ZOOM) {
-//     cur_screen = zoom_screen;
-//   } else if (in_mode == MODE_ENVIRONMENT) {
-//     cur_screen = environment_screen;
-//   } else if (in_mode == MODE_ANALYZE) {
-//     cur_screen = analyze_screen;
-  }
-}
-
-void cTextViewerManager::Refresh()
-{
-  ChangeCurScreen(cur_screen);
-//  bar_screen->Redraw();
-}
-
-void cTextViewerManager::Redraw()
-{
-//   bar_screen->Redraw();
-  if (cur_screen) cur_screen->Redraw();
-  else base_window->Redraw();
-}
-
-void cTextViewerManager::NewUpdate()
-{
-  if (info.GetPauseLevel() == PAUSE_ADVANCE_STEP) {
-    return;
-  }
-  NotifyUpdate();
-}
-
-void cTextViewerManager::NotifyUpdate()
-{
-//   bar_screen->Update();
-  info.UpdateSymbols();
-
-  if (cur_screen) cur_screen->Update();
-  DoInputs();
-}
-
-void cTextViewerManager::NotifyError(const cString & in_string)
-{
-  cString out_string(in_string);
-  out_string.Insert("Error: ");
-  Notify(out_string);
-  EndProg(1);
-}
-
-void cTextViewerManager::NotifyWarning(const cString & in_string)
-{
-  cString out_string(in_string);
-  out_string.Insert("Warning: ");
-  Notify(out_string);
-}
-
-void cTextViewerManager::NotifyComment(const cString & in_string)
-{
-  if (cur_screen == analyze_screen) analyze_screen->Notify(in_string);
-  else Notify(in_string);
-}
-
-void cTextViewerManager::NotifyOutput(const cString & in_string)
-{
-//   analyze_screen->Notify(in_string);
-//   if (cur_screen == analyze_screen) analyze_screen->Refresh();
-}
-
-void cTextViewerManager::DoBreakpoint()
-{
-  if (info.GetPauseLevel() == PAUSE_OFF ||
-      info.GetPauseLevel() == PAUSE_ADVANCE_UPDATE) {
-    Pause();
-    NotifyUpdate();
-  }
-}
-
-void cTextViewerManager::DoInputs()
-{
-  // If we are paused, delay doing anything else until a key is pressed.
-  if (info.GetPauseLevel() != PAUSE_OFF) nodelay(stdscr, false);
-
-  // If we are in step-wise mode, "finish" this step!
-  if (info.GetPauseLevel() == PAUSE_ADVANCE_STEP) {
-    info.DisEngageStepMode();
-    info.SetPauseLevel(PAUSE_ON);
-  }
-
-  // If there is any input in the buffer, process all of it.
-  int cur_char = ERR;
-  while ((cur_char = GetInput()) != ERR || info.GetPauseLevel() == PAUSE_ON) {
-    bool found_keypress = ProcessKeypress(cur_char);
-
-    // If we couldn't manage the keypress here, check the current screen.
-    if (found_keypress == false && cur_screen) cur_screen->DoInput(cur_char);
-  }
-
-  if (info.GetPauseLevel() == PAUSE_ADVANCE_UPDATE) {
-    info.SetPauseLevel(PAUSE_ON);
-  }
-
-  nodelay(stdscr, true);
-}
-
-bool cTextViewerManager::ProcessKeypress(int keypress)
-{
-  bool unknown = false;
-
-  switch (keypress) {
-//   case 'a':
-//   case 'A':
-//     ChangeCurScreen(analyze_screen);
-//     break;
-  case 'b':
-  case 'B':
-    ChangeCurScreen(NULL);
-    break;
-//   case 'C':
-//   case 'c':
-//     NavigateMapWindow();
-//     // Now we need to restore the proper window mode (already cleared)
-//     ChangeCurScreen(cur_screen);
-//     break;
-//   case 'e':
-//   case 'E':
-//     ChangeCurScreen(environment_screen);
-//     break;
-//   case 'h':
-//   case 'H':
-//     ChangeCurScreen(hist_screen);
-//     break;
-//   case 'm':
-//   case 'M':
-//     ChangeCurScreen(map_screen);
-//     break;
-//   case 'n':
-//   case 'N':
-//     if (info.GetPauseLevel() == PAUSE_ON) {
-//       info.SetPauseLevel(PAUSE_ADVANCE_UPDATE);
-//       // parasite_zoom = false; // if executing, show code that is running
-//       info.GetActiveCell()->GetOrganism()->GetPhenotype().SetFault("");
-//       nodelay(stdscr, true); // Don't delay for input; get to processing.
-//     }
-//     if (cur_screen) cur_screen->AdvanceUpdate();
-//     break;
-//   case 'o':
-//   case 'O':
-//     ChangeCurScreen(options_screen);
-//     break;
-  case 'p':
-  case 'P':
-    TogglePause();
-    // We don't want to delay if we're unpaused.
-    if (info.GetPauseLevel() == PAUSE_OFF) nodelay(stdscr, true);
-    else nodelay(stdscr, false);
-    break;
-  case 'q':
-    if (!Confirm("Are you sure you want to quit?")) break;
-  case 'Q':      // Note: Capital 'Q' quits w/o confirming.
-    // clear the windows before we go.  Do bar window last to end at top.
-    base_window->Redraw();
-    bar_screen->Clear();
-    bar_screen->Refresh();
-    EndProg(0);  // This implementation calls exit(), blowing us clean away
-    break;
-//   case 's':
-//   case 'S':
-//     ChangeCurScreen(stats_screen);
-//     break;
-//   case 'W':
-//   case 'w':
-//     CloneSoup();
-//     break;
-//   case 'X':
-//   case 'x':
-//     ExtractCreature();
-//     break;
-//   case 'z':
-//   case 'Z':
-//     ChangeCurScreen(zoom_screen);
-//     break;
-  case 3: // CTRL-C...
-    exit(0);
-    break;
-  case 12: // CTRL-L...
-    Refresh();
-    break;
-  case 26: // CTRL-Z
-    kill(getpid(), SIGTSTP);
-    break;
-//   case '*':   // Test Key!!!
-//     if (true) {
-//       Confirm("Starting Tests.");
-//       cMenuWindow menu(50);
-//       char message[40];
-//       for (int j = 0; j < 50; j++) {
-// 	sprintf(message, "Line %d", j);
-// 	menu.AddOption(j, message);
-//       }
-//       menu.SetActive(3);
-//       menu.Activate(base_window);
-//       Redraw();
-//     }
-//     break;
-  case ERR:
-    break;
-  default:
-    unknown = true;
-    break;
-  }
-
-  return !unknown;
-}
-
-void cTextViewerManager::TogglePause()
-{
-  // If the run is already paused, un-pause it!
-  if (info.GetPauseLevel() != PAUSE_OFF) {
-    info.DisEngageStepMode();
-    info.SetPauseLevel(PAUSE_OFF);
-    if (info.GetActiveCell()->IsOccupied()) {
-      info.GetActiveCell()->GetOrganism()->GetPhenotype().SetFault("");
-    }
-  }
-
-  // Otherwise, turn on the pause.
-  else {
-    info.SetPauseLevel(PAUSE_ON);
-  }
-
-  // Redraw the screen to account for the toggled pause.
-  if (cur_screen) cur_screen->Draw();
-}
-
-void cTextViewerManager::CloneSoup()
-{
-  cString filename;
-  filename.Set("clone.%d", info.GetWorld().GetStats().GetUpdate());
-  ofstream fp(static_cast<const char*>(filename));
-  info.GetPopulation().SaveClone(fp);
-  cString message;
-  message.Set("Saved clone to file: %s", static_cast<const char*>(filename));
-  Notify(message);
-}
-
-void cTextViewerManager::ExtractCreature()
-{
-  cGenotype * cur_gen = info.GetActiveGenotype();
-  cString gen_name = cur_gen->GetName();
-
-  if (gen_name == "(no name)")
-    gen_name.Set("%03d-unnamed", cur_gen->GetLength());
-
-  if (cur_screen) cur_screen->Print(20, 0, "Extracting %s...", static_cast<const char*>(gen_name));
-
-  cTestCPU* testcpu = info.GetWorld().GetHardwareManager().CreateTestCPU();
-  testcpu->PrintGenome(info.GetWorld().GetDefaultContext(), cur_gen->GetGenome(), gen_name);
-  delete testcpu;
-
-  if (cur_screen) {
-    cur_screen->Print(20, 24, "Done.");
-    cur_screen->Refresh();
-  }
-}
-
-
-void cTextViewerManager::ChangeCurScreen(cScreen* new_screen)
-{
-  if (cur_screen) cur_screen->Exit();
-
-  cur_screen = new_screen;
-  base_window->Redraw();
-  bar_screen->Redraw();
-  if (cur_screen) {
-    cur_screen->Clear();
-    cur_screen->Draw();
-  }
-}
-
-// void cTextViewerManager::PrintMerit(int in_y, int in_x, double in_merit)
-// {
-//   // if we can print the merit normally, do so.
-//   if (in_merit < 1000000.0) {
-//     if (cur_screen) cur_screen->Print(in_y, in_x, "%d", ((int) in_merit));
-//   }
-
-//   // otherwise use scientific notation. (or somesuch)
-//   else {
-//     if (cur_screen) cur_screen->Print(in_y, in_x, "%7.1e", in_merit);
-//   }
-// }
-
-// void cTextViewerManager::PrintFitness(int in_y, int in_x, double in_fitness)
-// {
-//   if (!cur_screen) return;
-
-//   // If we can print the fitness, do so!
-//   if (in_fitness <= 0.0) {
-//     cur_screen->Print(in_y, in_x, " 0.0000");
-//   }
-//   else if (in_fitness < 10)
-//     cur_screen->Print(in_y, in_x, "%7.4f", in_fitness);
-//   //  else if (in_fitness < 100)
-//   //    cur_screen->Print(in_y, in_x, "%7.3f", in_fitness);
-//   else if (in_fitness < 1000)
-//     cur_screen->Print(in_y, in_x, "%7.2f", in_fitness);
-//   //  else if (in_fitness < 10000)
-//   //    cur_screen->Print(in_y, in_x, "%7.1f", in_fitness);
-//   else if (in_fitness < 100000)
-//     cur_screen->Print(in_y, in_x, "%7.0f", in_fitness);
-
-//   // Otherwise use scientific notations.
-//   else
-//     cur_screen->Print(in_y, in_x, "%7.1e", in_fitness);
-// }
-
-void cTextViewerManager::NavigateMapWindow()
-{
-//   map_screen->Navigate();
-}
-
-
-int cTextViewerManager::Confirm(const cString & message)
-{
-  const int mess_length = message.GetSize();
-
-  // Create a confirm window, and draw it on the screen.
-
-  cTextWindow * conf_win
-    = new cTextWindow(3, mess_length + 10, 10, (base_window->Width() - 10 - mess_length) / 2);
-  conf_win->Box();
-  conf_win->SetBoldColor(COLOR_WHITE);
-  conf_win->Print(1, 2, "%s (y/n)", static_cast<const char*>(message));
-  conf_win->SetBoldColor(COLOR_CYAN);
-  conf_win->Print(1, mess_length + 4, 'y');
-  conf_win->Print(1, mess_length + 6, 'n');
-  conf_win->SetColor(COLOR_WHITE);
-  conf_win->Refresh();
-
-  // Wait for the results.
-  bool finished = false;
-  bool result = false;
-  int cur_char;
-
-  while (finished == false) {
-    cur_char = GetInput();
-    switch (cur_char) {
-    case 'q':
-    case 'Q':
-    case 'n':
-    case 'N':
-    case ' ':
-    case '\n':
-    case '\r':
-      finished = true;
-      result = false;
-      break;
-    case 'y':
-    case 'Y':
-      finished = true;
-      result = true;
-      break;
-    }
-  }
-
-  // Delete the window, redraw the screen, and return the results.
-  delete conf_win;
-  Redraw();
-  return result;
-}
-
-void cTextViewerManager::Notify(const cString & message)
-{
-  cString mess_copy(message);
-
-  // Setup all of the individual lines.
-  int num_lines = message.CountNumLines();
-  cString * line_array = new cString[num_lines];
-  int max_width = 0;
-  for (int i = 0; i < num_lines; i++) {
-    line_array[i] = mess_copy.PopLine();
-    if (line_array[i].GetSize() > max_width)
-      max_width = line_array[i].GetSize();
-  }
-
-  // Create a window and draw it on the screen.
-
-  cTextWindow * notify_win
-    = new cTextWindow(2 + num_lines, max_width + 4, (24 - num_lines - 3) / 2,
-		      (70 - max_width) / 2);
-  notify_win->Box();
-  notify_win->SetBoldColor(COLOR_WHITE);
-  for (int j = 0; j < num_lines; j++) {
-    notify_win->Print(1 + j, 2, "%s", static_cast<const char*>(line_array[j]));
-  }
-  notify_win->Refresh();
-
-  // Wait for the results.
-  bool finished = false;
-  int cur_char;
-
-  while (!finished) {
-    cur_char = GetInput();
-    switch (cur_char) {
-    case 'q':
-    case 'Q':
-    case ' ':
-    case '\n':
-    case '\r':
-      finished = true;
-      break;
-    }
-  }
-
-  // Delete the window and redraw the screen.
-  delete notify_win;
-  delete [] line_array;
-  Redraw();
-}
-

Deleted: development/source/targets/viewer-text/cTextViewerManager.h
===================================================================
--- development/source/targets/viewer-text/cTextViewerManager.h	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/targets/viewer-text/cTextViewerManager.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -1,123 +0,0 @@
-/*
- *  cTextViewerManager.h
- *  Avida
- *
- *  Created by Charles on 7-1-07
- *  Copyright 1999-2007 Michigan State University. All rights reserved.
- *
- *
- *  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; version 2
- *  of the License.
- *
- *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- *
- */
-
-#ifndef cTextViewerManager_h
-#define cTextViewerManager_h
-
-#ifndef cString_h
-#include "cString.h"
-#endif
-
-#ifndef cCoreView_Info_h
-#include "cCoreView_Info.h"
-#endif
-
-class cScreen;
-class cTextWindow;
-class cBarScreen;
-class cMapScreen;
-class cStatsScreen;
-class cHistScreen;
-class cOptionsScreen;
-class cZoomScreen;
-class cEnvironmentScreen;
-class cAnalyzeScreen;
-class cWorld;
-
-class cTextViewerManager {
-private:
-  cCoreView_Info info;
-
-  // Window information...
-  cTextWindow * base_window;
-  cScreen * cur_screen;
-  cBarScreen * bar_screen;
-  cMapScreen * map_screen;
-  cStatsScreen * stats_screen;
-  cHistScreen * hist_screen;
-  cOptionsScreen * options_screen;
-  cZoomScreen * zoom_screen;
-  cEnvironmentScreen * environment_screen;
-  cAnalyzeScreen * analyze_screen;
-
-  // Window managing functions...
-
-  void TogglePause();
-  void CloneSoup();
-  void ExtractOrganism();
-
-  // Input function
-  void DoInputs();
-
-  // Screen helpers
-  void ChangeCurScreen(cScreen * new_screen);
-  void PrintMerit(int in_y, int in_x, double in_merit);
-  void PrintFitness(int in_y, int in_x, double in_fitness);
-
-  // Map navigation
-  void NavigateMapWindow();
-
-public:
-  enum eTextViewerMode {
-    MODE_BLANK       = 0,
-    MODE_MAP         = 1,
-    MODE_STATS       = 2,
-    MODE_HIST        = 3,
-    MODE_OPTIONS     = 4,
-    MODE_ZOOM        = 5,
-    MODE_ENVIRONMENT = 6,
-    MODE_ANALYZE     = 7
-  };
-
-  cTextViewerManager(cWorld* world);
-  virtual ~cTextViewerManager();
-
-  void Setup(const cString & in_name);
-  void SetViewMode(int in_mode);
-
-  bool ProcessKeypress(int keypress);
-
-  void NewUpdate();
-  void NotifyUpdate();
-  void NotifyError(const cString & in_string);
-  void NotifyWarning(const cString & in_string);
-  void NotifyComment(const cString & in_string);
-  void NotifyOutput(const cString & in_string);
-  void Pause() { info.SetPauseLevel(cCoreView_Info::PAUSE_ON); }
-  void DoBreakpoint();
-  
-  int Confirm(const cString & message);
-  void Notify(const cString & message);
-
-  int GetStepOrganism() { return info.GetStepOrganism(); }
-  void SetStepOrganism(int in_id) { info.SetStepOrganism(in_id); }
-
-  void Refresh();
-
-  // Methods called by sub-windows.
-  void Redraw();
-};
-
-
-#endif

Added: development/source/tools/cBitArray.cc
===================================================================
--- development/source/tools/cBitArray.cc	                        (rev 0)
+++ development/source/tools/cBitArray.cc	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,550 @@
+#include "cBitArray.h"
+
+void cRawBitArray::Copy(const cRawBitArray & in_array, const int num_bits)
+{
+  const int num_fields = GetNumFields(num_bits);
+  if (bit_fields != NULL) {
+    delete [] bit_fields;
+  }
+  bit_fields = new int[num_fields];
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] = in_array.bit_fields[i];
+  }
+}
+
+
+bool cRawBitArray::IsEqual(const cRawBitArray & in_array, int num_bits) const
+{
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    if (bit_fields[i] != in_array.bit_fields[i]) return false;
+  }
+  return true;
+}
+
+
+void cRawBitArray::Resize(const int old_bits, const int new_bits)
+{
+  const int num_old_fields = GetNumFields(old_bits);
+  const int num_new_fields = GetNumFields(new_bits);
+  if (num_old_fields == num_new_fields) {
+    // Clear all bits past the new end and stop.
+    int & last_field = bit_fields[num_new_fields - 1];
+    for (int i = new_bits; i < old_bits; i++) {
+      const int clear_bit = i & 31;
+      last_field &= ~(1 << clear_bit);
+    }
+    return;
+  }
+
+  // If we made it this far, we have to change the number of fields.
+  // Create the new bit array and copy the old one into it.
+  int * new_bit_fields = new int[ num_new_fields ];
+  for (int i = 0; i < num_new_fields && i < num_old_fields; i++) {
+    new_bit_fields[i] = bit_fields[i];
+  }
+  
+  // If the old bits are longer, we need to clear the end of the last
+  // bit field.
+  if (num_old_fields > num_new_fields) {
+    int & last_field = new_bit_fields[num_new_fields - 1];
+    for (int clear_bit=GetFieldPos(new_bits); clear_bit < 32; clear_bit++) {
+      last_field &= ~(1 << clear_bit);
+    }
+  }
+  
+  // If the new bits are longer, clear everything past the end of the old
+  // bits.
+  for (int i = num_old_fields; i < num_new_fields; i++) {
+    new_bit_fields[i] = 0;
+  }
+
+  if (bit_fields != NULL) {
+    delete [] bit_fields;
+  }
+  bit_fields = new_bit_fields;
+}
+
+
+void cRawBitArray::ResizeSloppy(const int new_bits)
+{
+  const int new_fields = GetNumFields(new_bits);
+  if (bit_fields != NULL) {
+    delete [] bit_fields;
+  }
+  bit_fields = new int[ new_fields ];
+}
+
+void cRawBitArray::ResizeClear(const int new_bits)
+{
+  ResizeSloppy(new_bits);
+  Zero(new_bits);
+}
+
+
+// This technique counts the number of bits; it loops through once for each
+// bit equal to 1.  This is reasonably fast for sparse arrays.
+int cRawBitArray::CountBits(const int num_bits) const
+{
+  const int num_fields = GetNumFields(num_bits);
+  int bit_count = 0;
+  
+  for (int i = 0; i < num_fields; i++) {
+    int temp = bit_fields[i];
+    while (temp != 0) {
+      temp = temp & (temp - 1);
+      bit_count++;
+    }
+  }
+  return bit_count;
+}
+
+// This technique is another way of counting bits; It does a bunch of
+// clever bit tricks to do it in parallel in each int.
+int cRawBitArray::CountBits2(const int num_bits) const
+{
+  const int num_fields = GetNumFields(num_bits);
+  int bit_count = 0;
+  
+  for (int i = 0; i < num_fields; i++) {
+    const int  v = bit_fields[i];
+    unsigned int const t1 = v - ((v >> 1) & 0x55555555);
+    unsigned int const t2 = (t1 & 0x33333333) + ((t1 >> 2) & 0x33333333);
+    bit_count += ((t2 + (t2 >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
+  }
+  return bit_count;
+}
+
+int cRawBitArray::FindBit1(const int num_bits, const int start_pos) const
+{
+  // @CAO -- There are probably better ways to do this with bit tricks.
+  for (int i = start_pos; i < num_bits; i++) {
+    if (GetBit(i) == true) return i;
+  }
+
+  return -1;
+}
+
+tArray<int> cRawBitArray::GetOnes(const int num_bits) const
+{
+  // @CAO -- There are probably better ways to do this with bit tricks.
+  tArray<int> out_array(CountBits2(num_bits));
+  int cur_pos = 0;
+  for (int i = 0; i < num_bits; i++) {
+    if (GetBit(i) == true) out_array[cur_pos++] = i;
+  }
+
+  return out_array;
+}
+
+
+void cRawBitArray::NOT(const int num_bits)
+{
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] = ~bit_fields[i];
+  }
+
+  const int last_bit = GetFieldPos(num_bits);
+  if (last_bit > 0) {
+    bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
+  }
+}
+
+void cRawBitArray::AND(const cRawBitArray & array2, const int num_bits)
+{
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] &= array2.bit_fields[i];
+  }
+}
+
+void cRawBitArray::OR(const cRawBitArray & array2, const int num_bits)
+{
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] |= array2.bit_fields[i];
+  }
+}
+
+void cRawBitArray::NAND(const cRawBitArray & array2, const int num_bits)
+{
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] = ~(bit_fields[i] & array2.bit_fields[i]);
+  }
+
+  const int last_bit = GetFieldPos(num_bits);
+  if (last_bit > 0) {
+    bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
+  }
+}
+
+void cRawBitArray::NOR(const cRawBitArray & array2, const int num_bits)
+{
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] = ~(bit_fields[i] | array2.bit_fields[i]);
+  }
+
+  const int last_bit = GetFieldPos(num_bits);
+  if (last_bit > 0) {
+    bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
+  }
+}
+
+void cRawBitArray::XOR(const cRawBitArray & array2, const int num_bits)
+{
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] ^= array2.bit_fields[i];
+  }
+
+}
+
+void cRawBitArray::EQU(const cRawBitArray & array2, const int num_bits)
+{
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] = ~(bit_fields[i] ^ array2.bit_fields[i]);
+  }
+
+  const int last_bit = GetFieldPos(num_bits);
+  if (last_bit > 0) {
+    bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
+  }
+}
+
+
+
+
+
+void cRawBitArray::NOT(const cRawBitArray & array1, const int num_bits)
+{
+  ResizeSloppy(num_bits);
+
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] = ~array1.bit_fields[i];
+  }
+
+  const int last_bit = GetFieldPos(num_bits);
+  if (last_bit > 0) {
+    bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
+  }
+}
+
+void cRawBitArray::AND(const cRawBitArray & array1,
+		       const cRawBitArray & array2, const int num_bits)
+{
+  ResizeSloppy(num_bits);
+
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] = array1.bit_fields[i] & array2.bit_fields[i];
+  }
+}
+
+void cRawBitArray::OR(const cRawBitArray & array1,
+		      const cRawBitArray & array2, const int num_bits)
+{
+  ResizeSloppy(num_bits);
+
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] = array1.bit_fields[i] | array2.bit_fields[i];
+  }
+}
+
+void cRawBitArray::NAND(const cRawBitArray & array1,
+			const cRawBitArray & array2, const int num_bits)
+{
+  ResizeSloppy(num_bits);
+
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] = ~(array1.bit_fields[i] & array2.bit_fields[i]);
+  }
+
+  const int last_bit = GetFieldPos(num_bits);
+  if (last_bit > 0) {
+    bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
+  }
+}
+
+void cRawBitArray::NOR(const cRawBitArray & array1,
+		       const cRawBitArray & array2, const int num_bits)
+{
+  ResizeSloppy(num_bits);
+
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] = ~(array1.bit_fields[i] | array2.bit_fields[i]);
+  }
+
+  const int last_bit = GetFieldPos(num_bits);
+  if (last_bit > 0) {
+    bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
+  }
+}
+
+void cRawBitArray::XOR(const cRawBitArray & array1,
+		       const cRawBitArray & array2, const int num_bits)
+{
+  ResizeSloppy(num_bits);
+
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] = array1.bit_fields[i] ^ array2.bit_fields[i];
+  }
+
+}
+
+void cRawBitArray::EQU(const cRawBitArray & array1, const cRawBitArray & array2, const int num_bits)
+{
+  ResizeSloppy(num_bits);
+
+  const int num_fields = GetNumFields(num_bits);
+  for (int i = 0; i < num_fields; i++) {
+    bit_fields[i] = ~(array1.bit_fields[i] ^ array2.bit_fields[i]);
+  }
+
+  const int last_bit = GetFieldPos(num_bits);
+  if (last_bit > 0) {
+    bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
+  }
+}
+
+
+std::ostream & operator << (std::ostream & out, const cBitArray & bit_array)
+{
+  bit_array.Print(out);
+  return out;
+}
+
+
+
+#ifdef UNITTEST_CBITARRAY
+
+int main()
+{
+  int passed = true;
+  // Start by testing the cRawBitArray class.
+
+  // Test default constructor.
+  cRawBitArray bit_array1;
+  bit_array1.ResizeClear(10);
+  for (int i = 0; i < 10; i++) {
+    if (bit_array1.GetBit(i) != false) {
+      passed = false;
+      cerr << "ERROR in testing bit that should be cleared by ResizeClear()!"
+	   << endl;
+    }
+  }
+
+  //bit_array1.Print(10);
+  
+  bit_array1.SetBit(1, true);
+  bit_array1.SetBit(3, true);
+  bit_array1.SetBit(5, true);
+  bit_array1.SetBit(7, true);
+  bit_array1.SetBit(9, true);
+  
+  for (int i = 0; i < 10; i++) {
+    bool bit_value = !(2*(i/2) == i);
+    if (bit_array1.GetBit(i) != bit_value) {
+      passed = false;
+      cerr << "ERROR in testing bits after SetBit() was run on them!"
+	   << endl;
+    }
+  }
+
+  //bit_array1.Print(10);
+  bit_array1.SetBit(0, true);
+  bit_array1.SetBit(1, false);
+  bit_array1.SetBit(5, false);
+  bit_array1.SetBit(6, true);
+  bit_array1.SetBit(7, false);
+  //bit_array1.Print(10);
+  
+  for (int i = 0; i < 10; i++) {
+    bool bit_value = (3*(i/3) == i);
+    if (bit_array1.GetBit(i) != bit_value) {
+      passed = false;
+      cerr << "ERROR in testing bits after second round of SetBit() was run!"
+	   << endl;
+    }
+  }
+  
+  // Test constructor with initial size < 32.
+  cRawBitArray bit_array2(26);
+  for (int i = 0; i < 26; i++) {
+    if (bit_array2.GetBit(i) != false) {
+      passed = false;
+      cerr << "ERROR in testing bit that should be cleared by constructor()!"
+	   << endl;
+    }
+  }
+  bit_array2.SetBit(8, true);
+  bit_array2.Copy(bit_array1, 10);
+
+  for (int i = 0; i < 10; i++) {
+    bool bit_value = (3*(i/3) == i);
+    if (bit_array2.GetBit(i) != bit_value) {
+      passed = false;
+      cerr << "ERROR in testing bits after Copy()!"
+	   << endl;
+    }
+  }
+  
+  // Test constructor with initial size > 32.
+  const int high_bit_count = 1000;
+  cRawBitArray bit_array3(high_bit_count);
+  int bit_pos = 2;
+  while (bit_pos < high_bit_count) {
+    bit_array3.SetBit(bit_pos, true);
+    bit_pos = bit_pos * 3 / 2;
+  }
+
+  // Test faux copy constructor.
+  cRawBitArray bit_array4(bit_array3, high_bit_count);
+  bit_array4.SetBit(22, true);
+  bit_array4.SetBit(24, true);
+  int count1 =  bit_array3.CountBits(high_bit_count);
+  int count2 =  bit_array3.CountBits2(high_bit_count);
+  int count3 =  bit_array4.CountBits(high_bit_count);
+  int count4 =  bit_array4.CountBits2(high_bit_count);
+
+  if (count1 != count2 || count3 != count4) {
+    passed = false;
+    cerr << "ERROR: CountBits and CountBits2 don't agree!" << endl;
+  }
+
+  if (count1 != count3 - 2) {
+    passed = false;
+    cerr << "ERROR: Counts do not agree before and after copy!" << endl;
+  }
+
+  int diff_count = 0;
+  for (int i = 0; i < high_bit_count; i++) {
+    if (bit_array3.GetBit(i) != bit_array4.GetBit(i)) diff_count++;
+  }
+
+  if (diff_count != 2) {
+    passed = false;
+    cerr << "ERROR in cRawBitArray copy constructor." << endl;
+  }
+
+
+  // LOGICAL OPERATORS
+  
+  bit_array4.Resize(1000, 70);
+  int count5 = bit_array4.CountBits(70);
+  bit_array4.NOT(70);
+  int count6 = bit_array4.CountBits(70);
+  bit_array4.NOT(70);
+  
+  if (count5 + count6 != 70) {
+    passed = false;
+    cerr << "ERROR in NOT operation!" << endl;
+  }
+
+  cRawBitArray bit_array5(70);
+  int pos = 1;
+  int step = 1;
+  while (pos <= 70) {
+    bit_array5.SetBit(70 - pos, true);
+    pos += step++;
+  }
+
+  cRawBitArray bit_array6(70);
+  bit_array6.AND(bit_array4, bit_array5, 70);
+  int count_and = bit_array6.CountBits(70);
+  if (count_and != 3) {
+    passed = false;
+    cerr << "ERROR in AND operation!" << endl;
+  }
+
+  bit_array6.OR(bit_array4, bit_array5, 70);
+  int count_or = bit_array6.CountBits(70);
+  if (count_or != 21) {
+    passed = false;
+    cerr << "ERROR in OR operation!" << endl;
+  }
+
+  bit_array6.NAND(bit_array4, bit_array5, 70);
+  int count_nand = bit_array6.CountBits(70);
+  if (count_nand != 67) {
+    passed = false;
+    cerr << "ERROR in NAND operation!" << endl;
+  }
+
+  bit_array6.NOR(bit_array4, bit_array5, 70);
+  int count_nor = bit_array6.CountBits(70);
+  if (count_nor != 49) {
+    passed = false;
+    cerr << "ERROR in NOR operation!" << endl;
+  }
+
+  bit_array6.XOR(bit_array4, bit_array5, 70);
+  int count_xor = bit_array6.CountBits(70);
+  if (count_xor != 18) {
+    passed = false;
+    cerr << "ERROR in XOR operation!" << endl;
+  }
+
+  bit_array6.EQU(bit_array4, bit_array5, 70);
+  int count_equ = bit_array6.CountBits(70);
+  if (count_equ != 52) {
+    passed = false;
+    cerr << "ERROR in EQU operation!" << endl;
+  }
+
+//   bit_array4.Print(70);
+//   bit_array5.Print(70);
+//   bit_array6.Print(70);
+//   cout << bit_array6.CountBits(70) << endl;
+
+  cBitArray ba(74);
+  for (int i = 0; i < 74; i++) {  if (i % 5 == 3) ba[i] = true;  }
+
+  cBitArray ba2(74);
+  for (int i = 0; i < 74; i++)  {
+    if ((i%2==0 || i%3==0) && i%6 != 0) ba2[i] = true;
+  }
+
+  if ((ba & ba2).CountBits() != 8) {
+    passed = false;
+    cerr << "ERROR: operator& failed for cBitArray" << endl;
+  }
+  
+  if ((ba | ba2).CountBits() != 43) {
+    passed = false;
+    cerr << "ERROR: operator| failed for cBitArray" << endl;
+  }
+
+  if ((ba ^ ba2).CountBits() != 35) {
+    passed = false;
+    cerr << "ERROR: operator^ failed for cBitArray" << endl;
+  }
+  
+  if ((~ba).CountBits() != 59) {
+    passed = false;
+    cerr << "ERROR: operator~ failed for cBitArray" << endl;
+  }
+
+  if ((~ba & ~ba2).CountBits() != 31) {
+    passed = false;
+    cerr << "ERROR: Chained bitwise operators failed for cBitArray" << endl;
+  }
+  
+  cout << ba << "  " << ba.CountBits() << endl;
+  cout << ba2 << "  " << ba2.CountBits() << endl;
+  cout << (~ba & ~ba2) << "  " << (~ba & ~ba2).CountBits() << endl;
+
+  if (passed == true) {
+    cout << "cRawBitArray passed Unit Tests." << endl;
+  }
+}
+
+#endif

Added: development/source/tools/cBitArray.h
===================================================================
--- development/source/tools/cBitArray.h	                        (rev 0)
+++ development/source/tools/cBitArray.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,410 @@
+#ifndef BIT_ARRAY_H
+#define BIT_ARRAY_H
+
+#include <assert.h>
+
+#include <iostream>
+
+#include "tArray.h"
+
+using namespace std;
+
+// Class: cBitArray and cBitMatrix
+// Desc: These classes handle an arbitrarily large array or matrix of bits,
+//       and optimizes the operations on those bits to be as fast as possible.
+//
+
+// Constructors:
+//  cBitArray()                            -- Assume a size zero array.
+//  cBitArray(int in_size)                 -- Create an uninitialized array.
+//  cBitArray(const cBitArray & in_array)  -- Copy Constructor
+
+// Assignment and equality test:
+//  cBitArray & operator=(const cBitArray & in_array)
+//  bool operator==(const cBitArray & in_array) const
+
+// Sizing:
+//  int GetSize() const
+//  void Resize(const int new_size)
+//  void ResizeClear(const int new_size)
+
+// Accessors:
+//  void Set(int index, bool value)
+//  bool Get(int index) const
+//  bool operator[](int index) const
+//  cBitProxy operator[](int index)
+//  void Clear()
+//  void SetAll()
+
+// Printing:
+//  void Print(ostream & out=cout) const
+//  void PrintOneIDs(ostream & out=cout) const
+
+// Bit play:
+//  int CountBits()   -- Count 1s -- fast for sparse arrays.
+//  int CountBits2()  -- Count 1s -- fast for arbitary arrays.
+//  int FindBit1(int start_bit)   -- Return pos of first 1 after start_bit 
+
+// Boolean math functions:
+//  cBitArray NOT() const
+//  cBitArray AND(const cBitArray & array2) const
+//  cBitArray OR(const cBitArray & array2) const
+//  cBitArray NAND(const cBitArray & array2) const
+//  cBitArray NOR(const cBitArray & array2) const
+//  cBitArray XOR(const cBitArray & array2) const
+//  cBitArray EQU(const cBitArray & array2) const
+
+//  const cBitArray & NOTSELF()
+//  const cBitArray & ANDSELF(const cBitArray & array2)
+//  const cBitArray & ORSELF(const cBitArray & array2)
+//  const cBitArray & NANDSELF(const cBitArray & array2)
+//  const cBitArray & NORSELF(const cBitArray & array2)
+//  const cBitArray & XORSELF(const cBitArray & array2)
+//  const cBitArray & EQUSELF(const cBitArray & array2)
+
+// Operator overloads:
+//  cBitArray operator~() const
+//  cBitArray operator&(const cBitArray & ar2) const
+//  cBitArray operator|(const cBitArray & ar2) const
+//  cBitArray operator^(const cBitArray & ar2) const
+//  const cBitArray & operator&=(const cBitArray & ar2)
+//  const cBitArray & operator|=(const cBitArray & ar2)
+//  const cBitArray & operator^=(const cBitArray & ar2)
+
+
+
+
+// The following is an internal class used by cBitArray (and will be used in
+// cBitMatrix eventually....).  It does not keep track of size, so this value
+// must be passed in.
+
+class cRawBitArray {
+private:
+  int * bit_fields;
+  
+  // Disallow default copy constructor and operator=
+  // (we need to know the number of bits we're working with!)
+  cRawBitArray(const cRawBitArray & ) { assert(false); }
+  const cRawBitArray & operator=(const cRawBitArray & in_array)
+    { assert(false); return *this; }
+
+  inline int GetNumFields(const int num_bits) const
+    { return 1 + ((num_bits-1) >> 5); }
+  inline int GetField(const int index) const { return index >> 5; }
+  inline int GetFieldPos(const int index) const { return index & 31; }
+public:
+  cRawBitArray() : bit_fields(NULL) { ; }
+  ~cRawBitArray() {
+    if (bit_fields != NULL) {
+      delete [] bit_fields;
+    }
+  }
+
+  void Zero(const int num_bits) {
+    const int num_fields = GetNumFields(num_bits);
+    for (int i = 0; i < num_fields; i++) {
+      bit_fields[i] = 0;
+    }    
+  }
+
+  void Ones(const int num_bits) {
+    const int num_fields = GetNumFields(num_bits);
+    for (int i = 0; i < num_fields; i++) {
+      bit_fields[i] = -1;
+    }    
+    const int last_bit = GetFieldPos(num_bits);
+    if (last_bit > 0) {
+      bit_fields[num_fields - 1] &= (1 << last_bit) - 1;
+    }
+  }
+
+  cRawBitArray(const int num_bits) {
+    const int num_fields = GetNumFields(num_bits);
+    bit_fields = new int[ num_fields ];
+    Zero(num_bits);
+  }
+
+  // The Copy() method and the Copy Constructor must both be told how many
+  // bits they are working with.
+  void Copy(const cRawBitArray & in_array, const int num_bits);
+  cRawBitArray(const cRawBitArray & in_array, const int num_bits)
+    : bit_fields(NULL)
+  {
+    Copy(in_array, num_bits);
+  }
+
+  // For fast bit operations, we're not going to setup operator[]; instead
+  // we're going to have a GetBit and a SetBit commamd.  For this raw version
+  // we're also going to assume that the index is within range w/o any special
+  // checks.
+  bool GetBit(const int index) const{
+    const int field_id = GetField(index);
+    const int pos_id = GetFieldPos(index);
+    return (bit_fields[field_id] & (1 << pos_id)) != 0;
+  }
+
+  void SetBit(const int index, const bool value) {
+    const int field_id = GetField(index);
+    const int pos_id = GetFieldPos(index);
+    const int pos_mask = 1 << pos_id;
+
+    if (value == false) {
+      bit_fields[field_id] &= ~pos_mask;
+    } else {
+      bit_fields[field_id] |= pos_mask;
+    }
+  }
+
+  bool IsEqual(const cRawBitArray & in_array, int num_bits) const;
+
+  void Resize(const int old_bits, const int new_bits);
+  void ResizeSloppy(const int new_bits);
+  void ResizeClear(const int new_bits);
+
+  // Two different technique of bit counting...
+  int CountBits(const int num_bits) const; // Better for sparse arrays
+  int CountBits2(const int num_bits) const; // Better for dense arrays
+
+  // Other bit-play
+  int FindBit1(const int num_bits, const int start_pos) const;
+  tArray<int> GetOnes(const int num_bits) const;
+
+  void Print(const int num_bits, ostream & out=cout) const {
+    for (int i = 0; i < num_bits; i++) {
+      out << GetBit(i);
+    }
+  }
+
+  void PrintOneIDs(const int num_bits, ostream & out=cout) const {
+    for (int i = 0; i < num_bits; i++) {
+      if (GetBit(i) == true) {
+	out << i << " ";
+      }
+    }
+  }
+
+  // Fast bool operators where we uses this bit array as one of the 
+  // inputs and the place to store the results.
+  void NOT(const int num_bits);
+  void AND(const cRawBitArray & array2, const int num_bits);
+  void OR(const cRawBitArray & array2, const int num_bits);
+  void NAND(const cRawBitArray & array2, const int num_bits);
+  void NOR(const cRawBitArray & array2, const int num_bits);
+  void XOR(const cRawBitArray & array2, const int num_bits);
+  void EQU(const cRawBitArray & array2, const int num_bits);
+
+  // Fast bool operators where we load all of the inputs and store the
+  // results here.
+  void NOT(const cRawBitArray & array1, const int num_bits);
+  void AND(const cRawBitArray & array1, const cRawBitArray & array2,
+	   const int num_bits);
+  void OR(const cRawBitArray & array1, const cRawBitArray & array2,
+	  const int num_bits);
+  void NAND(const cRawBitArray & array1, const cRawBitArray & array2,
+	    const int num_bits);
+  void NOR(const cRawBitArray & array1, const cRawBitArray & array2,
+	   const int num_bits);
+  void XOR(const cRawBitArray & array1, const cRawBitArray & array2,
+	   const int num_bits);
+  void EQU(const cRawBitArray & array1, const cRawBitArray & array2,
+	   const int num_bits);
+};
+
+class cBitArray {
+private:
+  cRawBitArray bit_array;
+  int array_size;
+
+  // Setup a bit proxy so that we can use operator[] on bit arrays as a lvalue.
+  class cBitProxy {
+  private:
+    cBitArray & array;
+    int index;
+  public:
+    cBitProxy(cBitArray & _array, int _idx) : array(_array), index(_idx) {;}
+
+    inline cBitProxy & operator=(bool b);    // lvalue handling...
+    inline operator bool() const;            // rvalue handling...
+  };
+  friend class cBitProxy;
+public:
+  cBitArray() : array_size(0) { ; }
+  cBitArray(int in_size) : bit_array(in_size), array_size(in_size) { ; }
+  cBitArray(const cBitArray & in_array)
+    : bit_array(in_array.bit_array, in_array.array_size)
+    , array_size(in_array.array_size) { ; }
+  cBitArray(const cRawBitArray & in_array, int in_size)
+    : bit_array(in_array, in_size)
+    , array_size(in_size) { ; }
+
+  cBitArray & operator=(const cBitArray & in_array) {
+    bit_array.Copy(in_array.bit_array, in_array.array_size);
+    array_size = in_array.array_size;
+    return *this;
+  }
+
+  bool operator==(const cBitArray & in_array) const {
+    if (array_size != in_array.array_size) return false;
+    return bit_array.IsEqual(in_array.bit_array, array_size);
+  }
+
+  int GetSize() const { return array_size; }
+
+  void Set(int index, bool value) {
+    assert(index < array_size);
+    bit_array.SetBit(index, value);
+  }
+
+  bool Get(int index) const {
+    assert(index < array_size);
+    return bit_array.GetBit(index);
+  }
+
+  bool operator[](int index) const { return Get(index); }
+  cBitProxy operator[](int index) { return cBitProxy(*this, index); }
+
+  void Clear() { bit_array.Zero(array_size); }
+  void SetAll() { bit_array.Ones(array_size); }
+  
+
+  void Print(ostream & out=cout) const { bit_array.Print(array_size, out); }
+  void PrintOneIDs(ostream & out=cout) const
+    { bit_array.PrintOneIDs(array_size, out); }
+  void Resize(const int new_size) {
+    bit_array.Resize(array_size, new_size);
+    array_size = new_size;
+  }
+  void ResizeClear(const int new_size) {
+    bit_array.ResizeClear(new_size);
+    array_size = new_size;
+  }
+  int CountBits() const { return bit_array.CountBits(array_size); }
+  int CountBits2() const { return bit_array.CountBits2(array_size); }
+
+  int FindBit1(int start_bit=0) const
+    { return bit_array.FindBit1(array_size, start_bit); }
+  tArray<int> GetOnes() const { return bit_array.GetOnes(array_size); }
+
+  // Boolean math functions...
+  cBitArray NOT() const {
+    cBitArray out_array;
+    out_array.bit_array.NOT(bit_array, array_size);
+    out_array.array_size = array_size;
+    return out_array;
+  }
+
+  cBitArray AND(const cBitArray & array2) const {
+    assert(array_size == array2.array_size);
+    cBitArray out_array;
+    out_array.bit_array.AND(bit_array, array2.bit_array, array_size);
+    out_array.array_size = array_size;
+    return out_array;
+  }
+
+  cBitArray OR(const cBitArray & array2) const {
+    assert(array_size == array2.array_size);
+    cBitArray out_array;
+    out_array.bit_array.OR(bit_array, array2.bit_array, array_size);
+    out_array.array_size = array_size;
+    return out_array;
+  }
+
+  cBitArray NAND(const cBitArray & array2) const {
+    assert(array_size == array2.array_size);
+    cBitArray out_array;
+    out_array.bit_array.NAND(bit_array, array2.bit_array, array_size);
+    out_array.array_size = array_size;
+    return out_array;
+  }
+
+  cBitArray NOR(const cBitArray & array2) const {
+    assert(array_size == array2.array_size);
+    cBitArray out_array;
+    out_array.bit_array.NOR(bit_array, array2.bit_array, array_size);
+    out_array.array_size = array_size;
+    return out_array;
+  }
+
+  cBitArray XOR(const cBitArray & array2) const {
+    assert(array_size == array2.array_size);
+    cBitArray out_array;
+    out_array.bit_array.XOR(bit_array, array2.bit_array, array_size);
+    out_array.array_size = array_size;
+    return out_array;
+  }
+
+  cBitArray EQU(const cBitArray & array2) const {
+    assert(array_size == array2.array_size);
+    cBitArray out_array;
+    out_array.bit_array.EQU(bit_array, array2.bit_array, array_size);
+    out_array.array_size = array_size;
+    return out_array;
+  }
+
+  const cBitArray & NOTSELF() {
+    bit_array.NOT(array_size);
+    return *this;
+  }
+
+  const cBitArray & ANDSELF(const cBitArray & array2) {
+    assert(array_size == array2.array_size);
+    bit_array.AND(array2.bit_array, array_size);
+    return *this;
+  }
+
+  const cBitArray & ORSELF(const cBitArray & array2) {
+    assert(array_size == array2.array_size);
+    bit_array.OR(array2.bit_array, array_size);
+    return *this;
+  }
+
+  const cBitArray & NANDSELF(const cBitArray & array2) {
+    assert(array_size == array2.array_size);
+    bit_array.NAND(array2.bit_array, array_size);
+    return *this;
+  }
+
+  const cBitArray & NORSELF(const cBitArray & array2) {
+    assert(array_size == array2.array_size);
+    bit_array.NOR(array2.bit_array, array_size);
+    return *this;
+  }
+
+  const cBitArray & XORSELF(const cBitArray & array2) {
+    assert(array_size == array2.array_size);
+    bit_array.XOR(array2.bit_array, array_size);
+    return *this;
+  }
+
+  const cBitArray & EQUSELF(const cBitArray & array2) {
+    assert(array_size == array2.array_size);
+    bit_array.EQU(array2.bit_array, array_size);
+    return *this;
+  }
+
+  // Operator overloads...
+  cBitArray operator~() const { return NOT(); }
+  cBitArray operator&(const cBitArray & ar2) const { return AND(ar2); }
+  cBitArray operator|(const cBitArray & ar2) const { return OR(ar2); }
+  cBitArray operator^(const cBitArray & ar2) const { return XOR(ar2); }
+  const cBitArray & operator&=(const cBitArray & ar2) { return ANDSELF(ar2); }
+  const cBitArray & operator|=(const cBitArray & ar2) { return ORSELF(ar2); }
+  const cBitArray & operator^=(const cBitArray & ar2) { return XORSELF(ar2); }
+
+};
+
+std::ostream & operator << (std::ostream & out, const cBitArray & bit_array);
+
+cBitArray::cBitProxy & cBitArray::cBitProxy::operator=(bool b)
+{
+  array.Set(index, b);
+  return *this;
+}
+
+
+cBitArray::cBitProxy::operator bool() const
+{
+  return array.Get(index);
+}
+
+#endif

Modified: development/source/viewer-core/cCoreView_Info.cc
===================================================================
--- development/source/viewer-core/cCoreView_Info.cc	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/viewer-core/cCoreView_Info.cc	2007-08-20 17:27:17 UTC (rev 1964)
@@ -1,9 +1,42 @@
+/*
+ *  cCoreView_Info.cc
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
 #include "cCoreView_Info.h"
 
-cCoreView_Info::cCoreView_Info(cPopulation & in_pop, int in_total_colors)
-  : m_population(in_pop)
-  , m_total_colors(in_total_colors)
-  , m_threshold_colors(in_total_colors * 5 / 6)
+#include "cBitArray.h"
+#include "cClassificationManager.h"
+#include "cGenotype.h"
+#include "cPopulation.h"
+#include "cWorld.h"
+
+cCoreView_Info::cCoreView_Info(cWorld * in_world, int total_colors)
+  : m_world(in_world)
+  , m_population(in_world->GetPopulation())
+  , m_color_chart_id(total_colors, -1)
+  , m_color_chart_ptr(total_colors, NULL)
+  , m_threshold_colors(total_colors * 5 / 6)
+  , m_next_color(0)
   , m_pause_level(PAUSE_OFF)
   , m_step_organism_id(-1)
   , m_step_organism_thread(-1)
@@ -36,6 +69,57 @@
 /////////////////////////
 //  Other functions...
 
+void cCoreView_Info::SetupUpdate()
+{
+  const int num_colors = m_color_chart_id.GetSize();
+  const int num_genotypes = m_world->GetClassificationManager().GetGenotypeCount();
+  cBitArray free_color(num_colors);   // Keep track of genotypes still using their color.
+  free_color.SetAll();
+
+  // Loop through all genotypes that should be colors to mark those that we can clear out.
+  cGenotype * genotype = m_world->GetClassificationManager().GetBestGenotype();
+  int count = 0;
+  while (count < num_genotypes && count < num_colors) {
+    assert(genotype != NULL);
+    const int cur_color = genotype->GetMapColor();
+    const int cur_id = genotype->GetID();
+    if (cur_color >= 0) {
+      assert(m_color_chart_id[cur_color] == cur_id);     // If it has a color, the color should point back to it.
+      assert(m_color_chart_ptr[cur_color] == genotype);  // ...and so should the pointer.
+      free_color[cur_color] = false;
+    }
+    genotype = genotype->GetNext();
+    count++;
+  }
+
+  // Clear out colors for genotypes below threshold.
+  for (int i = count; i < num_genotypes; i++) {
+    if (genotype->GetMapColor() >= 0) genotype->SetMapColor(-1);
+    genotype = genotype->GetNext();
+  }
+
+  // Setup genotypes above threshold.
+  genotype = m_world->GetClassificationManager().GetBestGenotype();
+  count = 0;
+  while (count < num_genotypes && count < m_threshold_colors) {
+    assert(genotype != NULL);
+    if (genotype->GetMapColor() < 0) {
+      // We start with m_next_color (so we don't keep using the same set), but loop around if we need to.
+      int new_color = free_color.FindBit1(m_next_color);
+      if (new_color == -1) new_color = free_color.FindBit1(0);
+      assert(new_color != -1);
+      m_next_color = new_color + 1;
+      m_color_chart_id[new_color] = genotype->GetID();
+      m_color_chart_ptr[new_color] = genotype;
+      free_color[new_color] = false;
+      genotype->SetMapColor(new_color);
+    }
+    genotype = genotype->GetNext();
+    count++;
+  }
+}
+
+
 void cCoreView_Info::EnterStepMode(int org_id)
 {
   SetPauseLevel(PAUSE_ADVANCE_INST);

Modified: development/source/viewer-core/cCoreView_Info.h
===================================================================
--- development/source/viewer-core/cCoreView_Info.h	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/viewer-core/cCoreView_Info.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -1,3 +1,29 @@
+/*
+ *  cCoreView_Info.h
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+// This is a class to manage information that will be needed throughout the interface.
+
 #ifndef cCoreView_Info_h
 #define cCoreView_Info_h
 
@@ -4,20 +30,43 @@
 // The cCoreView_Info object is responsible for holding on to all of the general information about the state of
 // a population in the view.  It does not process any of this information, but allows it to be easily shared by
 // all of the sections of the viewer.
+//
+// We're assuming that each color has an ID.  The first four are set:
+//  -4 = Black
+//  -3 = Dark Gray
+//  -2 = Lt. Gray
+//  -1 = White
+//  0+ = All other available colors roughly in a smooth order for displaying fitness, etc.
+//
+// When coloring genotypes, we want only the top genotypes to be given a distinct color, but we want that
+// color to go away if the genotype's abundance drops to low.  Each position in the color_chart will have
+// a genotype ID associated with it, or -1 if that color is unused.  Each time the map is updated, all colors
+// are compared to the top of the genotype list.  Each genotype tracks the ID of its color, so it is easy to
+// index into the color chart to find its entry.
+//
+// For color scales, we should have a large scale and only use a piece of it at a time, rotating around.  This
+// will prevent an organism from having its color change during its lifetime (potentially confusing the user).
+// If we end up wraping around and using a color again before the old one is gone, instead of directly reusing it
+// or taking other desparate measures, we should just make the color less vibrant, and eventually become gray.
+// In the case of fitness, black is dead and gray is a fitness seriously below the dominant.
 
 #include <iostream>
 #include <sstream>
 #include <fstream>
 
 #include "cStringList.h"
+#include "tArray.h"
 #include "tList.h"
 
+class cGenotype;
 class cPopulation;
+class cWorld;
 
 using namespace std;
 
 class cCoreView_Info {
 protected:
+  cWorld * m_world;
   cPopulation & m_population;
 
   // Setup streams to capture stdin and stdout so we can control them as needed.
@@ -29,8 +78,10 @@
   cStringList m_cerr_list;
 
   // Constant Inforation setup by specific viewer.
-  const int m_total_colors;
-  const int m_threshold_colors;
+  tArray<int> m_color_chart_id;
+  tArray<cGenotype *> m_color_chart_ptr;
+  int m_threshold_colors;
+  int m_next_color;
 
   // Variable information, changing modes based on user input.
   int m_pause_level;
@@ -47,12 +98,15 @@
   enum ePause { PAUSE_ON, PAUSE_OFF, PAUSE_ADVANCE_INST, PAUSE_ADVANCE_UPDATE, PAUSE_ADVANCE_DIVIDE };
 
 public:
-  cCoreView_Info(cPopulation & in_pop, int in_total_colors);
+  cCoreView_Info(cWorld * in_world, int total_colors);
   ~cCoreView_Info();
 
   cPopulation & GetPopulation() { return m_population; }
   const cPopulation & GetPopulation() const { return m_population; }
 
+  // Generic Functions...
+  void SetupUpdate();
+
   // Accessors for variable information
   int GetPauseLevel() const { return m_pause_level; }
   int GetStepOrganism() const { return m_step_organism_id; }

Added: development/source/viewer-core/cCoreView_Map.cc
===================================================================
--- development/source/viewer-core/cCoreView_Map.cc	                        (rev 0)
+++ development/source/viewer-core/cCoreView_Map.cc	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,212 @@
+/*
+ *  cCoreView_Map.cc
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include "cCoreView_Map.h"
+
+#include "cCoreView_Info.h"
+#include "cEnvironment.h"
+#include "cGenotype.h"
+#include "cOrganism.h"
+#include "cPopulation.h"
+#include "cPopulationCell.h"
+
+cCoreView_Map::cCoreView_Map(cCoreView_Info & info)
+  : m_info(info)
+  , m_color_mode(0)
+  , m_symbol_mode(-1)
+  , m_tag_mode(-1)
+  , scale_max(80)
+{
+  // Setup the available view modes...
+  AddViewMode("Genotypes",      &cCoreView_Map::SetColors_Genotype, VIEW_COLOR, COLORS_TYPES);
+  AddViewMode("Fitness",        &cCoreView_Map::SetColors_Fitness,  VIEW_COLOR, COLORS_SCALE);
+  AddViewMode("_Genome Length", &cCoreView_Map::SetColors_Length,   VIEW_COLOR, COLORS_SCALE);
+  AddViewMode("Highlight Tags", &cCoreView_Map::SetColors_Tags,     VIEW_COLOR, COLORS_TYPES);
+
+  AddViewMode("None",           &cCoreView_Map::TagCells_None,      VIEW_TAGS);
+  AddViewMode("Parasite",       &cCoreView_Map::TagCells_Parasite,  VIEW_TAGS);
+
+  AddViewMode("Square",         &cCoreView_Map::SetSymbol_Square,   VIEW_SYMBOLS);
+  AddViewMode("Facing",         &cCoreView_Map::SetSymbol_Facing,   VIEW_SYMBOLS);
+
+  // Load tasks...
+  const cEnvironment & environment = m_info.GetPopulation().GetEnvironment();
+  const int num_tasks = environment.GetNumTasks();
+  for (int i = 0; i < num_tasks; i++) {
+    cString mode_name = environment.GetTask(i).GetDesc();
+    mode_name.Insert("Task/");
+    AddViewMode(mode_name, &cCoreView_Map::TagCells_Task,  VIEW_TAGS, i);
+  }
+}
+
+cCoreView_Map::~cCoreView_Map()
+{
+  for (int i = 0; i < m_view_modes.GetSize(); i++) {
+    delete m_view_modes[i];
+  }
+}
+
+void cCoreView_Map::UpdateMaps()
+{
+  if (m_color_mode >= 0) {
+    assert(m_view_modes[m_color_mode]->GetViewType() == VIEW_COLOR);
+    UpdateMap(m_color_mode);
+  }
+
+  if (m_symbol_mode >= 0) {
+    assert(m_view_modes[m_symbol_mode]->GetViewType() == VIEW_SYMBOLS);
+    UpdateMap(m_symbol_mode);
+  }
+
+  if (m_tag_mode >= 0) {
+    assert(m_view_modes[m_tag_mode]->GetViewType() == VIEW_TAGS);
+    UpdateMap(m_tag_mode);
+  }
+}
+
+
+void cCoreView_Map::SetMode(int mode)
+{
+  int type = m_view_modes[mode]->GetViewType();
+  if (type == VIEW_COLOR) m_color_mode = mode;
+  else if (type == VIEW_SYMBOLS) m_symbol_mode = mode;
+  else if (type == VIEW_TAGS) m_tag_mode = mode;
+  else assert(false);
+}
+
+
+////////////////////////
+// Protected methods
+
+void cCoreView_Map::SetColors_Genotype(int ignore)
+{
+  (void) ignore;
+  cPopulation & pop = m_info.GetPopulation();
+  m_color_grid.Resize(pop.GetSize());
+  for (int i = 0; i < pop.GetSize(); i++) {
+    cOrganism * org = pop.GetCell(i).GetOrganism();
+    if (org == NULL) m_color_grid[i] = -4;
+    else m_color_grid[i] = org->GetGenotype()->GetMapColor();
+  }
+}
+
+void cCoreView_Map::SetColors_Fitness(int ignore)
+{
+  (void) ignore;
+  cPopulation & pop = m_info.GetPopulation();
+  m_color_grid.Resize(pop.GetSize());
+
+  // Determine the max and min in the population.
+  double max_fit = 3;
+  double min_fit = -2;
+
+  for (int i = 0; i < pop.GetSize(); i++) {
+    cOrganism * org = pop.GetCell(i).GetOrganism();
+    if (org == NULL) continue;
+    double fit = org->GetPhenotype().GetFitness();
+    if (fit == 0.0) continue;
+    fit = log(fit);
+    // if (fit < min_fit) min_fit = fit;
+    if (fit > max_fit) max_fit = fit;
+  }
+  double fit_diff = max_fit - min_fit;
+  if (fit_diff == 0.0) fit_diff = 1.0;
+
+  // Now fill out the color grid.
+  for (int i = 0; i < pop.GetSize(); i++) {
+    cOrganism * org = pop.GetCell(i).GetOrganism();
+    if (org == NULL) {
+      m_color_grid[i] = -1;
+      continue;
+    }
+    double fit = org->GetPhenotype().GetFitness();
+    if (fit == 0.0) {
+      m_color_grid[i] = 0;
+    }
+    fit = log(fit);
+    m_color_grid[i] = 1 + (int) ((scale_max - 2) * ((fit - min_fit) / fit_diff));
+  }
+}
+
+void cCoreView_Map::SetColors_Length(int ignore)
+{
+  (void) ignore;
+}
+
+void cCoreView_Map::SetColors_Tags(int ignore)
+{
+  (void) ignore;
+}
+
+void cCoreView_Map::TagCells_None(int ignore)
+{
+  cPopulation & pop = m_info.GetPopulation();
+  m_tag_grid.Resize(pop.GetSize());
+  m_tag_grid.SetAll(0);
+}
+
+void cCoreView_Map::TagCells_Parasite(int ignore)
+{
+  (void) ignore;
+}
+
+void cCoreView_Map::TagCells_Task(int task_id)
+{
+  cPopulation & pop = m_info.GetPopulation();
+  m_tag_grid.Resize(pop.GetSize());
+  for (int i = 0; i < pop.GetSize(); i++) {
+    cOrganism * org = pop.GetCell(i).GetOrganism();
+    if (org == NULL) m_tag_grid[i] = 0;
+    else if (org->GetPhenotype().GetCurTaskCount()[task_id] > 0) m_tag_grid[i] = 1;
+    else if (org->GetPhenotype().GetLastTaskCount()[task_id] > 0) m_tag_grid[i] = 2;
+    else m_tag_grid[i] = 0;
+  }
+}
+
+void cCoreView_Map::SetSymbol_Square(int ignore)
+{
+  (void) ignore;
+}
+
+void cCoreView_Map::SetSymbol_Facing(int ignore)
+{
+  (void) ignore;
+}
+
+
+int cCoreView_Map::AddViewMode(const cString & name, yMethod call, eViewType type, int arg)
+{
+  if (m_symbol_mode == -1 && type == VIEW_SYMBOLS) m_symbol_mode = m_view_modes.GetSize();
+  if (m_tag_mode == -1 && type == VIEW_TAGS) m_tag_mode = m_view_modes.GetSize();
+  
+  m_view_modes.Push( new cMapViewEntry(name, call, type, arg) );
+  return m_view_modes.GetSize();
+}
+
+void cCoreView_Map::UpdateMap(int map_id)
+{
+  yMethod call = m_view_modes[map_id]->GetCall();
+  int arg = m_view_modes[map_id]->GetArg();
+  (this->*call)(arg);
+}

Added: development/source/viewer-core/cCoreView_Map.h
===================================================================
--- development/source/viewer-core/cCoreView_Map.h	                        (rev 0)
+++ development/source/viewer-core/cCoreView_Map.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,115 @@
+/*
+ *  cCoreView_Map.h
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+// This class helps manage the map object in the user inteface.
+
+#ifndef cCoreView_Map_h
+#define cCoreView_Map_h
+
+#ifndef cString_h
+#include "cString.h"
+#endif
+
+#ifndef tArray_h
+#include "tArray.h"
+#endif
+
+class cCoreView_Info;
+class cPopulationCell;
+
+class cCoreView_Map {
+public:
+  typedef void (cCoreView_Map::*yMethod)(int arg);
+  enum eViewType { VIEW_COLOR, VIEW_SYMBOLS, VIEW_TAGS };
+  enum eColorType { COLORS_TYPES, COLORS_SCALE };
+
+protected:
+  class cMapViewEntry {
+  private:
+    const cString m_name;
+    const yMethod m_call;
+    const eViewType m_type;
+    const int m_arg;
+  public:
+    cMapViewEntry(const cString & name, yMethod call, eViewType type, int arg=0)
+      : m_name(name), m_call(call), m_type(type), m_arg(arg) { ; }
+    ~cMapViewEntry() { ; }
+    const cString & GetName() const { return m_name; }
+    yMethod GetCall() const { return m_call; }
+    int GetViewType() const { return (int) m_type; }
+    int GetArg() const { return m_arg; }
+  };
+
+  cCoreView_Info & m_info;
+
+  tArray<cMapViewEntry *> m_view_modes;  // List of view modes...
+  int m_color_mode;      // Current map color mode (index into m_view_modes, -1 = off)
+  int m_symbol_mode;     // Current map symbol mode (index into m_view_modes, -1 = off)
+  int m_tag_mode;        // Current map tag mode (index into m_view_modes, -1 = off)
+
+  tArray<int> m_color_grid;     // This maintains the colors in the current grid.
+  tArray<int> m_symbol_grid;    // Should we have special symbols at each cell?
+  tArray<int> m_tag_grid;         // Track tagged cells.
+
+  int scale_max;
+
+  void SetColors_Genotype(int ignore);
+  void SetColors_Fitness(int ignore);
+  void SetColors_Length(int ignore);
+  void SetColors_Tags(int ignore);
+  
+  void TagCells_None(int ignore);
+  void TagCells_Parasite(int ignore);
+  void TagCells_Task(int task_id);
+
+  void SetSymbol_Square(int ignore);
+  void SetSymbol_Facing(int ignore);
+
+  int AddViewMode(const cString & name, yMethod call, eViewType type, int arg=0);
+
+  void UpdateMap(int map_id);
+
+public:
+  cCoreView_Map(cCoreView_Info & info);
+  ~cCoreView_Map();
+
+  int GetColorMode() const { return m_color_mode; }
+  int GetSymbolMode() const { return m_symbol_mode; }
+  int GetTagMode() const { return m_tag_mode; }
+
+  const tArray<int> & GetColors() { return m_color_grid; }
+  const tArray<int> & GetSymbols() { return m_symbol_grid; }
+  const tArray<int> & GetTags() { return m_tag_grid; }
+
+  int GetNumModes() const { return m_view_modes.GetSize(); }
+  const cString & GetModeName(int id) const { return m_view_modes[id]->GetName(); }
+  int GetModeType(int id) const { return m_view_modes[id]->GetViewType(); }
+  int GetModeArg(int id) const { return m_view_modes[id]->GetArg(); }
+
+  void UpdateMaps();
+
+  void SetMode(int mode);
+};
+
+#endif

Added: development/source/viewer-coreGUI/cColor.cc
===================================================================
--- development/source/viewer-coreGUI/cColor.cc	                        (rev 0)
+++ development/source/viewer-coreGUI/cColor.cc	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,168 @@
+/*
+ *  cColor.cc
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+#include "cColor.h"
+
+#define HEX_COLOR(RED,GREEN,BLUE) (0x ## RED, 0x ## GREEN, 0x ## BLUE)
+
+const cColor cColor::BLACK   HEX_COLOR(00, 00, 00);
+const cColor cColor::WHITE   HEX_COLOR(FF, FF, FF);
+const cColor cColor::RED     HEX_COLOR(FF, 00, 00);
+const cColor cColor::GREEN   HEX_COLOR(00, FF, 00);
+const cColor cColor::BLUE    HEX_COLOR(00, 00, FF);
+const cColor cColor::YELLOW  HEX_COLOR(FF, FF, 00);
+const cColor cColor::CYAN    HEX_COLOR(00, FF, FF);
+const cColor cColor::MAGENTA HEX_COLOR(FF, 00, FF);
+
+const cColor cColor::GRAY       HEX_COLOR(A0, A0, A0);
+const cColor cColor::LT_RED     HEX_COLOR(FF, 50, 50);
+const cColor cColor::LT_GREEN   HEX_COLOR(50, FF, 50);
+const cColor cColor::LT_BLUE    HEX_COLOR(50, 50, FF);
+const cColor cColor::LT_YELLOW  HEX_COLOR(FF, FF, 50);
+const cColor cColor::LT_CYAN    HEX_COLOR(50, FF, FF);
+const cColor cColor::LT_MAGENTA HEX_COLOR(FF, 50, FF);
+
+const cColor cColor::DARK_GRAY    HEX_COLOR(50, 50, 50);
+const cColor cColor::DARK_RED     HEX_COLOR(A0, 00, 00);
+const cColor cColor::DARK_GREEN   HEX_COLOR(00, A0, 00);
+const cColor cColor::DARK_BLUE    HEX_COLOR(00, 00, A0);
+const cColor cColor::DARK_YELLOW  HEX_COLOR(A0, A0, 00);
+const cColor cColor::DARK_CYAN    HEX_COLOR(00, A0, A0);
+const cColor cColor::DARK_MAGENTA HEX_COLOR(A0, 00, A0);
+
+tArray<cColor> cColor::SET_BRIGHT(100);
+tArray<cColor> cColor::SET_DARK(100);
+
+void cColor::Setup()
+{
+  int index = 0;
+  //   SET_BRIGHT[index++].Set(0.5 , 0.0 , 0.0 );
+  //   SET_BRIGHT[index++].Set(0.55, 0.0 , 0.0 );
+
+  SET_BRIGHT[index++].Set(0.2 , 0.2 , 0.2 );
+
+  SET_BRIGHT[index++].Set(0.6 , 0.0 , 0.0 );
+  SET_BRIGHT[index++].Set(0.65, 0.0 , 0.0 );
+  SET_BRIGHT[index++].Set(0.7 , 0.0 , 0.0 );
+  SET_BRIGHT[index++].Set(0.75, 0.0 , 0.0 );
+  SET_BRIGHT[index++].Set(0.8 , 0.0 , 0.0 );
+  SET_BRIGHT[index++].Set(0.85, 0.0 , 0.0 );
+  SET_BRIGHT[index++].Set(0.9 , 0.0 , 0.0 );
+  SET_BRIGHT[index++].Set(0.95, 0.0 , 0.0 );
+
+  SET_BRIGHT[index++].Set(1.0 , 0.0 , 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.05, 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.1 , 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.15, 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.2 , 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.25, 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.3 , 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.35, 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.4 , 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.45, 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.5 , 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.55, 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.6 , 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.65, 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.7 , 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.75, 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.8 , 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.85, 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.9 , 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 0.95, 0.0 );
+
+  SET_BRIGHT[index++].Set(1.0 , 1.0 , 0.0 );
+  SET_BRIGHT[index++].Set(1.0 , 1.0 , 0.05);
+  SET_BRIGHT[index++].Set(0.95, 1.0 , 0.1 );
+  SET_BRIGHT[index++].Set(0.9 , 1.0 , 0.15);
+  SET_BRIGHT[index++].Set(0.85, 1.0 , 0.2 );
+  SET_BRIGHT[index++].Set(0.8 , 1.0 , 0.25);
+  SET_BRIGHT[index++].Set(0.75, 1.0 , 0.3 );
+  SET_BRIGHT[index++].Set(0.7 , 1.0 , 0.35);
+  SET_BRIGHT[index++].Set(0.65, 1.0 , 0.4 );
+  SET_BRIGHT[index++].Set(0.6 , 1.0 , 0.45);
+  SET_BRIGHT[index++].Set(0.55, 1.0 , 0.5 );
+  SET_BRIGHT[index++].Set(0.5 , 1.0 , 0.55);
+  SET_BRIGHT[index++].Set(0.45, 1.0 , 0.6 );
+  SET_BRIGHT[index++].Set(0.4 , 1.0 , 0.65);
+  SET_BRIGHT[index++].Set(0.35, 1.0 , 0.7 );
+  SET_BRIGHT[index++].Set(0.3 , 1.0 , 0.75);
+  SET_BRIGHT[index++].Set(0.25, 1.0 , 0.8 );
+  SET_BRIGHT[index++].Set(0.2 , 1.0 , 0.85);
+  SET_BRIGHT[index++].Set(0.15, 1.0 , 0.9 );
+  SET_BRIGHT[index++].Set(0.1 , 1.0 , 0.95);
+  SET_BRIGHT[index++].Set(0.05, 1.0 , 1.0 );
+
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 1.0 );
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.95);
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.9 );
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.85);
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.8 );
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.75);
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.7 );
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.65);
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.6 );
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.55);
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.5 );
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.45);
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.4 );
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.35);
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.3 );
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.25);
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.2 );
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.15);
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.1 );
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.05);
+
+  SET_BRIGHT[index++].Set(0.0 , 1.0 , 0.0 );
+  SET_BRIGHT[index++].Set(0.0 , 0.95, 0.0 );
+  SET_BRIGHT[index++].Set(0.0 , 0.9 , 0.0 );
+  SET_BRIGHT[index++].Set(0.0 , 0.85, 0.0 );
+  SET_BRIGHT[index++].Set(0.0 , 0.8 , 0.0 );
+  SET_BRIGHT[index++].Set(0.0 , 0.75, 0.0 );
+  SET_BRIGHT[index++].Set(0.0 , 0.7 , 0.0 );
+  SET_BRIGHT[index++].Set(0.0 , 0.65, 0.0 );
+  SET_BRIGHT[index++].Set(0.0 , 0.6 , 0.0 );
+  SET_BRIGHT[index++].Set(0.0 , 0.55, 0.0 );
+//  SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+//   SET_BRIGHT[index++].Set(0.0 , 0.5 , 0.0 );
+}

Added: development/source/viewer-coreGUI/cColor.h
===================================================================
--- development/source/viewer-coreGUI/cColor.h	                        (rev 0)
+++ development/source/viewer-coreGUI/cColor.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,84 @@
+/*
+ *  cColor.h
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+// This class manages colors in the graphical viewer.
+
+#ifndef cColor_h
+#define cColor_h
+
+#ifndef tArray_h
+#include "tArray.h"
+#endif
+
+class cColor {
+private:
+  int m_red;
+  int m_green;
+  int m_blue;
+
+public:
+  cColor(int r=0, int g=0, int b=0) : m_red(r), m_green(g), m_blue(b) { ; }
+  cColor(const cColor & _in) : m_red(_in.m_red), m_green(_in.m_green), m_blue(_in.m_blue) { ; }
+
+  cColor & operator=(const cColor & _in) { m_red=_in.m_red; m_green=_in.m_green; m_blue=_in.m_blue; }
+
+  void Set(int r, int g, int b) { m_red = r; m_green = g; m_blue = b; }
+  void Set(double r, double g, double b) { Set( (int) (255 * r), (int) (255 * g), (int) (255 * b) ); }
+  
+  int Red() const { return m_red; }
+  int Green() const { return m_green; }
+  int Blue() const { return m_blue; }
+
+  static const cColor BLACK;
+  static const cColor WHITE;
+  static const cColor RED;
+  static const cColor GREEN;
+  static const cColor BLUE;
+  static const cColor YELLOW;
+  static const cColor CYAN;
+  static const cColor MAGENTA;
+
+  static const cColor GRAY;
+  static const cColor LT_RED;
+  static const cColor LT_GREEN;
+  static const cColor LT_BLUE;
+  static const cColor LT_YELLOW;
+  static const cColor LT_CYAN;
+  static const cColor LT_MAGENTA;
+
+  static const cColor DARK_GRAY;
+  static const cColor DARK_RED;
+  static const cColor DARK_GREEN;
+  static const cColor DARK_BLUE;
+  static const cColor DARK_YELLOW;
+  static const cColor DARK_CYAN;
+  static const cColor DARK_MAGENTA;
+
+  static tArray<cColor> SET_BRIGHT;  
+  static tArray<cColor> SET_DARK;
+
+  static void Setup();
+};
+
+#endif

Added: development/source/viewer-coreGUI/cGUIBaseDraw.h
===================================================================
--- development/source/viewer-coreGUI/cGUIBaseDraw.h	                        (rev 0)
+++ development/source/viewer-coreGUI/cGUIBaseDraw.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,55 @@
+/*
+ *  cGUIBaseDraw.h
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+// This is a base class for GUI widgets that can be drawn on.
+
+#ifndef cGUIBaseDraw_h
+#define cGUIBaseDraw_h
+
+#include "cGUIWidget.h"
+
+class cColor;
+class cGUIContainer;
+class cString;
+
+class cGUIBaseDraw : public cGUIWidget {
+protected:
+public:
+  cGUIBaseDraw() { ; }
+  cGUIBaseDraw(cGUIContainer & parent, int x, int y, int width=0, int height=0, const cString & name="")
+    : cGUIWidget(parent, x, y, width, height, name) { ; }
+  virtual ~cGUIBaseDraw() { ; }
+
+  virtual void Draw() = 0;
+  virtual int Handle(int event) = 0;
+  virtual void Redraw() = 0;
+
+  virtual void DrawLine(int x1, int y1, int x2, int y2) = 0;
+  virtual void DrawBox(int x1, int y1, int _w, int _h, bool fill=false) = 0;
+  virtual void DrawCircle(int _x, int _y, int _r, bool fill=false) = 0;
+
+  virtual void SetColor(const cColor & color) = 0;
+};
+
+#endif

Added: development/source/viewer-coreGUI/cGUIMenu.h
===================================================================
--- development/source/viewer-coreGUI/cGUIMenu.h	                        (rev 0)
+++ development/source/viewer-coreGUI/cGUIMenu.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,50 @@
+/*
+ *  cGUIMenu.h
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+// A base clasee for menus in the GUI.
+
+#ifndef cGUIMenu_h
+#define cGUIMenu_h
+
+#include "cGUIWidget.h"
+
+class cGUIMenuItem;
+
+class cGUIMenu : public cGUIWidget {
+protected:
+
+public:
+  cGUIMenu(cGUIContainer & parent, int x, int y, int width, int height, const cString & name="")
+    : cGUIWidget(parent, x, y, width, height, name) { ; }
+
+  virtual ~cGUIMenu() { ; }
+  
+  virtual int GetSize() = 0;
+  virtual const cString & GetName(int id) const = 0;
+  virtual const cGUIMenuItem & GetOption(int id) const = 0;
+
+  virtual void Trigger(int id) = 0;
+};
+
+#endif

Added: development/source/viewer-coreGUI/cGUIMenuItem.h
===================================================================
--- development/source/viewer-coreGUI/cGUIMenuItem.h	                        (rev 0)
+++ development/source/viewer-coreGUI/cGUIMenuItem.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,44 @@
+/*
+ *  cGUIMenuItem.h
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+// A base clasee for single menu items in the GUI.
+
+#ifndef cGUIMenuItem_h
+#define cGUIMenuItem_h
+
+class cGUIMenuItem {
+protected:
+  cString m_name;
+
+public:
+  cGUIMenuItem(const cString & name="") : m_name(name) { ; }
+  virtual ~cGUIMenuItem() { ; }
+  
+  const cString & GetName() const { return m_name; }
+  void SetName(const cString & name) { m_name = name; }
+
+  virtual void Trigger() = 0;
+};
+
+#endif

Modified: development/source/viewer-coreGUI/cGUIWidget.h
===================================================================
--- development/source/viewer-coreGUI/cGUIWidget.h	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/viewer-coreGUI/cGUIWidget.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -61,11 +61,11 @@
   int GetY() const { return m_y; }
   int GetWidth() const { return m_width; }
   int GetHeight() const { return m_height; }
+  int GetFontSize() const { return m_font_size; }
   
   void SetName(const cString & _name) { m_name = _name; }
   void SetFontSize(int _size) { m_font_size = _size; }
-
-  virtual void Refresh() { ; }
+  void Resize(int new_w, int new_h) { m_width = new_w; m_height = new_h; }
 };
 
 #endif

Modified: development/source/viewer-coreGUI/tGUIButton.h
===================================================================
--- development/source/viewer-coreGUI/tGUIButton.h	2007-08-20 04:11:13 UTC (rev 1963)
+++ development/source/viewer-coreGUI/tGUIButton.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -22,7 +22,7 @@
  *
  */
 
-// This is a base class for all GUI widgets that act as buttons.
+// This is a second-level base class/template for all GUI widgets that act as buttons.
 
 #ifndef tGUIButton_h
 #define tGUIButton_h

Added: development/source/viewer-coreGUI/tGUIMenu.h
===================================================================
--- development/source/viewer-coreGUI/tGUIMenu.h	                        (rev 0)
+++ development/source/viewer-coreGUI/tGUIMenu.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,74 @@
+/*
+ *  tGUIMenu.h
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+// This is a base class/template for all GUI widgets that act as menus.
+
+#ifndef tGUIMenu_h
+#define tGUIMenu_h
+
+#include "cGUIMenu.h"
+#include "tArray.h"
+#include "tGUIMenuItem.h"
+
+template <class T, class ARG> class tGUIMenu : public cGUIMenu {
+protected:
+  tArray< tGUIMenuItem<T,ARG> * > m_menu_options;
+
+  virtual void SetupOption(int opt_id) = 0;
+
+public:
+  tGUIMenu(cGUIContainer & parent, int x, int y, int width, int height, const cString & name="")
+    : cGUIMenu(parent, x, y, width, height, name)
+  { ; }
+  virtual ~tGUIMenu() { 
+    for (int i = 0; i < m_menu_options.GetSize(); i++) delete m_menu_options[i];
+  }
+
+  int GetSize() { return m_menu_options.GetSize(); }
+  const cString & GetName(int id) const { return m_menu_options[id]->GetName(); }
+  T & GetTarget(int id) { return *(m_menu_options[id]->GetTarget()); }
+  ARG GetArg(int id) { return m_menu_options[id]->GetArg(); }
+  const cGUIMenuItem & GetOption(int id) const { return *(m_menu_options[id]); }
+
+  void AddOption(const cString & name, T * target, void (T::*cb_fun)(ARG), ARG arg=0) {
+    int new_id = m_menu_options.GetSize();
+    m_menu_options.Push( new tGUIMenuItem<T,ARG>(name, target, cb_fun, arg) );
+    SetupOption(new_id);
+  }
+
+  virtual void Trigger(int id) {
+    if (m_menu_options[id]->GetCallback() != NULL) {
+      ARG cur_arg = m_menu_options[id]->GetArg();
+      T & cur_target = m_menu_options[id]->GetTarget();
+      ( cur_target.*(m_menu_options[id]->GetCallback()) )( cur_arg );
+    }
+  }
+  virtual void Trigger(int id, ARG arg) {
+    if (m_menu_options[id]->GetCallback() != NULL) {
+      (m_menu_options[id]->GetTarget().*(m_menu_options[id]->GetCallback()))(arg);
+    }
+  }
+};
+
+#endif

Added: development/source/viewer-coreGUI/tGUIMenuItem.h
===================================================================
--- development/source/viewer-coreGUI/tGUIMenuItem.h	                        (rev 0)
+++ development/source/viewer-coreGUI/tGUIMenuItem.h	2007-08-20 17:27:17 UTC (rev 1964)
@@ -0,0 +1,61 @@
+/*
+ *  tGUIMenuItem.h
+ *  Avida
+ *
+ *  Created by Charles on 7-9-07
+ *  Copyright 1999-2007 Michigan State University. All rights reserved.
+ *
+ *
+ *  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; version 2
+ *  of the License.
+ *
+ *  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ */
+
+// A single item from a menu that should be able to handle what happens when it is chosen.
+
+#ifndef tGUIMenuItem_h
+#define tGUIMenuItem_h
+
+#include "cGUIMenuItem.h"
+
+template <class T, class ARG> class tGUIMenuItem : public cGUIMenuItem {
+public:
+  typedef void (T::*yCallback)(ARG);
+
+protected:
+  T * m_target;
+  yCallback m_callback;
+  ARG m_arg;
+
+public:
+  tGUIMenuItem() : m_target(NULL), m_callback(NULL), m_arg(-1.0) { ; }
+  tGUIMenuItem(const cString & name, T * target, void (T::*cb_fun)(ARG), ARG arg=0.0)
+    : cGUIMenuItem(name), m_target(target), m_callback(cb_fun), m_arg(arg) { ; }
+
+  T & GetTarget() { return *m_target; }
+  const T & GetTarget() const { return *m_target; }
+  yCallback GetCallback() const { return m_callback; }
+  ARG GetArg() const { return m_arg; }
+
+  void SetCallback(T * target, void (T::*cb_fun)(ARG), ARG arg=0.0) {
+    m_target = target;
+    m_callback = cb_fun;
+    m_arg = arg;
+  }
+
+  virtual void Trigger() { if (m_callback != NULL) (m_target->*(m_callback))(m_arg); }
+  virtual void Trigger(ARG arg) { if (m_callback != NULL) (m_target->*(m_callback))(arg); }
+};
+
+#endif




More information about the Avida-cvs mailing list