/*===========================================================================
  Copyright (C) 1988-2009 European Southern Observatory (ESO)
 
  This program is free software; you can redistribute it and/or 
  modify it under the terms of the GNU General Public License as 
  published by the Free Software Foundation; either version 2 of 
  the License, or (at your option) any later version.
 
  This program 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 General Public License for more details.
 
  You should have received a copy of the GNU General Public 
  License along with this program; if not, write to the Free 
  Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, 
  MA 02139, USA.
 
  Corresponding concerning ESO-MIDAS should be addressed as follows:
	Internet e-mail: midas@eso.org
	Postal address: European Southern Observatory
			Data Management Division 
			Karl-Schwarzschild-Strasse 2
			D 85748 Garching bei Muenchen 
			GERMANY
===========================================================================*/

/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

.TYPE		Module
.IDENTIFICATION tapplic.c
.AUTHOR    	Francois Ochsenbein [ESO-IPG]
.LANGUAGE  	C
.KEYWORDS	Window Management
.ENVIRONMENT	TermWindows
.COMMENTS	This module contains simple application of TermWindows:
\begin{TeX}
\begin{itemize}
\item {\em ta\_yes}	which creates a ``yes/no'' window, and prompts
	for this simple answer.
\item {\em ta\_dummy}	which creates a ``dummy'' window of $1\times 1$
\end{itemize}

\end{TeX}


.VERSION 3.0	20-Jun-1988: Creation
.VERSION 3.1	09-Mar-1990: Added ta_passwd ta_open ta_gets

 090901         last modif
----------------------------------------------------------------------------*/

#define	DEBUG		0	/* For debugging only		*/

#define PM_LEVEL 	LEVEL_TW-1

#include <stesodef.h>
#include <tw.h>
#include <atype.h>
#include <twset.h>


extern int tv_dim(), tv_where(), tv_bell();

extern int tw_fill(), tw_attr(), tw_uattr(), tw_r(), tw_goto(), tw_rule();
extern int tw_st(), tw_uflag(), tw_chars(), tw_copw(), tw_flags();
extern int tw_uw(), tw_write(), tw_il(), tw_clear(), tw_dc();
extern int tw_nl(), tw_upw(), tw_uc(), tw_mvc(), tw_copy();
extern int tw_mrule(), tw_cus(), tw_gc2(), tw_close(), tw_cur();
extern int tw_home(), tw_tra(), tw_wa(), tw_agoto(), tw_mods();

extern int pm_enter(), pm_iexit(), pm_tr2(), pm_ed_i();



/*==========================================================================
 *			ta_dummy
 *==========================================================================*/
WINDOW *ta_dummy()
/*+++
.PURPOSE Create a dummy (1x1) window
.RETURNS The allocated window
.REMARKS 
---*/
{
	WINDOW	*w;

  ENTER("*ta_dummy");

  w = OpenWindow("<dummy>", -1, -1, 1, 1, _NORMAL_, 0, 0);

  EXIT_PTR(WINDOW, w);
}

/*==========================================================================
 *			ta_open
 *==========================================================================*/
