// Output from p2c 1.21alpha-07.Dec.93, the Pascal-to-C translator
// From input file "/var/home/pantec/src/turbo/tmenu/tmenu.p"


//$DEFINE BIG_VIDEO_STACK
//$N-

//$O+


#include <p2c/p2c.h>


#include <p2c/exithandler.h>


#define TMENU_G
#include "/software/include/p2c/tmenu.h"
// p2c: /var/home/pantec/src/turbo/tmenu/tmenu.p, line 219: 
// * Note: Consider using TagStructs or {} for this [328] 


#ifndef NCRT_H
#include "/software/include/p2c/ncrt.h"
#endif


#ifndef FEXIST_H
#include "/software/include/p2c/fexist.h"
#endif


//,
//    Mouse


#define MaxVideoMem     31744   /* 8192,16384,24574,32768 */

#define MaxHeapNr       8

typedef char CharArray[171];
typedef unsigned short WordArrayType[80];
typedef unsigned short BufferType[MaxVideoMem + 1];

struct _REC_Heap {
  unsigned short Min, Max;
};

struct VideoType {
//  unsigned short Seg, index;
  unsigned short index; 
  _REC_Heap Heap[MaxHeapNr + 1];
  long Used[24];
//  BufferType Mem;
};

typedef char CType[255];


