Index: /Swollen/include/swwreader.h
===================================================================
--- /Swollen/include/swwreader.h	(revision 110)
+++ /Swollen/include/swwreader.h	(revision 111)
@@ -71,5 +71,5 @@
     virtual osg::ref_ptr<osg::Vec2Array> getBedslopeTextureCoords();
 
-    virtual bool hasBedslopeTexture() {return (_bedslopetexture != NULL);}
+    virtual bool hasBedslopeTexture() {return (_state.bedslopetexturefilename != NULL);}
     virtual void setBedslopeTexture( std::string filename );
     virtual osg::Image* getBedslopeTexture();
@@ -87,22 +87,24 @@
     virtual unsigned int getNumberOfTimesteps() {return _ntimesteps;}
 
-    virtual float getAlphaMin() {return _alphamin;}
-    virtual float getAlphaMax() {return _alphamax;}
-    virtual float getHeightMin() {return _heightmin;}
-    virtual float getHeightMax() {return _heightmax;}
-    virtual float getCullAngle() {return _cullangle;}
+    virtual float getAlphaMin() {return _state.alphamin;}
+    virtual float getAlphaMax() {return _state.alphamax;}
+    virtual float getHeightMin() {return _state.heightmin;}
+    virtual float getHeightMax() {return _state.heightmax;}
+    virtual float getCullAngle() {return _state.cullangle;}
 
-    virtual void setAlphaMin( float value ) {_alphamin = value;}
-    virtual void setAlphaMax( float value ) {_alphamax = value;}
-    virtual void setHeightMin( float value ) {_heightmin = value;}
-    virtual void setHeightMax( float value ) {_heightmax = value;}
+    virtual void setAlphaMin( float value ) {_state.alphamin = value;}
+    virtual void setAlphaMax( float value ) {_state.alphamax = value;}
+    virtual void setHeightMin( float value ) {_state.heightmin = value;}
+    virtual void setHeightMax( float value ) {_state.heightmax = value;}
 
-    virtual void setCullAngle( float value ) {_cullangle = value;}
-    virtual void toggleCulling() {_culling = _culling ? false : true;}
+    virtual void setCullAngle( float value ) {_state.cullangle = value;}
+    virtual void toggleCulling() {_state.culling = _state.culling ? false : true;}
+    virtual bool getCulling() {return _state.culling;}
+    virtual void setCulling(bool value) {_state.culling = value;}
     
     virtual triangle_list getConnectivity(unsigned int index) {return _connectivity.at(index);}
 
-    const std::string getSwollenDir() {return *_swollendir;}
-    virtual void setSwollenDir(const std::string path) {_swollendir = new std::string(path);}
+    const std::string getSwollenDir() {return *(_state.swollendirectory);}
+    virtual void setSwollenDir(const std::string path) {_state.swollendirectory = new std::string(path);}
 
 
@@ -111,7 +113,23 @@
     virtual ~SWWReader();
 
-    std::string* _filename;
-    std::string* _swollendir;
-    
+
+    // state contains all the info needed to serialize
+    struct
+    {
+          float alphamax;  // define alpha (transparency) function
+          float alphamin;
+          float heightmax;
+          float heightmin;
+
+          float cullangle;  // cull triangles with steepness angle above this value
+          bool culling;   // culling is on or off
+
+          std::string* swwfilename;
+          std::string* bedslopetexturefilename;
+          std::string* swollendirectory;
+
+    } _state;
+
+
     // constructor determines SWW validity (netcdf + proper structure)
     bool _valid;
@@ -147,7 +165,4 @@
     osg::ref_ptr<osg::Vec4Array> _stagecolors;
 
-    // optional bedslope texture map
-    std::string* _bedslopetexture;
-
     // optional geodata for bedslope texture map
     struct
@@ -179,11 +194,4 @@
     std::vector<triangle_list> _connectivity;
 
-    // define alpha (transparency) function
-    float _alphamax, _alphamin, _heightmax, _heightmin;
-
-    // cull triangles with steepness angle above this value
-    float _cullangle;
-    bool _culling;
-
 };
 
Index: /Swollen/swollen/hud.cpp
===================================================================
--- /Swollen/swollen/hud.cpp	(revision 110)
+++ /Swollen/swollen/hud.cpp	(revision 111)
@@ -47,4 +47,14 @@
     _time->setText("t = 0.0");
 
