==============================================================

   class Screen; // 

   class StackScreen {
      int topStack;
      // :    Screen
      Screen *stack;
      void (*handler)();
   };

   class StackScreen {
      int topStack;
      void (*handler)(); //   
??      vector<Screen> stack; //  
   };


   class Screen {
      friend istream& operator>>( istream&, Screen& );
      friend ostream& operator<<( ostream&, const Screen& );
   /*
    * _ screen    _height * _width
    * _cursor     
    * _height  _width -     
    */
   public:
      Screen( int hi = 8, int wid = 40, char bkground = '#');
      //   -  
      void home() { _cursor = 0; }
      void move( int, int ) const ;
      char get() const { return _screen[_cursor]; }
      inline char get( int, int );
      void checkRange( int, int );
      int height() { return _height; }
      int width() { return _width; }
      void set( const string &s );
      void set( char ch );
      bool isEqual( char ch ) const;
      // ...
   private:
      string _screen;
      mutable string::size_type _cursor; //  
      // short _height, _width;
      //    (. 13.5)
      static const int _height = 24;
      static const int _width = 80;   
      inline int remainingSpace();
   };


   class LinkScreen {
      Screen window;
      LinkScreen *next;
      LinkScreen *prev;
   };


   Screen::Screen( int hi, int wid, char bk ) :
      _height( hi ), //  _height  hi
      _width( wid ), //  _width  wid
      _cursor ( 0 ), //  _cursor 
      _screen( hi * wid, bk ) //    hi * wid
                              //   
                              //  '#'
    {  //       
       //      14.5
    }

   bool Screen::isEqual( char ch ) const
   {
      return ch == _screen[_cursor];
   }

   inline void Screen::move( int r, int c )  const
   { //     
      if ( checkRange( r, c ) ) //     ?
      {
         int row = (r-1) * _width; //   
         _cursor = row + c - 1;
      }
   }

   char Screen::get( int r, int c )
   {
      move( r, c ); //  _cursor
      return get(); //   - get()
   }

   inline int Screen::remainingSpace()
   {
      int sz = _width * _height;
      return ( sz - _cursor );
   }


-------------------------------------------------------------------------

   #include <iostream>
   ostream& operator<<( ostream& os, const Screen& s )
   {
      // :    _height, _width  _screen
      os << "<" << s._height << "," << s._width << ">";
      os << s._screen;
      return os;
   }

   #include <iostream>

   #include "screen.h"

   //  -   Screen::
   bool Screen::checkRange( int row, int col )
   { //   
      if ( row < 1 || row > _height || col < 1 || col > _width ) {
         cerr << "Screen coordinates ( "
              << row << ", " << col
              << " ) out of bounds.\n";
         return false;
      }
      return true;
   }

   #include <string>

   void Screen::copy( const Screen &sobj )
   {
      //      sobj -    ,
      //  
      //    this (.  13.4)
      if ( this != &sobj )
      {
         _height = sobj._height;
         _width = sobj._width;
         _cursor = 0;
         //   ;
         //    ,  sobj._screen
         _screen = sobj._screen;
     }
   }

   void Screen::set( const string &s )
   { //   ,     
      int space = remainingSpace();
      int len = s.size();
      if ( space < len ) {
         cerr << "Screen: warning: truncation: "
              << "space: " << space
              << "string length: " << len << endl;
         len = space;
      }
      _screen.replace( _cursor, len, s );
      _cursor += len - 1;
   }

   void Screen::set( char ch )
   {
      if ( ch == '\0' )
         cerr << "Screen: warning: "
              << "null character (ignored).\n";
      else _screen[_cursor] = ch;
   }


   #include "Screen.h"
   #include <iostream>

   int main() {
      Screen sobj(3,3); //     13.3.4
      string init("abcdefghi");
      cout << "Screen Object ( "
           << sobj.height() << ", "
           << sobj.width() << " )\n\n";

      //   
      string::size_type initpos = 0;
      for ( int ix = 1; ix <= sobj.width(); ++ix )
         for ( int iy = 1; iy <= sobj.height(); ++iy )
         {
            sobj.move( ix, iy );
            sobj.set( init[ initpos++ ] );
         }
       
      //   
      for ( int ix = 1; ix <= sobj.width(); ++ix )
      {
         for ( int iy = 1; iy <= sobj.height(); ++iy )
            cout << sobj.get( ix, iy );
         cout << "\n";
      }
      return 0;
   }

