
/*
  *  constream.h , v 0.4 1996/05/02
  *
  * 
  *  o  based on NCurses
  *  o  OO - Designed and Implemented
  *  o  redirects the outputstream to the screen using the
  *     ostream interface  
  *  o  compatible with the constream interface of Borlands 
  *     C++ DOS package 
  *
  *
  *  Copyright (c) 1996 Dipl.-Ing.,Dipl.-Ing.(FH)  Jurgen Eidt
  *  All rights reserved.  
  *  GPL-Copying-policy.
  *  
  *  Redistribution and use in source and binary forms are permitted
   *  provided that the above copyright notice and this paragraph are
  *  duplicated in all such forms and that any documentation,
  *  advertising materials, and other materials related to such
  *  distribution and use acknowledge that the software was developed
  *  by Jurgen Eidt.  The name may not be used to endorse or promote 
  *  products derived from this software without specific prior written 
  *  permission.
  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  *  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  *  WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
  * 
  *  	Jurgen Eidt
  *  	Dromersheimer Str. 2
  *  	D-55411 Bingen am Rhein
  *     Germany
  * 
  *  	E-Mail: jurgen@tap.de 
  *  	FidoNet: 2:2455/240.25
  * 
*/


#ifndef CONSTREAM
#define CONSTREAM

#include<ostream.h>
#include<ncurses.h>


// DOS-conio-Colors <-> NCurses-Colors
// for compatibility
#define BLACK 		COLOR_BLACK
#define RED		COLOR_RED
#define GREEN 		COLOR_GREEN
#define YELLOW		COLOR_YELLOW
#define BROWN		COLOR_YELLOW
#define BLUE		COLOR_BLUE
#define MAGENTA		COLOR_MAGENTA
#define CYAN 		COLOR_CYAN
#define WHITE		COLOR_WHITE


// for LIGHT-Colors, use the highvideo manipulator;
// they are only considered for compatibility
#define LIGHTGRAY	COLOR_WHITE
#define DARKGRAY	COLOR_WHITE
#define LIGHTBLUE	COLOR_BLUE
#define LIGHTGREEN	COLOR_GREEN
#define LiGHTCYAN	COLOR_CYAN
#define LIGHTRED	COLOR_RED


// generic manipulator-class with one Argument
// we need only int's here, but for enhancements
// it's easier to define a Template
template<class T> class CNSTRMmanip_arg
{
private:
  T i;
  ostream& (*f)(ostream&, T);   // the pointer to the manipulator-function

public:
  CNSTRMmanip_arg(ostream& (*ff)(ostream&, T), T ii)
  { f = ff; i = ii; }

  // define, what do to with that class in an ostream
  friend ostream& operator<<(ostream& os, CNSTRMmanip_arg m)
  { return (*m.f)(os, m.i); }
};


// generic manipulator-class with two Arguments
// like above :-)
template<class T> class CNSTRMmanip_arg_arg
{
private:
  T _i1;
  T _i2;
  ostream& (*f)(ostream&, T, T); 

public:
  CNSTRMmanip_arg_arg(ostream& (*ff)(ostream&, T, T), T i1, T i2)
  { f = ff, _i1 = i1, _i2 = i2; } 

  friend ostream& operator<<(ostream& os, CNSTRMmanip_arg_arg m)
  { return (*m.f)(os, m._i1, m._i2); }
};


class conbuf : public streambuf
{
private:
  int x1, y1, x2, y2;
  int isInit;
  
  void NCursesInit();
  int overflow(int);    // flushes Buffer
      
protected:
  short fg, bg;		// foregroundcolor, backgroundcolor
  short wfg, wbg;	// the colors for clrscr()	
  int b, h;		// geometry of the window,
                        // for the boundary check of setxy(...)
  
  void clrscr(chtype);
  void reset();
  void window(int, int, int, int);

  chtype mask;		// for the attributes (i.e. highvideo)
  WINDOW* Fenster;	// The "constream" - Window

public:
  conbuf();
  ~conbuf();
};


class constream: virtual private conbuf, public ostream
{
public:
  void clrscr(chtype ch = ' ')         // (chtype)' ' is space-character 
  { 
    conbuf::clrscr(ch & A_CHARTEXT); 
  }

  void reset()
  { 
    conbuf::reset();
  }

  void window(int x1, int y1, int x2, int y2)
  {
   conbuf::window(x1, y1, x2, y2);
  }
  
  int wherex();
  int wherey();
  
  friend ostream& flush(ostream& os);
  friend ostream& endl(ostream& os);
  friend ostream& clreol(ostream& os);
  friend ostream& delline(ostream& os);
  friend ostream& highvideo(ostream& os);
  friend ostream& insline(ostream& os);
  friend ostream& lowvideo(ostream& os);
  friend ostream& normvideo(ostream& os); 
  friend ostream& blinkon(ostream& os);
  friend ostream& blinkoff(ostream& os);
  friend ostream& reverseon(ostream& os);
  friend ostream& reverseoff(ostream& os);
  friend ostream& reset(ostream& os);
  friend ostream& underlineon(ostream& os);
  friend ostream& underlineoff(ostream& os);
 
 
  friend CNSTRMmanip_arg<int> setclr(int i);
  friend ostream& _setclr(ostream& os, int i);
  friend CNSTRMmanip_arg<int> setbk(int i);
  friend ostream& _setbk(ostream& os, int i);
  friend CNSTRMmanip_arg<int> setattr(int i);
  friend ostream& _setattr(ostream& os, int i);
  friend CNSTRMmanip_arg<int> setcrsrtype(int i);
  friend ostream& _setcrsrtype(ostream& os, int i);
  friend CNSTRMmanip_arg_arg<int> setxy(int x, int y);
  friend ostream& _setxy(ostream& os, int x, int y);


  constream() : ostream((conbuf*)this), ios(0) 
  {
    window(1, 1, COLS, LINES); 
  }

  constream(int x1, int y1, int x2, int y2)
       : ostream((conbuf*)this), ios(0) 
  {
    window(x1, y1, x2, y2); 
  }

  virtual ~constream() { sync(); }
};


#endif
