/*===========================================================================
  Copyright (C) 1989-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
.NAME		tfshow.c
.AUTHOR		A.Richmond, F. Ochsenbein
.LANGUAGE	C
.CATEGORY	Forms interface.
.COMMENTS	Includes functions to display forms or fields in a form.
.ENVIRONMENT	TermWindows.
.VERSION  1.0	08-Jun-1989: Extracted from Proteus

 090902         last modif
------------------------------------------------------------------------*/

#define	PM_LEVEL	LEVEL_TF

#define  PASCAL_DEF	0	/* Don't include Pascalisation 	*/

#include <stesodef.h>	/* Standard definitions	*/
#include <tform.h>	/* for form values	*/



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 tw_cline(), tw_stopin(), tw_ms2(), tw_wf(), tw_awhere();
extern int tw_getc(), tw_helps(), tw_where(), tw_tr();

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

extern int tff_goto(), tff_convert(), tff_edit(), tff_display();

extern int tf_edit(), tf_active(), tf_oset();


#define FINISH	goto FIN

static	char	blanks[] = "            ";
static	TFIELD	*field;
static	TFORM	*theform;
static 	unsigned short option_raw;

/*======================================================================*/ 
/*		Internal Routine					*/
/*======================================================================*/ 

static int show(string)
/*++++++++++++++
.PURPOSE Display a form field.
.RETURNS OK / NOK (field empty)
.REMARKS If field is too small, the `Rubbish Char' is added.
----------------*/
	char	*string;	/* IN: Text to display		*/
{
	int	len, state_echo, old_pos;
	WINDOW	*w;
	char	saved[2], *asaved;


  asaved = (char *) 0;
  saved[0] = saved[1] = ' ';

  if_not(field->string_size)	return(NOK);
  if(option_raw & _FIELD_RAW)	len = field->string_size - 1;
  else				len = (string ? strlen(string) : 0);

  if (len >= field->string_size)	/* Use '\01' to issue Rubbish */
  {
	asaved = string + field->string_size - 2;
	saved[0] = asaved[0], saved[1] = asaved[1];
	asaved[0] = '\01', asaved[1] = EOS;
  }
  else	saved[0] = EOS;


  if ((ischarField(field)) && (w = field->value.window))
  {  						/* Use Subwindow	*/
  	old_pos = GetPosition(w);
  	state_echo = EchoOff(w);
	ClearWindow(w);
	if (string)
           {
		if (option_raw & _FIELD_RAW) WriteBinary(w, string, len);
		else	Put(w, string);
           }
  	SetPosition(w, old_pos);
  }
  else				/* Use Window		*/
  {
	w = theform->window;
  	old_pos = GetPosition(w);
  	state_echo = EchoOff(w);

	CursorTo (w, field->pos[0], field->pos[1]);
	SetAttr(w, field->attr);

	if (string)	
           {
		if (option_raw & _FIELD_RAW) WriteBinary(w, string, len);
		else	Put(w, string);
           }
	len = field->string_size - 1 - len;	/* Blanks to add */

	while (len > 0)		
	{
		WriteBinary(w, blanks, MIN(len, sizeof(blanks)-1));
		len -= sizeof(blanks) - 1;
	}
  	SetPosition(w, old_pos);
  }

  if (state_echo)	ActiveWindow(w);

	/* Restore the characters replaced by Rubbish */

  if (saved[0])	asaved[0] = saved[0], asaved[1] = saved[1];

  return(OK);
}

/*======================================================================*/ 
/*		Actions on Fields					*/
/*======================================================================*/ 

int tff_clear(form)
/*+++++++++++++
.PURPOSE Clear the current field.
.RETURNS OK.
--------------*/
	TFORM	*form;		/* IN: The Form	concerned */
{
  ENTER("tff_clear");

  option_raw = 0;
  theform = form, field = form->fields + form->ifield;

  EXIT(show(NULL_PTR(char)));
}

/*======================================================================*/ 
int tff_show(form)
/*+++++++++++++
.PURPOSE Display the current field.
.RETURNS OK / NOK (when DUMB = no-echo fields)
--------------*/
	TFORM	*form;		/* IN: The Form	concerned */
{
	int	status;

  ENTER("tff_show");

  theform = form, field = form->fields + form->ifield;

  option_raw = field->options;
  if (field->options & _FIELD_NOECHO)	/* When Field must not be displayed */
  	status = NOK;
  else	status = show(field->string);
		
  EXIT(status);
}