WINDOW *ta_open(title, lines, bytes, attr, border, pos_opt)
/*+++
.PURPOSE Create a window, and try to adjust at best ...
.RETURNS The opened window
.REMARKS pos_opt may be _UPLEFT_, _UPRIGHT_, _DOWNLEFT_, _DOWNRIGHT_, _CENTER_,
		or -1 (at current cursor position)
---*/
	char	*title;		/* IN: The title of the window		*/
	int	lines;		/* IN: Number of lines			*/
	int	bytes;		/* IN: Longest column or size		*/
	int	attr;		/* IN: Window attribute			*/
	int	border;		/* IN: Window border options		*/
	int	pos_opt;	/* IN: Positioning option, _UPLEFT_ etc.*/
{
	short	screen_size[2], win_size[2], add_size[2], win_pos[2];
	WINDOW	*w;
	int	options, i;

  ENTER("*ta_open");

  ScreenSize(screen_size); ScreenCursor(win_pos);
  options = border;
  add_size[0] = add_size[1] = 0;	/* Added lines/cols for borders...    */

	/* Look for the longest line */

  win_size[0] = MAX (lines, 1);		/* Required lines	*/
  win_size[1] = MAX (bytes, 1);		/* Required width	*/
  
	/* add_size contains extra space required for edges ...	*/

  if (options & _TITLE_)	add_size[0] += (options & _BORDER_ ? 2 : 1);
  if (options & _BORDER_)
  {	add_size[0] += 2;
  	add_size[1] += (options & _BORDER2_ ? 4 : 2);
  }

	/* Derive geometry of the Window	*/

  i = screen_size[1] - add_size[1];
  if (win_size[1] > i)
  {  	win_size[0] += ((win_size[1]-1)/i);
  	win_size[1] = i;
  }
  win_size[0] += add_size[0];	win_size[1] += add_size[1];

	/* If text too long, suppress options like edges ...		*/

  if (win_size[0] > screen_size[0])	/* Try to diminish the size	*/
  {	if (options & _BORDER_)	
  	{	win_size[0] -= add_size[0];
  		win_size[1] -= add_size[1]; 
  		add_size[0] = (options & _TITLE_ ? 1 : 0);
  		add_size[1] = 0;
  		win_size[0] += add_size[0];
  		options &= ~(_BORDER_|_BORDER2_);
  	}
  }

  if (win_size[0] > screen_size[0])	/* Try to diminish the size	*/
  {	if (options & _TITLE_)	
  	{	win_size[0] -= 1;
  		add_size[0] = 0;
  		options &= ~_TITLE_;
  	}
  }

	/* Find the home position of the window, according to pos_opt	*/

  switch(pos_opt)
  { case _UPLEFT_: 	win_pos[0] = win_pos[1] = 0;			break;
    case _DOWNLEFT_: 	win_pos[0] = screen_size[0] - win_size[0];
    			win_pos[1] = 0;				  	break;
    case _DOWNRIGHT_: 	win_pos[0] = screen_size[0] - win_size[0];
    			win_pos[1] = screen_size[1] - win_size[1];  	break;
    case _UPRIGHT_: 	win_pos[0] = 0;
    			win_pos[1] = screen_size[1] - win_size[1];  	break;
    case _CENTER_:	win_pos[0] = win_pos[1] = 0;
    			win_size[0]= -win_size[0];
    			win_size[1]= -win_size[1];			break;
    default :		/* We try to adjust the new window at the current 
    				cursor position ... */
  	if (add_size[0])
  	{	win_pos[0] -= 1;
		if ((i = add_size[0] - 2) > 0)	win_pos[0] -= i;
  	}
	if (win_pos[0] < 0)	win_pos[0] = 0;

	win_pos[1] += bytes + (add_size[1]/2);	/* Col. position */
	if (win_pos[1] >= screen_size[1])	win_pos[1] = screen_size[1]-1;
	win_pos[1] -= win_size[1];	
	if (win_pos[1] < 0)	win_pos[1] = 0;
  }

  w = OpenWindow(title, win_pos[0], win_pos[1], win_size[0], win_size[1],
  	attr, options, 0);
  
  EXIT_PTR(WINDOW, w);
}

/*==========================================================================
 *			ta_aopen
 *==========================================================================*/
WINDOW *ta_aopen(name, text, bytes, attr, border, pos_opt)
/*+++
.PURPOSE Create a bordered window adjusted to a text
.RETURNS The opened window
.REMARKS To have window positioned at current cursor, use -1 for pos_opt
---*/
	char	*name;		/* IN: The title of the window		*/
	char	*text;		/* IN: The text to diplay in the Window	*/
	int	bytes;		/* IN: Length of text			*/
	int	attr;		/* IN: Window attribute			*/
	int	border;		/* IN: Border option (_BORDER_, etc)	*/
	int	pos_opt;	/* IN: Positioning option, _UPLEFT_ etc.*/
{
	WINDOW	*w;
	char	*p, *pe;
	int	lines, cols, j;

  ENTER("*ta_aopen");

	/* Look for longest line */

  j = cols = 0;		/* Longest line */
  for (lines = 1, p = text, pe = text + bytes; p < pe; p++) {
  	if (*p == '\n') {
  		lines++;
  		cols = MAX(cols, j);
  		j = 0;
  	}
  	else	j++;
  }
  cols = MAX(cols, j);
  cols += 1;		/* To allow a 1-char input */

  if ((w = ta_open(name, lines, cols, attr, border, pos_opt)))
  {
  	Write(w, text, bytes);
  	/* CursorLeft(w, 1);	/. Be sure there is space to get 1 char ... */
  }

  EXIT_PTR(WINDOW, w);
}

/*==========================================================================
 *			ta_yes
 *==========================================================================*/