+    // recording mode text
+    _record = new osgText::Text;
+    _record->setFont(font);
+    _record->setColor(osg::Vec4(DEF_HUD_COLOUR) );
+    _record->setCharacterSize(30);
+    _record->setPosition(osg::Vec3(600,20,0));
+    _record->setFontResolution(40,40);
+    _record->setText("");
+
+
     // state
     osg::StateSet *state = _projection->getOrCreateStateSet();
@@ -60,4 +70,5 @@
     textnode->addDrawable( _title );
     textnode->addDrawable( _time );
+    textnode->addDrawable( _record );
     xfm->addChild( textnode );
     _projection->addChild( xfm );
@@ -84,2 +95,8 @@
 }
 
+
+void HeadsUpDisplay::setRecordingMode( char *s )
+{
+    _record->setText(s);
+}
+
Index: /Swollen/swollen/hud.h
===================================================================
--- /Swollen/swollen/hud.h	(revision 110)
+++ /Swollen/swollen/hud.h	(revision 111)
@@ -25,4 +25,5 @@
     virtual void setTime(float t);
     virtual void setTitle(char *s);
+    virtual void setRecordingMode(char *s);
     virtual osg::Projection* get(){ return _projection; }
 
@@ -30,6 +31,7 @@
 
     osg::Projection* _projection;
-	osgText::Text* _title;
-	osgText::Text* _time;
+    osgText::Text* _title;
+    osgText::Text* _time;
+    osgText::Text* _record;
     virtual ~HeadsUpDisplay();
 
Index: /Swollen/swollen/keyboardeventhandler.cpp
===================================================================
--- /Swollen/swollen/keyboardeventhandler.cpp	(revision 110)
+++ /Swollen/swollen/keyboardeventhandler.cpp	(revision 111)
@@ -15,4 +15,5 @@
     _togglewireframe = false;
     _toggleculling = false;
+
 }
 
@@ -83,4 +84,19 @@
 
 
+	    case '1':
+		_togglerecording = true;
+		handled = true;
+		break;
+
+	    case '2':
+		_recordingplayback = true;
+		handled = true;
+		break;
+
+	    case '3':
+		_recordingsave = true;
+		handled = true;
+		break;
+
 	    }
 
@@ -138,2 +154,11 @@
 
 
+bool KeyboardEventHandler::toggleRecording()
+{
+    if( _togglerecording )
+    {
+        _togglerecording = false;
+        return true;
+    }
+    return false;
+}
Index: /Swollen/swollen/keyboardeventhandler.h
===================================================================
--- /Swollen/swollen/keyboardeventhandler.h	(revision 110)
+++ /Swollen/swollen/keyboardeventhandler.h	(revision 111)
@@ -24,4 +24,5 @@
     virtual bool toggleWireframe();
     virtual bool toggleCulling();
+    virtual bool toggleRecording();
     virtual int getTimestep(){return (unsigned int) _timestep;}
     virtual void setTime(float time);
@@ -31,4 +32,5 @@
     float _tps, _prevtime, _tpsorig;
     bool _paused, _timestepchanged, _togglewireframe, _toggleculling;
+    bool _togglerecording, _recordingplayback, _recordingsave;
 };
 
Index: /Swollen/swollen/main.cpp
===================================================================
--- /Swollen/swollen/main.cpp	(revision 110)
+++ /Swollen/swollen/main.cpp	(revision 111)
@@ -184,4 +184,5 @@
    }
 
+
    // register additional event handler
    KeyboardEventHandler* event_handler = new KeyboardEventHandler(sww->getNumberOfTimesteps(), tps);
@@ -205,4 +206,8 @@
 
 
+   // animation mode is off to start
+   bool recordingmode = false;
+
+
    unsigned int timestep = 0;
    while( !viewer.done() )
@@ -235,4 +240,50 @@
       }
 
+      /*
+        Finite State Machine for animation
+      
+        0 1 1 begin storing view/orientation/cull settings
+        0 2 2 if exists, store current settings, commence playback of saved animation path
+        0 3 0 save animation to disk
+
+        1 1 0 stop storing settings
+        1 2 2 stop storing settings and commence playback
+        1 3 1 save animation, keep recording
+
+        2 2 0 stop playback, return to saved settings
+        2 1 2 no effect
+        2 3 2 save animation, continue playing back
+
+        header comprised of original command line arguments
+
+        state comprised of:
+           frame
+           elapsedtime
+           position
+           orientation
+           timestep
+           cullsteep
+           wireframe
+  
+      */
+
+
+      if( event_handler->toggleRecording() )
+      {
+         switch( recordingmode )
+         {
+            case false : 
+               recordingmode = true; 
+               hud->setRecordingMode("recording");
+               break;
+            case true : 
+               recordingmode = false; 
+               hud->setRecordingMode("");
+               break;
+         }
+
+      }
+
+
       // update the scene by traversing with the update visitor 
       viewer.update();