/*=====================================================================*/ 
int tff_nshow (form)
/*+++++++++++++++
.PURPOSE Display the current Note.
.REMARKS A field without note will appear blank.
.RETURNS OK
-----------------*/
	TFORM	*form;		/* IN: The Form	concerned */
{
  ENTER("tff_nshow");
		
  option_raw = 0;
  theform = form, field = form->fields + form->ifield;
		
  EXIT(show(field->note));
}

/*=====================================================================*/ 
int tff_pshow (form)
/*+++++++++++++++
.PURPOSE Display the current Picture.
.REMARKS A field without picture will appear blank.
.RETURNS OK.
-----------------*/
	TFORM	*form;		/* IN: The Form	concerned */
{
  ENTER("tff_pshow");
		
  option_raw = 0;
  theform = form, field = form->fields + form->ifield;
		
  EXIT(show(field->picture));
}

/*=====================================================================*/ 
int tff_dshow (form)
/*+++++++++++++++
.PURPOSE Display the current Data Type of data.
.REMARKS A field without picture will appear blank.
.RETURNS OK
-----------------*/
	TFORM	*form;		/* IN: The Form	concerned */
{
  ENTER("tff_dshow");
		
  option_raw = 0;
  theform = form, field = form->fields + form->ifield;
		
  EXIT(show(field->parm));
}

/*=====================================================================*/ 
int tff_oshow (form, mask, ifset)
/*+++++++++++++++
.PURPOSE Display the current option.
.REMARKS A field without the option will appear blank.
.RETURNS OK
-----------------*/
	TFORM	*form;		/* IN: The Form	concerned */
	int	mask;		/* IN: Mask option selection */
	int	ifset;		/* IN: Display character for present option */
{
	char 	option[2];

  ENTER("tff_oshow");
  
  option_raw = 0;
  theform = form, field = form->fields + form->ifield;
  option[0] = (field->options&mask ? ifset : ' ');
  option[1] = EOS;
		
  EXIT(show(option));
}

/*=====================================================================*/ 
int tff_display(form, string)
/*++++++++++++++
.PURPOSE Display supplied string within the current field.
.RETURNS OK.
---------------*/
	TFORM	*form;		/* IN: The Form	concerned */
	char	*string;	/* IN: Text to display	*/
{
  ENTER("tff_display");

  option_raw = 0;
  theform = form, field = form->fields + form->ifield;

  EXIT(show(string));
}

/*======================================================================*/ 
/*		Actions on Forms					*/
/*======================================================================*/ 

int tf_clear(form)
/*+++++++++++++
.PURPOSE Clear the complete Form.
.RETURNS OK.
--------------*/
	TFORM	*form;		/* IN: The Form	concerned */
{
	int	i, state_echo;

  ENTER("tf_clear");

  theform = form;
  state_echo = EchoOff(form->window);

  option_raw = 0;
  for (i = form->nfields, field = form->fields; --i >= 0; field++)
  	show(NULL_PTR(char));

  tff_goto (form, form->ifield);
  if (state_echo)	ActiveWindow(form->window);

  EXIT (OK);
}

/*======================================================================*/ 
int tf_update(form)
/*++++++++++++++
.PURPOSE Rewrite onto Form the modified fields.
.REMARKS Numbers are not edited.
.RETURNS OK.
----------------*/
	TFORM	*form;	/* IN: The form concerned	*/
{
	int	i, state_echo;
	char	*p;
	
  ENTER("tf_update");

  theform = form;

  if (form->compute_fct)  		/* Derive Computed Fields */
  {	(*form->compute_fct)(form);
					/* Flag DUMB fields as modified */
  	for (i = form->nfields, field = form->fields; --i >= 0; field++)
  	{	if (field->options & (_FIELD_DISPLAY|_FIELD_COMPUTED))
  			field->options |= _FIELD_MODIFIED;
	}
  }

	/* Edit MODIFIED fields */
	
  tf_edit(form);
  
  	/* Write the fields onto Window	*/

  if_not(form->options & _FORM_TOSCREEN)	FINISH;
  
  state_echo = tf_active(form, 0);
  for (i = form->nfields, field = form->fields; --i >= 0; field++)
  {
	if_not(field->options & (_FIELD_DISPLAY|_FIELD_COMPUTED))
			continue;
	p = NULL_PTR(char);
	if (field->options & _FIELD_NOECHO)	;
	else if (field->options & _FIELD_TOSCREEN)	p = field->string;
  	option_raw = field->options;
	show(p);
	field->options &= ~_FIELD_MODIFIED;
  }
  tff_goto (form, form->ifield);
  tf_active(form, state_echo);

  FIN:
  EXIT (OK);
}