int ta_yes(prompt, attr, pos_opt)
/*+++
.PURPOSE Create a new window to answer to a specified prompt.
.RETURNS 1 (yes) / 0 (no) / -1 (EOF)
.REMARKS No carriage return required. Case insensitive.
---*/
	char	*prompt;	/* IN: The prompt to answer to	*/
	int	attr;		/* IN: Attribute	*/
	int	pos_opt;	/* IN: Positioning option, _UPLEFT_ etc.*/
{
	int 	l, stat;
	WINDOW	*w;
	TWSAVE	saved;

  ENTER("ta_yes");

  SaveCursor(&saved);
  stat = 0;
  l = strlen(prompt);

  if ((w =  ta_aopen("<yes>", prompt, l+1, _NORMAL_, 
  			_BORDER_|_BORDER2_, pos_opt)))
  {
  	SetPosition(w, l), ClearRight(w);
  	RaiseWindow(w), ActiveWindow(w);
  
  	while(1)
  	{	SetPosition(w, l), ClearRight(w);
		switch (stat = GetKey2(w))
  		{ case 'Y': case 'y':	stat = 1; goto FOUND;
  		  case 'N': case 'n': 	stat = 0; goto FOUND;
  		  case _EOF_:			  goto FOUND;
  		}
		Bell();
  	}
  	FOUND:
  	DestroyWindow(w);
  }

  RestoreCursor(&saved);
  EXIT(stat);
}

/*==========================================================================
 *			ta_passwd
 *==========================================================================*/
int ta_passwd(prompt, buffer, size, pos_opt)
/*+++
.PURPOSE Prompt (in a new window) for a password
.RETURNS OK / EOF / ... (See tv_gets)
.REMARKS 
---*/
	char	*prompt;	/* IN: The prompt, e.g. "Password" 	*/
	char	*buffer;	/* OUT: what's typed by the end-user	*/
	int	size;		/* IN: Size of buffer			*/
	int	pos_opt;	/* IN: Positioning option, _UPLEFT_ etc.*/
{
	int 	stat;
	WINDOW	*w;
	TWSAVE	saved;

  ENTER("ta_passwd");

  SaveCursor(&saved);

  w = ta_open(prompt, 1, size-1, _NORMAL_, _BORDER_|_BORDER2_|_TITLE_, pos_opt);
  
  RaiseWindow(w);	DeactiveWindow(w);

  stat = Gets(w, buffer, size);
  
  DestroyWindow(w);
  RestoreCursor(&saved);
  EXIT(stat);
}

/*==========================================================================
 *			ta_gets
 *==========================================================================*/
int ta_gets(prompt, buffer, size, pos_opt)
/*+++
.PURPOSE Get a text in a newly opened and adjusted window.
.RETURNS OK / EOF / ... (See tv_gets)
.REMARKS 
---*/
	char	*prompt;	/* IN: The prompt, e.g. "Password" 	*/
	char	*buffer;	/* OUT: what's typed by the end-user	*/
	int	size;		/* IN: Size of buffer			*/
	int	pos_opt;	/* IN: Positioning option, _UPLEFT_ etc.*/
{
	int 	stat;
	WINDOW	*w;
	TWSAVE	saved;

  ENTER("ta_gets");

  SaveCursor(&saved);

  w = ta_open(prompt, 1, size, _NORMAL_, _BORDER_|_BORDER2_|_TITLE_, pos_opt);
  
  RaiseWindow(w);	ActiveWindow(w);

  stat = Gets(w, buffer, size);
  
  DestroyWindow(w);
  RestoreCursor(&saved);
  EXIT(stat);
}

/*==========================================================================
 *			ta_prp
 *==========================================================================*/
int ta_prp(buffer, len, attr, pos_opt)
/*+++
.PURPOSE Print a text in a new window, and wait for a single char input.
.RETURNS OK / EOF / ... (See tw_gc2, or GetKey2)
.REMARKS 
---*/
	char	*buffer;	/* OUT: what's typed by the end-user	*/
	int	len;		/* IN: text to display			*/
	int	attr;		/* IN: Attribute of Window		*/
	int	pos_opt;	/* IN: Positioning option, _UPLEFT_ etc.*/
{
	int 	stat = NOK;
	WINDOW	*w;
	TWSAVE	saved;

  ENTER("ta_prp");

  SaveCursor(&saved);

  if ((w = ta_aopen("<ta_prp>", buffer, len, attr, _BORDER_|_BORDER2_, pos_opt)))
  {
  	RaiseWindow(w);
  	stat = GetKey2(w);

  	DestroyWindow(w);
  }  
  RestoreCursor(&saved);

  EXIT(stat);
}

/*=====================================================================*
 *			ta_ret					
 *=====================================================================*/
int ta_ret(attr, pos_opt)
/*+++
.PURPOSE Open a window with "Hit Return" text ...
.RETURNS Key typed (GetKey2)
---*/
	int	attr;		/* IN: Attribute	*/
	int	pos_opt;	/* IN: Positioning option, _UPLEFT_ etc.*/
{
	MID_RSTATIC char text[] = "Hit <Return>... ";

  return ( ta_prp (text, sizeof(text)-1, attr, pos_opt)) ;
}