static unsigned long int FChar[5][8] = {
  { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
  { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' },
//  { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0' },
  {  ACS_DIAMOND,ACS_CKBOARD,ACS_BULLET,ACS_BOARD,ACS_DEGREE,ACS_LANTERN,ACS_BLOCK,ACS_LTEE },
  { '\332', '\304', '\277', '\263', '\263', '\300', '\304', '\331' },
  { '\261', '\261', '\261', '\261', '\261', '\261', '\261', '\261' }
//  { '\311', '\315', '\273', '\272', '\272', '\310', '\315', '\274' },
//  { '\333', '\337', '\333', '\333', '\333', '\333', '\334', '\333' }
};



#define Extra_Chars  (ACS_DIAMOND | ACS_CKBOARD | ACS_BULLET |  ACS_BOARD |  \
                      ACS_DEGREE | ACS_LANTERN | ACS_BLOCK | \
                      ACS_LTEE | ACS_BTEE | ACS_RTEE | ACS_TTEE | \
                      ACS_DARROW | ACS_UARROW | ACS_LARROW | ACS_RARROW | \
                      ACS_ULCORNER | ACS_LLCORNER | ACS_URCORNER | ACS_LRCORNER | \
                      ACS_VLINE | ACS_HLINE | ACS_PLUS)

static boolean MouseAvail = false;
static boolean OutOfMemory = false;

ExitProcType TMenuSaveExit;


VideoType *_Video;


// $I ToString.pas
// $I FExists.pas
// $I ToNumber.pas

// $I cursorOn.pas
// $I NoCursor.pas
// $I setcurs.pas
// $I getcurs.pas




unsigned short GetCurs()
{
 return ((WhereY() << 8) | WhereX());
}

void SetCurs(unsigned short XY)
{
  move((XY >> 8),(XY & 0x0ff));
}



//$F+
static void TMenuExit(void)
{
  delete _Video;
//  _CRT_Done();
  
#ifdef DEBUG
  fprintf(stderr,"TMenu.Done\n"); 
#endif    
}


//$F-

void InstallTMenuExit(void)
{
  TMenuSaveExit.proc = ExitProc.proc;
  TMenuSaveExit.link = ExitProc.link;
  
  ExitProc.proc = TMenuExit;
  ExitProc.link = (long int)&TMenuSaveExit; 

  _Video = new VideoType;

  _Video->index = 0;
  P_expset(_Video->Used, 0x1);
//  _Video->Heap[0].Min = 0;
//  _Video->Heap[0].Max = 0;

//  Video->Seg = &(Video->Mem);
//  void *p = &Video->Mem;
//  memset(p, '\0', MaxVideoMem + 1);
 
  _CRT_Init();
  bkgdset(ct_attr(7) | ' ');
  wnoutrefresh(stdscr);
  
  clear();
  wnoutrefresh(stdscr);
//  doupdate();
  getmaxyx(stdscr,_Display_.Height,_Display_.Width);
}


static unsigned short GetChar(uchar X, uchar Y)
{
#ifdef DEBUG
  fprintf(stderr,"GetChar(entry)\n");
#endif

  chtype ch;
  unsigned short c,a,b,d,r;
  
  int lx=stdscr->_curx;
  int ly=stdscr->_cury;
  
  ch=mvinch(Y,X);
  c = (ch & A_CHARTEXT);
  a = 0;
 
  if ((ch & A_BOLD)>0) 
     a|=0x0800;

  if ((ch & A_BLINK)>0) 
     a|=0x8000;
     
  b = (ch & A_COLOR);        // -----> this is a HACK
  d = a | ((b & 0x3800) << 1) | (b & 0x0700);    

  r = (d | c);
  move(ly,lx);

   
  return r;
}


static void WriteChar(uchar X, uchar Y, unsigned short AC)
{
#ifdef DEBUG
  fprintf(stderr,"WriteChar(entry)\n");
#endif
  int lx=stdscr->_curx;
  int ly=stdscr->_cury;

  TextAttr=(AC >> 8);
  _Set_Attribute();
   
  mvaddch(Y,X,AC & 0xff);
  move(ly,lx);
}


void ChangeAttr(uchar x, uchar y, uchar x2, uchar y2, uchar a)
{
#ifdef DEBUG
  fprintf(stderr,"ChangeAttr(entry)\n");
#endif

  unsigned long int li;

  uchar m = x - 1;
  uchar n = x2 - 1;
  uchar o = y - 1;
  uchar p = y2 - 1;

  int lx=stdscr->_curx;
  int ly=stdscr->_cury;

//  TextAttr=a;
//  _Set_Attribute();
  li=ct_attr(a);

  for (uchar i = m; i <= n; i++)
     mvchgat(o,m,n-m+1,cur_attr,li,NULL);
  
  move(ly,lx);   
  wnoutrefresh(stdscr);               
}


void GetStringFast(uchar x, uchar y, uchar l, char *st)
{
#ifdef DEBUG
  fprintf(stderr,"GetStringFast(entry)\n");
#endif

  chtype chstr[256];
  char b;
  char c = '\0';
  
  int lx=stdscr->_curx;
  int ly=stdscr->_cury;
  mvinchstr(y,x,(chtype *)&chstr);

  strcpy(st,"");
  int i;
  for (i=0;i<l;i++)
    {
     b=(chstr[i] & A_CHARTEXT);
     st[i]=b;
    } 
    
  st[i]='\0';  
  move(ly,lx);
}


void WriteStringFast(uchar x, uchar y, uchar a, char *st)
{
#ifdef DEBUG
  fprintf(stderr,"WriteStringFast(entry)\n");
#endif

  int lx=stdscr->_curx;
  int ly=stdscr->_cury;

  TextAttr=a;
  _Set_Attribute();
  mvaddstr(y,x,st);
  move(ly,lx);
}


void ReadXYCharAttr(int x, int y, chtype* C, unsigned char* A)
{
  chtype CH=mvwinch(stdscr,y,x);

  *C = (CH & (A_CHARTEXT | Extra_Chars));
  *A = 0;
 
  if ((CH & A_BOLD)>0) 
     *A |= 0x08;

  if ((CH & A_BLINK)>0) 
     *A |= 0x80;
     
  unsigned short b = (CH & A_COLOR);        // -----> this is a HACK
  unsigned short d = ((b & 0x3800) << 1) | (b & 0x0700);    
           
  *A |= (d  >> 8);
}



void Noise(void)
{
  for (uchar i = 1; i <= 20; i++)
    {
     Sound(300);
     Delay(1);
     Sound(200);
     Delay(2);
    }

  NoSound();
}


char GetCharAbs(uchar X, uchar Y)
{
#ifdef DEBUG
  fprintf(stderr,"GetCharAbs(entry)\n");
#endif
  return (GetChar(X, Y) & 255);
}


void WriteCharAbs(uchar X, uchar Y, uchar A, char C)
{
#ifdef DEBUG
  fprintf(stderr,"WriteCharAbs(entry)\n");
#endif

  unsigned short w = C | ((A << 8) & 0xff00L);

  WriteChar(X, Y, w);
}


void SetCursAbs(uchar x, uchar y)
{
//  unsigned short w = x | ((y << 8) & 0xff00L);
//  SetCurs(w);
  move(y,x);
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// The Object:  TextViewType
//___________________________________________________
void TextViewType::Init(uchar nx1, uchar ny1, uchar nx2, uchar ny2, uchar ntp)
{
#ifdef DEBUG
  fprintf(stderr,">TextViewType.Init()\n");
#endif
  
  Tp = ntp;
  Hidden = true;
  BC = 0x07;
  
  Coord.x1 = nx1;
  Coord.y1 = ny1;
  Coord.x2 = nx2;
  Coord.y2 = ny2;
  Coord.h  = Coord.y2-Coord.y1+1;
  Coord.w  = Coord.x2-Coord.x1+1;

  HeapNr=_Video->index;
  _Video->index++;  

//  sprintf((char *)&BufName,"/tmp/%d.w%d",getpid(),HeapNr);
//  tmpfile=fopen(BufName,"w+");  

#ifdef DEBUG
//  if (tmpfile==NULL)
//    fprintf(stderr,"==%s==%d==\n",BufName,tmpfile);
#endif
  

    
  if (Coord.x1 == 1 || Coord.y1 == 1)
    Tp = 6;

  switch (Coord.x2)
    {

            case 80: Tp = 0;
     break; case 79:
            case 78: Tp %= 6;
    }

  switch (Coord.y2)
    {
            case 25: Tp = 0;
     break; case 24: Tp %= 6;
    }

  int i,j;
  
  // Border
  if (unsigned(Tp % 6) < 32 && ((1L << (Tp % 6)) & 0x3e) != 0)
          i = 1;
        else
          i = 0;

  // Shadow
  if (Tp / 6 == 1)
          j = 1;
        else
          j = 0;

  BackStore.y1 = Coord.y1 - 1 - i;
  BackStore.x1 = Coord.x1 - 1 - i;
  BackStore.w  = Coord.w+j+i+i;
  BackStore.h  = Coord.h+j+i+i;


  w_save=newwin(BackStore.h,BackStore.w,BackStore.y1,BackStore.x1); 
  w_self=subwin(stdscr,Coord.h+i+i,Coord.w+i+i,Coord.y1-1-i,Coord.x1-1-i);
  w_in  =subwin(stdscr,Coord.h,Coord.w,Coord.y1-1,Coord.x1-1);

#ifdef DEBUG
  fprintf(stderr,"i: %d\tj: %d\n",i,j);
  fprintf(stderr,"Coords: h:%d w:%d y:%d x:%d y2:%d x2:%d\n",Coord.h,Coord.w,
                                                     Coord.y1,Coord.x1,
                                                     Coord.y2,Coord.x2);
  fprintf(stderr,"SA      h:%d w:%d y:%d x:%d y2:%d x2:%d\n",BackStore.h,BackStore.w,
                                                     BackStore.y1,BackStore.x1);
  fprintf(stderr,"w_save: %d\tw_self: %d\tw_in: %d\n",w_save,w_self,w_in);
#endif

 
  BackStore.Size = BackStore.h * BackStore.w;
  BackStore.Buf = new CA_Type[BackStore.Size];

  if (Coord.h>1) 
     scrollok(w_in,true);

  clearok(w_in,true);  

#ifdef DEBUG     
  fprintf(stderr,"<TextViewType.Init()\n");
#endif  
}


void TextViewType::Hide(void)
{
  uchar i, j;
  unsigned short k;
  unsigned char Last_Attr=0;

#ifdef DEBUG
  fprintf(stderr,"TextViewType.Hide(%d)>\t",HeapNr);
#endif

  if (Hidden==false)
     {
      for (i=0;i<BackStore.h;i++)
        for (j=0;j<BackStore.w;j++)
          {
           k=(i*BackStore.w)+j;
           TextAttr=BackStore.Buf[k].a;
           if (TextAttr != Last_Attr) 
              {
               Last_Attr=TextAttr;
               _Set_Attribute();
              } 
           mvwaddch(stdscr,i+BackStore.y1,j+BackStore.x1,BackStore.Buf[k]._ec);   
          }
      
      wnoutrefresh(stdscr);
      Hidden = true;
    }  

  doupdate();    
#ifdef DEBUG
  fprintf(stderr,">TextViewType.Hide()\n");
#endif  
}





void TextViewType::Show(void)
{
  uchar i, j;
  unsigned short k,d,b;
  chtype CH;

#ifdef DEBUG
  fprintf(stderr,"TextView::Show(%d)>\t",HeapNr);
#endif

  if (Hidden==true)
    {
     wnoutrefresh(stdscr);

     for (i=0;i<BackStore.h;i++)
        for (j=0;j<BackStore.w;j++)
          {
           k=(i*BackStore.w) + j;

           ReadXYCharAttr(j+BackStore.x1,
                          i+BackStore.y1,
                          &BackStore.Buf[k]._ec,
                          &BackStore.Buf[k].a);
          } 
    }  

  Frame();
  Shadow();

  Hidden = false;

#ifdef DEBUG 
  fprintf(stderr,">TextView::Show(%d)\n",HeapNr);
#endif  
}



void TextViewType::Frame(void)
{
  if (unsigned(Tp % 6) >= 32 || ((1L << (Tp % 6)) & 0x3e) == 0)
    return;
  
  int i=Tp % 6;
  
  wattr_set(w_self,ct_attr(BC));
  wborder(w_self,FChar[i][0],
                 FChar[i][1],
                 FChar[i][2],
                 FChar[i][3],
                 FChar[i][4],
                 FChar[i][5],
                 FChar[i][6],
                 FChar[i][7]);  
                 
//  touchwin(w_save);
  wnoutrefresh(w_self);                 
}


void TextViewType::Shadow(void)
{
  if ((Tp / 6 != 1) || (Tp == 0))
    return;

  chtype CH;
  unsigned char A;
   
  TextAttr=fmShadowColor;
  _Set_Attribute();
 
  for (int i=-1; i<= Coord.w; i++)
    {
     ReadXYCharAttr(i+Coord.x1,Coord.y2+1,&CH,&A);
     mvwaddch(stdscr,Coord.y2+1,i+Coord.x1,CH);
    }

  for (int i=-1; i<= Coord.h; i++)
    {
     ReadXYCharAttr(Coord.x2+1,i+Coord.y1,&CH,&A);
     mvwaddch(stdscr,i+Coord.y1,Coord.x2+1,CH);
    }

  wnoutrefresh(stdscr);               
}


void TextViewType::Activate(void)
{
/*
  Other.WMin = WindMin;
  Other.WMax = WindMax;
  Other.XY = GetCurs();
  Other.Attr = TextAttr;
*/  
//  wnoutrefresh(w_self);
//  wnoutrefresh(w_save);
//  Frame();
//  Shadow();
}


void TextViewType::RestorePrevWin(void)
{
//  LastXY = GetCurs();
/*
  WindMin = Other.WMin;
  WindMax = Other.WMax;
  TextAttr = Other.Attr;
  SetCurs(Other.XY);

  _Set_Window();
  _Set_Attribute();
*/  
}




void TextViewType::Done(void)
{
//  if (!Hidden)
//    Hide();
  
//  fclose(tmpfile);
//  unlink(BufName);
  delete [] BackStore.Buf;
 
    
  if (w_in!=NULL)
    delwin(w_in);
  if (w_self!=NULL)
    delwin(w_self);       
  if (w_save!=NULL)
    delwin(w_save);
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// The Object:  TextWindowType
//________________________________________________
void TextWindowType::Init(uchar x1, uchar y1, uchar x2, uchar y2, uchar nbc,
			  uchar tc, uchar nc, uchar ntp, char *Title)
{
#ifdef DEBUG
  fprintf(stderr,">TextWindowType.Init()\n"); 
#endif  

  TextViewType::Init(x1, y1, x2, y2, ntp);

  NormColor  = nc;
  BC         = nbc;
  TitleColor = tc;

  strcpy(TitleStr, Title);
  LinesWritten = 0;

  Last.X = x1-1;
  Last.Y = y1-1;
  
//  wnoutrefresh(w_in);

#ifdef DEBUG
  fprintf(stderr,"<TextWindowType.Init()\n");
#endif  
}


void TextWindowType::Show(void)
{
#ifdef DEBUG
  fprintf(stderr,"TextWindowType.Show(%d)>\t",HeapNr);
#endif  

  TextViewType::Show();

  while (strlen(TitleStr) > Coord.x2 - Coord.x1 + 3)
    {
     if (*TitleStr != '\0')
       TitleStr[strlen(TitleStr) - 1] = '\0';
    }
  uchar i = ((Coord.x2 - Coord.x1 - strlen(TitleStr) + 3) >> 1) + 1;
  
  wattr_set(w_self,ct_attr(TitleColor));
  wbkgdset(w_self,ct_attr(TitleColor) | ' ');
  mvwaddstr(w_self,0,i,TitleStr);
  wnoutrefresh(w_self);

  wattr_set(w_in,ct_attr(NormColor));
  wbkgdset(w_in,ct_attr(NormColor) | ' ');
  wclear(w_in);
  wnoutrefresh(w_in);
  
#ifdef DEBUG
  fprintf(stderr,">TextWindowType.Show(%d)\n",HeapNr);
#endif  
}



uchar __strcpy(char *D, char *S,uchar n,uchar e)
{
  char *d,*s;
  
  d=D;
  s=S;
  uchar i=0;
  
  while ((*s!=e) && (i<n-1))
    {
     *d=*s;
     d++;
     s++;
     i++;
    }
  *d='\0';  
  return i;
}

void TextWindowType::ScrollDown(char *st)
{
  uchar i;
  uchar k = 0;
  char s[5][82];
  char *sp = st;

  // scan for "newlines" in st
  while ((k < 5) && (*sp != '\0'))
    {
     i=__strcpy((char *)&s[k],sp,82,'\n');
     sp=sp+i+1;
     if (i==0)
        strcat(s[k]," ");
     k++;
    }
    
  SaveState();  
  fprintf(stderr,"%d lines back\n",k);

  for (uchar j = k; j >= 1; j--)
    {
     wscrl(w_in,-1);

     if (strlen(s[j-1]) > Coord.w)
	s[j-1][Coord.w] = '\0';
       else
         while (strlen(s[j-1]) < Coord.w)
	   strcat(s[j-1], " ");

     mvwaddstr(w_in,0,0,st);
    }

  Activate();
  wnoutrefresh(w_in);
  LinesWritten -= k;
}


void TextWindowType::ScrollUp(char st_[])
{
  uchar j = 1;
  uchar i = 0;

  while ((st_[i]!='\0') && (i<254))
     {
      if (st_[i]=='\n')
         j++; 
      i++;
     } 

  LinesWritten += j;
  Activate();
  waddstr(w_in,st_);
  waddch(w_in,'\n');  

  wnoutrefresh(w_in);
  SaveState();
}


void TextWindowType::Activate(void)
{
  wmove(w_in,Last.Y,Last.X);
  wattr_set(w_in,ct_attr(NormColor));
}


void TextWindowType::SaveState(void)
{
  Last.X = w_in->_curx;
  Last.Y = w_in->_cury; 
}


void TextWindowType::Clear(void)
{
  Activate();
  wclear(w_in);
  Last.X = w_in->_curx;
  Last.Y = w_in->_cury; 
  wnoutrefresh(w_in);
}



void TextWindowType::_write_C(char c)
{
  waddch(w_in,c);
  wnoutrefresh(w_in);
}


void TextWindowType::WriteChr(char c)
{
  _write_C(c);
}


void TextWindowType::WriteLnStr(char *St_)
{
  char St[256];

  sprintf((char *)&St,"%s\n",St_);
  waddstr(w_in,St);
  wnoutrefresh(w_in);
}


void TextWindowType::WriteStr(char *St_)
{
  waddstr(w_in,St_);
  wnoutrefresh(w_in);
}


void TextWindowType::ClrEol(void)
{
  wattr_set(w_in,ct_attr(NormColor));
  wclrtoeol(w_in);
  wnoutrefresh(w_in);
}


void TextWindowType::ClrEOF(void)
{
  wattr_set(w_in,ct_attr(NormColor));
  wclrtobot(w_in);
  wnoutrefresh(w_in);
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// calculate the width and height from the Menudef-string
// counting tabs, newlines etc.
//_________________________________________________________
static void CheckString(char *st, uchar &x, uchar &y)
{
  uchar i = 0;
  uchar m = 0;
  char s[256];

  strcpy(s, st);
  x = 0;
  y = 0;

  while (i < strlen(s))
    {
     i++;
     switch (s[i-1])
       {
	       case '\002':
	       case '\003':
	       case '\004':
               case '\005':
               case '\006': m += s[i-1] - 1;
	break; case   '\t': m += 8;
	break; case '\035': m += 28;
	break; case '\036': m += 57;
	break; case    '~': 
               case    '@': {
                             strdelete(s, i, 1);
                  	     i--;
                            } 
	break; case   '\n': {
                             strdelete(s, 1, i);
                	     i += m;
                             m = 0;
                             if (i > x)
                                x = i - 1;
                             i = 0;
                             y++;
                            } 
       } // case    
    } // while
  i += m;

  if (i > x)
    x = i;
}



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// The Object:  TextMenuType
//______________________________________________________

void TextMenuType::Init(uchar nx, uchar ny, uchar nc, uchar hic, uchar asc,
			uchar ntp, char *nst)
{
  uchar j, k;
  char STR_[256];

#ifdef DEBUG
  fprintf(stderr,">TextMenuType.Init()\n");
#endif

  Hidden = true;
  strcpy(st, nst);

  NormColor = nc;
  HiColor = hic;
  AskColor = asc;
  Coord.x1 = nx;
  Coord.y1 = ny;
  Tp = ntp;

  unsigned short i;

  // clear scan- and ctrl-codes
  for (i = 1; i <= MaxItem; i++)
   {
    Box[i-1].scan = '\0';
    Box[i-1].ctrl = '\0';
   } 

  i = 0;
  i = strpos2(st, "\370", 1);
  if (i > 0)
    {
     j = strlen(st);
     for (k = 1; k <= (j - i); k++)
       Box[k-1].scan = st[k + i - 1];
    }
  else
    i = strlen(st) + 1;

  sprintf(STR_, "%.*s", i - 1, st);
  strcpy(st, STR_);

  Coord.y2 = Coord.y1;
  Coord.x2 = _Display_.Width;                  // _Display_.Width
  Event.Filled = false;
  MenuType = Horiz;


  if (strchr(st, '\n') != NULL)
    {
     MenuType = Vert;
     CheckString(st, j, k);
     Coord.x2 = Coord.x1 + j;
     Coord.y2 = Coord.y1 + k;
    }

  if (strchr(st, '@') != NULL)
    MenuType = VertAsk;


#ifdef DEBUG
  fprintf(stderr,"x1: %d\ty1: %d\tx2: %d\ty2: %d\tj: %d\tk: %d\n",nx,ny,Coord.x2,Coord.y2,j,k);
#endif

  TextViewType::Init(nx,ny,Coord.x2,Coord.y2,ntp);
  BC = (NormColor & 0xf0) | (HiColor & 0xf);

#ifdef DEBUG
  fprintf(stderr,"<TextMenuType.Init()\n");
#endif  
}


void TextMenuType::Show(void)
{
  uchar j = 0;
  uchar _k = 0;
  uchar l;

#ifdef DEBUG
  fprintf(stderr,"TextMenuType.Show()->\t");
#endif
    
  boolean HiV = false;
  boolean AsV = false;

  TextViewType::Show();

  wbkgdset(w_in,ct_attr(NormColor) | ' ');
  wattr_set(w_in,ct_attr(NormColor));
  werase(w_in);
  wmove(w_in,0,0);
  wnoutrefresh(w_in);
  
  for (uchar i = 1; i <= strlen(st); i++)
    {
     char c = st[i-1];
     fprintf(stderr,"%c",c); 

     switch (c)
       {

	 case '\002':
	 case '\003':
	 case '\004':
	 case '\005':
	 case '\006':
	for (l = 1; l <= c; l++)
	  waddch(w_in,' ');
	break; case   '\t': waddstr(w_in,"\t");
	break; case '\035': waddstr(w_in,"                             ");
	break; case '\036': waddstr(w_in,"                                                          ");
	break; case    '~': if (!HiV)
                               {
                                wbkgdset(w_in,ct_attr(HiColor) | ' ');
                       		wattr_set(w_in,ct_attr(HiColor));
                                wnoutrefresh(w_in);
                                HiV = true;
                                j++;
                                Box[j-1].x1 = WhereX() * 8; 
                                Box[j-1].y1 = WhereY() * 8;
                                Box[j-1].ctrl = toupper(st[i]);
                               }
                             else
                               {
                       		HiV = false;
                                wbkgdset(w_in,ct_attr(NormColor) | ' ');
                                wattr_set(w_in,ct_attr(NormColor));
                                wnoutrefresh(w_in);
                                Box[j-1].x2 = WhereX() * 8;
                                Box[j-1].y2 = WhereY() * 8;
                               }
	break; case    '@': if (AsV)
                               {
                       		AsV = false;
                                wbkgdset(w_in,ct_attr(NormColor) | ' ');
                                wattr_set(w_in,ct_attr(NormColor));
                                wnoutrefresh(w_in);
                                DSP[_k-1].VL = w_in->_curx - DSP[_k-1].V.x;
                               }
                             else
                               {
                       		_k++;
                                DSP[_k-1].V.x = w_in->_curx;
                                DSP[_k-1].V.y = w_in->_cury;
                                wbkgdset(w_in,ct_attr(AskColor) | ' ');
                                wattr_set(w_in,ct_attr(AskColor));
                                wnoutrefresh(w_in);
                                AsV = true;
                               }
	break; case fmSpecialUp: waddch(w_in,ACS_UARROW);
	break; case fmSpecialDown: waddch(w_in,ACS_DARROW);
	break;

	 default:
	if ((uchar)c > '\001' && c != '\013' && c != '\f' &&
	    (c < '\016' || c > '\034') && c != '\037')
	  {
           waddch(w_in,c);
	   if (HiV)
	     {
	      HiV = false;
              wbkgdset(w_in,ct_attr(NormColor) | ' ');
              wattr_set(w_in,ct_attr(NormColor));
              wnoutrefresh(w_in);	      

	      Box[j-1].x2 = WhereX() * 8;
	      Box[j-1].y2 = WhereY() * 8;
	     } // if
	  } // if 
	break;
       } // case
    }  // for
  Size = j;

#ifdef DEBUG
  fprintf(stderr,"<TextMenuType.Show()\n");  
#endif  
}


void TextMenuType::ClearEvent(void)
{
  Event.WasKey = false;
  Event.Filled = false;
}


void TextMenuType::Idle(void)
{
  usleep(10000);
}

char TextMenuType::GetEvent(void)
{
  char __Result__;

  doupdate();

  if (!EventAvail() == TRUE)
     do {
         Idle();
        } while (!EventAvail() == TRUE);

  if (Event.WasKey)
    __Result__ = ReadKey();

  Event.Filled = false;



#ifdef DEBUG
  fprintf(stderr,"GetEvent_return(%d)\n",__Result__);
#endif
//  for (int i=0; i<MaxItem; i++)

  short i;
  while (i<MaxItem)
    {
     if (Box[i].ctrl==toupper(__Result__))
        return Box[i].ctrl;
     i++;   
    }    

  return __Result__;
}


boolean TextMenuType::EventAvail(void)
{
  if (KeyPressed())
    {
     Event.WasKey = true;
     Event.Filled = true;
    }
  return (Event.Filled);
}


void TextMenuType::Display(uchar nr, char *s, uchar a)
{
  char sv[256];
  char STR_[256];

  strcpy(sv, s);
  while (strlen(sv) < DSP[nr-1].VL)
    strcat(sv, " ");
  while (strlen(sv) > DSP[nr-1].VL)
    strcpy(sv, strsub(STR_, sv, 2, strlen(sv)));

  wbkgdset(w_in,ct_attr(a) | ' ');
  wattr_set(w_in,ct_attr(a));
  mvwaddstr(w_in,DSP[nr-1].V.y,DSP[nr-1].V.x,sv);
  wnoutrefresh(w_in);
}


char *TextMenuType::GetString(char *__Result__, uchar nr)
{
  char s[256];
  char ch;
  uchar p = 0;

  *s = '\0';

  do
    {
     doupdate();
     do {
         Idle();
        } while (KeyPressed()==FALSE);

     ch = ReadKey();
     switch (ch)
       {
	 case '\b':
	if (*s != '\0')
	  {
	   strdelete(s, strlen(s), 1);
	   p--;
	  }
	else
	  Noise();
	break;

	 case '\015':
	// blank case
	break;

	 case '\033':
	strcpy(s, "\033");
	break;

	 default:
	sprintf(s + strlen(s), "%c", ch);
	p++;
	break;
       }

     if ((uchar)ch >= 32 || ((1L << ch) & 0x8002000L) == 0)
       Display(nr, s, fmInputColor);

    } while ((uchar)ch >= 32 || ((1L << ch) & 0x8002000L) == 0);

  if (ch != '\033')
    {
     __Result__ = s;
     return __Result__;
    }
  else
    {
     __Result__ = "\033";
     return __Result__;
    }
}


boolean TextMenuType::ReadStr(uchar nr, char *stn)
{
  boolean __Result__;
  char s[256];
  Str79 STR_;
  char STR_1[256];

  __Result__ = true;
  Display(nr, stn, fmInputColor);
  strcpy(s, GetString(STR_, nr));
  if (strcmp(s, "\033") != 0)
    strcpy(stn, s);
  else
    __Result__ = false;
  Display(nr, stn, AskColor);
//  TextAttr = NormColor;
  return __Result__;
}



void TextMenuType::ReadInt(uchar nr, int &i)
{
  int j;
  char s[256];
  char STR_[256];
//  Str79 STR_1;
  char STR_2[256];

  if (MenuType != VertAsk)
    return;
  Display(nr, IToString(STR_, i), fmInputColor);

//  FormatHex(s, 
  strcpy(s,GetString(STR_, nr));

  int c = sscanf(s, "%d", &j);
  if (c == 1)
    i = j;
  Display(nr, IToString(STR_2, i), AskColor);
//  TextAttr = NormColor;
}


void TextMenuType::ReadWord(uchar nr, unsigned short &i)
{
  unsigned short j;
  char s[256];
  char STR_[256];
//  Str79 STR_1;
  char STR_2[256];

  if (MenuType != VertAsk)
    return;

  Display(nr, WToString(STR_, i), fmInputColor);

//  FormatHex(s, );
//  int c = sscanf(s, "%d", &j) == 0;
  strcpy(s,GetString(STR_, nr));

  int c = sscanf(s, "%d", &j);
  if (c == 1)
    i = j;
  Display(nr, WToString(STR_2, i), AskColor);
//  TextAttr = NormColor;
}


void TextMenuType::ReadByte(uchar nr, uchar &i)
{
  uchar j;
  char s[256];
  char STR_[256];
//  Str79 STR_1;
  char STR_2[256];

  if (MenuType != VertAsk)
    return;
  Display(nr, WToString(STR_, i), fmInputColor);

//  FormatHex(s, 
  strcpy(s,GetString(STR_, nr));

  int c = sscanf(s, "%d", &j);
  if (c == 1)
    i = j;

  Display(nr, WToString(STR_2, i), AskColor);
//  TextAttr = NormColor;
}


void TextMenuType::ReadLong(uchar nr, long &i)
{
  long j;
  char s[256];
  char STR_[256];
//  Str79 STR_1;
  char STR_2[256];

  if (MenuType != VertAsk)
    return;
  Display(nr, LToString(STR_, i), fmInputColor);

//  FormatHex(s, 
  strcpy(s,GetString(STR_, nr));

  int c = sscanf(s, "%d", &j);
  if (c == 1)
    i = j;
  Display(nr, LToString(STR_2, i), AskColor);
//  TextAttr = NormColor;
}


char *TextBrowseType::SeekBack(char *__Result__, long &L)
{
  boolean ready = false;
  char st[256];
  uchar _i;
  CType ChA;

  *st = '\0';
  if (L > 257)
    {
     L -= 257;
     fseek(F, L, 0);
     unsigned short r = fread(ChA, 1, 255, F);
     _i = 255;
    }
  else
    {
     fseek(F, 0, 0);
     unsigned short r = fread(ChA, 1, L - 2, F);
     _i = (L - 1) & 255;
     L = 0;
    }
  while (_i > 0 && !ready)
    {
     _i--;
     if (ChA[_i] == '\n')
       {
	L += _i + 1;
	ready = true;
       }
    }
  fseek(F, L, 0);
  unsigned short r = fread(ChA, 1, 255, F);
  sprintf(st, "%.255s", ChA);
  uchar len = strpos2(st, "\n", 1);
  st[len] = '\0';
  if (*st == '\0')
    strcat(st, " ");
  __Result__ = st;
  return __Result__;
}



char *TextBrowseType::SeekFor(char *__Result__, long &L)
{
  char st[256];
  CType ChA;

  *st = '\0';
  if (L >= P_maxpos(F) - 1)
    {
     strcpy(st, "\n");
     __Result__ = st;
     return __Result__;
    }
  fseek(F, L, 0);
  unsigned short r = fread(ChA, 1, 255, F);
  if (r <= 0)
    {
     strcpy(st, "\n");
     __Result__ = st;
     return __Result__;
    }
  sprintf(st, "%.255s", ChA);
  uchar len = strpos2(st, "\n", 1);

  if (len > 0)
    len--;
  else
    len = P_maxpos(F) - L;

  st[len] = '\0';

  for (uchar _i = 1; _i <= len; _i++)
    st[_i-1] = ChA[_i-1];

  L += len + 1;
  __Result__ = st;
  return __Result__;
}


/*
SeekFor()
{
  char A[384];
  char s[256];
  int i;

  fseek(F,L,0);
  fread(A,1,256,F);
  i=0;
  while ((i<256) && (A[i]!='\n'))
    {
     s[i]=A[i];
     i++;
    } 
  s[i]='\0';
  L=L+i+1;  
}
*/

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//____________________________________________________


void TextBrowseType::Idle(void)
{
}


void TextBrowseType::WriteUp(void)
{
  char st[256];
  char STR_[256];
  char STR_1[256];

  if (L1 <= 0 || i <= 0)
    return;

  Frame.ScrollDown(SeekBack(STR_, L1));
  strcpy(st, SeekBack(STR_, L2));
  i--;
  Menu.Display(2, LToString(STR_, L2), 0x3e);
}

void TextBrowseType::WriteDown(void)
{
  char st[256];
  char STR_[256];
  char STR_1[256];

  if (L2 >= P_maxpos(F))
    return;
  *st = '\0';
  strcpy(st, SeekFor(STR_, L2));
  if (strcmp(st, "\033") == 0)
    return;
  Frame.ScrollUp(st);
  strcpy(st, SeekFor(STR_, L1));
  i++;
  Menu.Display(2, LToString(STR_, L2), 0x3e);
}


void TextBrowseType::Exec(void)
{
  char ch;
  char STR_[256];
  char STR_1[256];

  unsigned short WMin = WindMin;
  unsigned short WMax = WindMax;
  unsigned short XY = GetCurs();
  uchar Attr = TextAttr;

  Menu.Show();
  Frame.Show();

  if (*FileName == '\0')
    strcpy(FileName, "\033");

  doupdate();
  fprintf(stderr,"filename:%s\n",FileName);
//  while (!FileExists(FileName) && Menu.ReadStr(1, FileName)) ;

//  assign(F, FileName);
  F=fopen(FileName,"r");
  rewind(F);
  if (P_ioresult == 0)
    {
     Menu.Display(1, FileName, 0x31);
     L1 = 0;
     L2 = 0;
     h = Frame.Coord.y2 - Frame.Coord.y1;

     for (unsigned short _i = 0; _i <= h; _i++)
	Frame.ScrollUp(SeekFor(STR_, L2));

     i = 0;

     do
       {
	Idle();

	if (Menu.EventAvail())
	  {
//           fprintf(stderr,"updated\n");
	   ch = Menu.GetEvent();
	   switch (ch)
	     {

	       case 'F':
	      if (Menu.ReadStr(1, FileName) && FileExists(FileName))
		{
		 Menu.Display(1, FileName, 0x31);
		 if (F != NULL)
		   fclose(F);
		 F = NULL;

		 /*assign(F, FileName);*/ F=fopen(FileName,"r");
		 rewind(F);
		 L1 = 0;
		 L2 = 0;
		 for (int _i = 0; _i <= h; _i++)
		   {
		    Frame.ScrollUp(SeekFor(STR_, L2));
		   }

		 i = 0;
		}
	      break; case           ' ': for (int _i = 0; _i <= h; _i++)
                        	            WriteDown();
              break; case        '\015':
	             case fmSpecialDown:
	             case fmRightButton: WriteDown();
	      break; case           'b':
                     case           'B': for (int _i = 0; _i <= h; _i++)
                                	    WriteUp();
              break; case           'r':
                     case           'R': WriteUp();
              break; case   fmSpecialUp: WriteUp();
	      break; case  fmLeftButton: if (ch == fmLeftButton &&
                                                Menu.Event.WasY >> 3 < _Display_.Height >> 1)
                                             WriteUp();
                                           else 
                                             WriteDown();
	      break; case          '\0': ch = Menu.GetEvent();
                                	 switch (ch)
                                           {
                                            case fmAltFKey: {   
              if (Menu.ReadStr(1, FileName) && FileExists(FileName))
		{
		 Menu.Display(1, FileName, 0x31);
		 if (F != NULL)
		   fclose(F);
		 F = NULL;

		 //assign(F, FileName);
                 F=fopen(FileName,"r");
		 rewind(F);
		 L1 = 0;
		 L2 = 0;
		 for (int _i = 0; _i <= h; _i++)
		   {
		    Frame.ScrollUp(SeekFor(STR_, L2));
		   }

		 i = 0;
		}
               } 
                 break; case       '-': ch = '\033';
		 break; case   fmUpKey: WriteUp();
		 break; case fmDownKey: WriteDown();
		 break; case fmPgUpKey: for (int _i = 0; _i <= h; _i++)
                                	   WriteUp();
		 break; case fmPgDnKey: for (int _i = 0; _i <= h; _i++)
		                           WriteDown();
		} // case
	     } // case 
	   Menu.ClearEvent();
         } // if EventaAvail
       } while (ch != '\033');  // do

     ch = '~';

     if (F != NULL)
       fclose(F);
     F = NULL;
    } // if P_ioresult

  Frame.Hide();
  Menu.Hide();
/*
  WindMin = WMin;
  WindMax = WMax;
  TextAttr = Attr;
  SetCurs(XY);

  CursorOn();
*/  
}


void TextBrowseType::PopUp(unsigned short context)
{
}


void TextBrowseType::Done(void)
{
  Frame.Done();
  Menu.Done();
}


void TextBrowseType::Init(uchar x, uchar y, uchar x2, uchar y2, char *Name,
			  char *Title)
{
//  char Name[256], Title[256];

//  strcpy(Name, Name_);
//  strcpy(Title, Title_);
#ifdef DEBUG
  fprintf(stderr,"TextBrowseType.Init()\n");
#endif
    
  strcpy(FileName, Name);

  if (x == y && x == 0)
    {
     Menu.Init(1, 1, pgMenuColor, pgMenuHighColor, pgMenuDisplayColor, 0,
	       " ~File  @........................@    FilePos: ~~@.....@  ");
     Menu.Coord.x2 = x2 + 1;

     Frame.Init(x + 1, y + 2, x2 + 1, y2, 
                 pgFrameColor, pgFrameHighColor, pgFrameDisplayColor, 0, Title);
     return;
    }

  Menu.Init(x, y, pgMenuColor, pgMenuHighColor, pgMenuDisplayColor, 0,
	    " ~File  @........................@    FilePos: ~~@.....@  ");

  Frame.Init(x + 1, y + 2, x2, y2, 
                 pgFrameColor, pgFrameHighColor, pgFrameDisplayColor, 8, Title);
                 
  Menu.Coord.x2 = x2 + 1;
}




void _TMenu_init(void)
{
  static int _was_initialized = 0;
  if (_was_initialized++)
    return;
}

//das ist murks

// p2c: /var/home/pantec/src/turbo/tmenu/tmenu.p, line 1656: 
// * Warning: Junk at end of input file ignored [277] 
// p2c: Note: Remember to call _TMenu_init() in main program [215]







// End.