/*======================================================================*/ 
int tf_show(form)
/*+++++++++++++
.PURPOSE Show a complete Form: edit the fields, show them ... 
.REMARKS 
.RETURNS OK.
--------------*/
	TFORM	*form;		/* IN: The Form	concerned */
{
  ENTER("tf_show");

  tf_oset(form, _FIELD_MODIFIED);	/* All fields are modified... */

  EXIT(tf_update(form));
}

/*=====================================================================*/ 
int tf_nshow (form)
/*+++++++++++++++
.PURPOSE Display all Notes.
.REMARKS When notes are too long, the Rubbish character is added.
.RETURNS OK
-----------------*/
	TFORM	*form;		/* IN: The Form	concerned */
{
	int	i, state_echo;

  ENTER("tf_nshow");
		
  theform = form;
  state_echo = tw_st(form->window, Echo, 0);
  option_raw = 0;
  for (i = form->nfields, field = form->fields; --i >= 0; field++)
	show(field->note);
  tff_goto (form, form->ifield);
  TouchWindow(form->window);
  tw_st(form->window, Echo, state_echo);
  		
  EXIT(OK);
}

/*=====================================================================*/ 
int tf_pshow (form)
/*+++++++++++++++
.PURPOSE Display the current Picture.
.REMARKS A field without picture will appear blank.
.RETURNS OK
-----------------*/
	TFORM	*form;		/* IN: The Form	concerned */
{
	int	i, state_echo;

  ENTER("tf_pshow");
		
  theform = form;
  state_echo = tw_st(form->window, Echo, 0);
  option_raw = 0;
  for (i = form->nfields, field = form->fields; --i >= 0; field++)
	show(field->picture);
  tff_goto (form, form->ifield);
  TouchWindow(form->window);
  tw_st(form->window, Echo, state_echo);
		
  EXIT(OK);
}

/*=====================================================================*/ 
int tf_dshow (form)
/*+++++++++++++++
.PURPOSE Display the Types of the data.
.REMARKS A field without picture will appear blank.
.RETURNS OK
-----------------*/
	TFORM	*form;		/* IN: The Form	concerned */
{
	int	i, state_echo;

  ENTER("tf_dshow");
		
  theform = form;
  state_echo = tw_st(form->window, Echo, 0);
  option_raw = 0;
  for (i = form->nfields, field = form->fields; --i >= 0; field++)
	show(field->parm);
  tff_goto (form, form->ifield);
  TouchWindow(form->window);
  tw_st(form->window, Echo, state_echo);
		
  EXIT(OK);
}

/*=====================================================================*/ 
int tf_oshow (form, mask, ifset)
/*+++++++++++++++
.PURPOSE Display the status of the selected option.
.REMARKS A field without the option will appear blank.
.RETURNS OK
-----------------*/
	TFORM	*form;		/* IN: The Form	concerned */
	int	mask;		/* IN: Mask option selection */
	int	ifset;		/* IN: Display character for present option */
{
	char 	option[2];
	int	i, state_echo;

  ENTER("tf_oshow");
  
  theform = form;
  option_raw = 0;
  option[1] = EOS;
  state_echo = tw_st(form->window, Echo, 0);

  for (i = form->nfields, field = form->fields; --i >= 0; field++)
  {
	option[0] = (field->options&mask ? ifset : ' ');
	show(option);
  }
  tff_goto (form, form->ifield);
  TouchWindow(form->window);
  tw_st(form->window, Echo, state_echo);
		
  EXIT(OK);
}