Index: /Swollen/swollen/version.cpp
===================================================================
--- /Swollen/swollen/version.cpp	(revision 110)
+++ /Swollen/swollen/version.cpp	(revision 111)
@@ -1,1 +1,1 @@
-const char* version() { const char* s = "Revision: 105:106M"; return s; }
+const char* version() { const char* s = "Revision: 110M"; return s; }
Index: /Swollen/swollen/watersurface.cpp
===================================================================
--- /Swollen/swollen/watersurface.cpp	(revision 110)
+++ /Swollen/swollen/watersurface.cpp	(revision 111)
@@ -73,4 +73,8 @@
     _stateset->setTextureAttributeAndModes( 1, texgen, osg::StateAttribute::ON );
     _stateset->setTextureAttribute( 1, texenv );
+
+    // default is filled watersurface
+    _wireframe = false;
+
 }
 
@@ -114,4 +118,15 @@
 void WaterSurface::toggleWireframe()
 {
+   if( _wireframe )
+      _wireframe = false;
+   else
+      _wireframe = true;
+
+   setWireframe(_wireframe);
+}
+
+
+void WaterSurface::setWireframe(bool value)
+{
     osg::PolygonMode* polyModeObj = 
         dynamic_cast<osg::PolygonMode*>(_stateset->getAttribute(osg::StateAttribute::POLYGONMODE));
@@ -123,12 +138,13 @@
     }
 
-    switch( polyModeObj->getMode(osg::PolygonMode::FRONT_AND_BACK) )
+    switch( value )
     {
-    
-      case osg::PolygonMode::FILL : polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,
-							 osg::PolygonMode::LINE); break;
-      case osg::PolygonMode::LINE : polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,
-							 osg::PolygonMode::FILL); break;
-      case osg::PolygonMode::POINT : break;
+       case true :
+          polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
+          break;
+
+       case false :
+         polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL);
+         break;
     }
 }
Index: /Swollen/swollen/watersurface.h
===================================================================
--- /Swollen/swollen/watersurface.h	(revision 110)
+++ /Swollen/swollen/watersurface.h	(revision 111)
@@ -27,4 +27,6 @@
     virtual void setTimeStep( unsigned int ts );
     virtual void toggleWireframe();
+    virtual bool getWireframe(){ return _wireframe; };
+    virtual void setWireframe(bool wireframe);
 
 protected:
@@ -35,5 +37,5 @@
     osg::StateSet* _stateset;
     virtual ~WaterSurface();
-
+    bool _wireframe;
 };
 
Index: /Swollen/swwreader/swwreader.cpp
===================================================================
--- /Swollen/swwreader/swwreader.cpp	(revision 110)
+++ /Swollen/swwreader/swwreader.cpp	(revision 111)
@@ -40,8 +40,8 @@
 
    // netcdf filename
-   _filename = new std::string(filename);
+   _state.swwfilename = new std::string(filename);
 
    // netcdf open
-   _status.push_back( nc_open(_filename->c_str(), NC_NOWRITE, &_ncid) );
+   _status.push_back( nc_open(filename.c_str(), NC_NOWRITE, &_ncid) );
    if (this->_statusHasError()) return;
 
@@ -131,12 +131,12 @@
 
    // alpha-scaling defaults, can be overridden after construction by command line parameters
-   _alphamin = DEFAULT_ALPHAMIN;
-   _alphamax = DEFAULT_ALPHAMAX;
-   _heightmin = DEFAULT_HEIGHTMIN;
-   _heightmax = DEFAULT_HEIGHTMAX;
+   _state.alphamin = DEFAULT_ALPHAMIN;
+   _state.alphamax = DEFAULT_ALPHAMAX;
+   _state.heightmin = DEFAULT_HEIGHTMIN;
+   _state.heightmax = DEFAULT_HEIGHTMAX;
 
    // steepness culling default, can be overridden after construction by command line parameter
-   _cullangle = DEFAULT_CULLANGLE;
-   _culling = DEFAULT_CULLONSTART;
+   _state.cullangle = DEFAULT_CULLANGLE;
+   _state.culling = DEFAULT_CULLONSTART;
 
    // loop index
@@ -270,4 +270,14 @@
    _valid = true;
 
