// This may look like C code, but it is really -*- C++ -*-

/* 
Copyright (C) 1989, 1992 Free Software Foundation
    written by Eric Newton (newton@rocky.oswego.edu)

This file is part of the GNU C++ Library.  This library is free
software; you can redistribute it and/or modify it under the terms of
the GNU Library General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.  This library 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 Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*
 * Edited for compatablity with C++, 2/28/89 <ecn>
 * This file has all the /usr/include/curses.h info (with proper prototypes)
 * used for the CursesWindow classes.  You may need to change this to be
 * compatable with your curses implementation.
 *
 */

#ifndef _curses_h
#ifdef __GNUG__
#pragma interface
#endif
#define _curses_h

# include   <stddef.h>
# include   <std.h>
# include   <stdio.h> 
extern "C" {
#ifndef VMS
# include   <sgtty.h>
#endif

// protection against possibility that these are macros:

#ifndef stty
extern int stty(int, struct sgttyb*); 
#endif

#ifndef gtty
extern int gtty(int, struct sgttyb*); 
#endif

int       tputs(const char *, int, auto int (*)());
int       tgetent(const char*, const char*);
int       tgetnum(const char*);
int       tgetflag(const char*);
char*     tgetstr(const char *, char **);
char*     tgoto(const char*, int, int);

}

typedef char cbool; // curses explicitly declares bools as chars

#if defined(hpux)
#define ERR -1
#define OK 0
#else
#define ERR 0
#define OK 1
#endif

/*
 *  BSD'ish.  Warning!!
 *
 */
# define    _ENDLINE    001
# define    _FULLWIN    002
# define    _SCROLLWIN  004
# define    _FLUSH      010
# define    _FULLLINE   020
# define    _IDLINE     040
# define    _STANDOUT   0200
# define    _NOCHANGE   -1

# define    _puts(s)    tputs(s, 0, _putchar)

/*
 * Capabilities from termcap
 */

extern cbool     AM, BS, CA, DA, DB, EO, HC, HZ, IN, MI, MS, NC, NS, OS, UL,
        XB, XN, XT, XS, XX;
extern char *AL, *BC, *BT, *CD, *CE, *CL, *CM, *CR, *CS, *DC, *DL,
        *DM, *DO, *ED, *EI, *K0, *K1, *K2, *K3, *K4, *K5, *K6,
        *K7, *K8, *K9, *HO, *IC, *IM, *IP, *KD, *KE, *KH, *KL,
        *KR, *KS, *KU, *LL, *MA, *ND, *NL, *RC, *SC, *SE, *SF,
        *SO, *SR, *TA, *TE, *TI, *UC, *UE, *UP, *US, *VB, *VS,
        *VE, *AL_PARM, *DL_PARM, *UP_PARM, *DOWN_PARM,
        *LEFT_PARM, *RIGHT_PARM;

extern char PC;

extern cbool    GT, NONL, UPPERCASE, normtty, _pfast;

struct _win_st {
#ifdef VMS
    int		_cury, _curx;
    int		_maxy, _maxx;
    int		_begy, _begx;
#else
    short       _cury, _curx;
    short       _maxy, _maxx;
    short       _begy, _begx;
#endif
    short       _flags;
#ifndef VMS
    short       _ch_off;
#endif
    cbool       _clear;
    cbool       _leave;
    cbool       _scroll;
#ifdef VMS
    cbool	_wrap;
#endif
    char        **_y;
    short       *_firstch;
    short       *_lastch;
    struct _win_st  *_nextp, *_orig;
#ifdef VMS
    struct _win_st  *_parent , *_child;
    int		_id;
#endif
};

#define WINDOW  struct _win_st

extern cbool My_term;
extern cbool _echoit;
extern cbool _rawmode;
extern cbool _endwin;

extern char *Def_term;
extern char  ttytype[];

extern int  LINES;
extern int  COLS; 
extern int  _tty_ch;
extern int  _res_flg;


typedef struct sgttyb SGTTY;

extern SGTTY _tty;

/*
 * standard curses functions.
 *
 */