+   std::cout << _state.alphamin << std::endl;
+   std::cout << _state.alphamax << std::endl;
+   std::cout << _state.heightmin << std::endl;
+   std::cout << _state.heightmax << std::endl;
+   std::cout << _state.cullangle << std::endl;
+   std::cout << _state.culling << std::endl;
+
+   std::cout << *_state.swwfilename << std::endl;
+   std::cout << *_state.bedslopetexturefilename << std::endl;
+
 }
 
@@ -285,5 +295,5 @@
 {
    osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] filename: " << filename <<  std::endl;
-   _bedslopetexture = new std::string(filename);
+   _state.bedslopetexturefilename = new std::string(filename);
    _bedslopegeodata.hasData = false;
 
@@ -311,15 +321,15 @@
       {
          _bedslopegeodata.xorigin = geodata[0];
-	 _bedslopegeodata.yorigin = geodata[3];
-	 _bedslopegeodata.rotation = geodata[2];
-	 _bedslopegeodata.xpixel = geodata[1];
-	 _bedslopegeodata.ypixel = geodata[5];
-	 _bedslopegeodata.hasData = true;
-
-	 osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] xorigin: " << _bedslopegeodata.xorigin <<  std::endl;
-	 osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] yorigin: " << _bedslopegeodata.yorigin <<  std::endl;
-	 osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] xpixel: " << _bedslopegeodata.xpixel <<  std::endl;
-	 osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] ypixel: " << _bedslopegeodata.ypixel <<  std::endl;
-	 osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] rotation: " << _bedslopegeodata.rotation <<  std::endl;
+         _bedslopegeodata.yorigin = geodata[3];
+         _bedslopegeodata.rotation = geodata[2];
+         _bedslopegeodata.xpixel = geodata[1];
+         _bedslopegeodata.ypixel = geodata[5];
+         _bedslopegeodata.hasData = true;
+
+         osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] xorigin: " << _bedslopegeodata.xorigin <<  std::endl;
+         osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] yorigin: " << _bedslopegeodata.yorigin <<  std::endl;
+         osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] xpixel: " << _bedslopegeodata.xpixel <<  std::endl;
+         osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] ypixel: " << _bedslopegeodata.ypixel <<  std::endl;
+         osg::notify(osg::INFO) << "[SWWReader::setBedslopetexture] rotation: " << _bedslopegeodata.rotation <<  std::endl;
       }
    }
@@ -330,5 +340,5 @@
 osg::Image* SWWReader::getBedslopeTexture()
 {
-   return osgDB::readImageFile( _bedslopetexture->c_str() );
+   return osgDB::readImageFile( _state.bedslopetexturefilename->c_str() );
 }
 
@@ -350,5 +360,5 @@
    else
    {
-      // decal'd using (x,y) locations scaled by extents into range [0,1]
+      // decaled using (x,y) locations scaled by extents into range [0,1]
       for( unsigned int iv=0; iv < _npoints; iv++ )
          _bedslopetexcoords->push_back( osg::Vec2( (_px[iv]-_xoffset)*_xscale, (_py[iv]-_yoffset)*_yscale ) );
@@ -391,5 +401,5 @@
 
    // cullangle given in degrees, test is against dot product
-   float cullthreshold = cos(osg::DegreesToRadians(_cullangle));
+   float cullthreshold = cos(osg::DegreesToRadians(_state.cullangle));
 
    // over all stage triangles
@@ -427,5 +437,5 @@
    // where a = (alphamax-alphamin)/(hmax-hmin)
    float alpha, height, alphascale;
-   alphascale = (_alphamax - _alphamin) / (_heightmax - _heightmin);
+   alphascale = (_state.alphamax - _state.alphamin) / (_state.heightmax - _state.heightmin);
    _stagecolors = new osg::Vec4Array;
    for (iv=0; iv < _npoints; iv++)
@@ -434,11 +444,11 @@
       height = _stagevertices->at(iv).z() - _bedslopevertices->at(iv).z();
 	
-      if (height < _heightmin)
+      if (height < _state.heightmin)
          alpha = 0.0;
       else 
       {
-         alpha = alphascale * (height - _heightmin) + _alphamin;
-         if( alpha > _alphamax ) 
-            alpha = _alphamax;
+         alpha = alphascale * (height - _state.heightmin) + _state.alphamin;
+         if( alpha > _state.alphamax ) 
+            alpha = _state.alphamax;
       }
 
@@ -447,5 +457,5 @@
 
    // steep triangle vertices should have alpha=0, overwrite such vertex colours
-   if( _culling )
+   if( _state.culling )
    {
       for (iv=0; iv < steeptri->size() ; iv++)