extern "C"
{
extern WINDOW * stdscr;
extern WINDOW * curscr;
WINDOW * newwin(int lines, int cols, int sy, int sx);
WINDOW * subwin(WINDOW *w, int lines, int cols, int sy, int sx);
WINDOW * initscr();
int      box (WINDOW*, char, char);
int      delwin(WINDOW*);
int      mvcur(int, int, int, int);
int      overlay(WINDOW*, WINDOW*);
int      overwrite(WINDOW*, WINDOW*);
int      scroll(WINDOW*);
int      touchwin(WINDOW*);
int      waddch(WINDOW*, char);
int      waddstr(WINDOW*, const char*);
int      wclear(WINDOW*);
int      wclrtobot(WINDOW*);
int      wclrtoeol(WINDOW*);
int      wdelch(WINDOW*);
int      wdeleteln(WINDOW*);
int      werase(WINDOW*);
int      wgetch(WINDOW*);
int      wgetstr(WINDOW*, char*);
int      winsch(WINDOW*, char);
int      winsertln(WINDOW*);
int      wmove(WINDOW*, int, int);
int      wrefresh(WINDOW*);
int      wstandend(WINDOW*);
int      wstandout(WINDOW*);
int      wprintw(WINDOW*, const char * fmt, ...);
int      mvwprintw(WINDOW*, int y, int x, const char * fmt, ...);
int      wscanw(WINDOW*, const char *, ...);
int      mvwscanw(int, int, WINDOW*, const char*, ...);
int      endwin();
}

/* Pseudo functions */
/* 
 * these are inlines rather than defines here so as to allow overloaded
 * versions in the CursesWindow class
 */

inline int clearok(WINDOW* win, cbool bf)  { return(win->_clear = bf); }
inline int leaveok(WINDOW* win, cbool bf)  { return(win->_leave = bf); }
inline int scrollok(WINDOW* win, cbool bf) { return(win->_scroll = bf); }
inline int flushok(WINDOW* win, cbool bf)  
{ return(bf ? (win->_flags |= _FLUSH):(win->_flags &= ~_FLUSH)); }
inline void getyx(WINDOW* win, int& y, int& x)   
{ y = win->_cury; x = win->_curx; }
inline int winch(WINDOW* win)   
{return  win->_y[win->_cury][win->_curx] & 0177; }

#if defined(USG) || defined(VMS)
extern "C" {
int raw();
int noraw();
int cbreak();
int nocbreak();
}

#else

inline int raw()    
{ return _tty.sg_flags|=RAW, _pfast=_rawmode=1, stty(_tty_ch,&_tty); }
inline int noraw()  
{ return _tty.sg_flags&=~RAW,_rawmode=0,_pfast=!(_tty.sg_flags&CRMOD),stty(_tty_ch,&_tty); }
inline int cbreak() 
{ return _tty.sg_flags |= CBREAK, _rawmode = 1, stty(_tty_ch,&_tty); }
inline int nocbreak() 
{ return _tty.sg_flags &= ~CBREAK,_rawmode=0,stty(_tty_ch,&_tty); }

#endif /* USG */


#if defined(USG) || defined(VMS)

extern "C" {
int _setecho(int);
int _setnonl(int);
}

inline int echo()   { return _setecho(1); }
inline int noecho() { return _setecho(0); }
inline int nl()     { return _setnonl(0); }
inline int nonl()   { return _setnonl(1); }

extern "C" {
int savetty();
int resetty();
int erasechar();
int killchar();
int baudrate();
}

#else /* not USG */

inline int echo()   
{ return _tty.sg_flags |= ECHO, _echoit = 1, stty(_tty_ch, &_tty); }
inline int noecho() 
{ return _tty.sg_flags &= ~ECHO, _echoit = 0, stty(_tty_ch, &_tty); }
inline int nl()     
{ return _tty.sg_flags |= CRMOD,_pfast = _rawmode,stty(_tty_ch, &_tty); }
inline int nonl()   
{ return _tty.sg_flags &= ~CRMOD, _pfast = 1, stty(_tty_ch, &_tty); }
inline int savetty() 
{ return (void) gtty(_tty_ch, &_tty), _res_flg = _tty.sg_flags; }
inline int resetty() 
{ return _tty.sg_flags = _res_flg, stty(_tty_ch, &_tty); }
inline int erasechar() 
{ return _tty.sg_erase; }
inline int killchar()  
{ return _tty.sg_kill; }
inline int baudrate()  
{ return _tty.sg_ospeed; }

#endif /* USG */

extern "C" {
char *longname(char *, char *);
char *getcap(char *);
extern char *_unctrl[];
}

inline int crmode() { return  cbreak(); }
inline int nocrmode() { return  nocbreak(); }
inline char * unctrl(int c) {  return _unctrl[(c) & 0177]; }

#endif

