/*===========================================================================
  Copyright (C) 1986-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 twclear.c
.AUTHOR    	Francois Ochsenbein [ESO-IPG]
.LANGUAGE  	C
.KEYWORDS	Window Management
.ENVIRONMENT 	TermWindows
.COMMENTS	This module includes clear functions.
\begin{TeX}
\end{TeX}
.VERSION  1.0	26-Aug-1986:	Creation

.VERSION  2.0	03-Dec-1986	New terminal-independant graphic characters
			with output buffering version.
.VERSION  2.1	25-Jun-1987	Version '2'
.VERSION 3.0	20-Mar-1988: Version '3'

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

#define DEBUG		0	/* Only for debugging	*/

#define PM_LEVEL 	LEVEL_TW

#define  TW_import	0	/* Do not use macro window definitions	*/
#include <twset.h>


extern int tv_buffer(), tv_agoto(), tv_clear();

extern int tw_st(), tw_chars(), tw_fill(), tw_r(), tw_uw(), tw_uc();

extern int pm_enter(), pm_iexit();



MID_EXTERN	WINDOW *Screen;

#if 	DEBUG
#define ed_level	3
#define ENTER_DEBUG(x)	ENTER(x)
#define EXIT_DEBUG(x)	EXIT(x)
#define DISPLAY(opt)	tw_ed(w,opt)
#else
#define DISPLAY(opt)
#define ENTER_DEBUG(x)	
#define EXIT_DEBUG(x)	return(x)
#endif

	MONITOR(TWCLEAR);

/*==========================================================================
 *			tw_cc
 *==========================================================================*/
int	tw_cc(w, nchar)
/*+++
.PURPOSE Clear n chars from the cursor inclusive.
.RETURNS OK / NOK (did not clear all required characters)
.REMARKS The cursor position remains unchanged. Simply write a blank.
	If nchar<0, clear chars at the left of the cursor.
	The `Insert Mode' is turned off.
	Clearing is limited to markers.
---*/
	WINDOW	*w;		/* MOD: The window concerned	*/
	int nchar;		/* IN: Number of chars to clear	*/
{
	register int d, n;
	int 	chars[2];

  ENTER_TWA("tw_cc");

#if DEBUG
  TRACE_ED_STR2("Clearing Chars on:", w->id, 8);
  TRACE_ED_I("... Number of chars: ", nchar);
#endif

  w->flags &= (~Imode);

  if (nchar == 0) 	FINISH;

  n = nchar;
  tw_chars(w, chars);  

  if (n < 0)			/* Clear at Left of Cursor	*/
  { 	n = -n;
	if (n > chars[0])	n = chars[0], status = NOK;
	d = chars[0] - n;
  }
  else
  {	if (n > chars[1])	n = chars[1], status = NOK;
	d = chars[0];
  }

  if (w->flags & FullW)	d += w->marker[0];
  else			d += (w->pos/w->Nj) * w->Nj;

  tw_fill(w, d, n, w->attr_init);

  FINISH;
  EXIT_TWA(status);
}

/*==========================================================================
 *			tw_cl
 *==========================================================================*/
int	tw_cl(w)
/*
.PURPOSE Clear the running line on a window; 
	the cursor is moved to the left margin of the current line.
.RETURNS OK
.REMARKS Does not take markers into account.
	The `Insert Mode' is turned off.
---*/
	WINDOW	*w;		/* MOD: The window concerned	*/
{

  ENTER("tw_cl");
  CheckScreen(w);  

#if DEBUG
  TRACE_ED_STR2("Clearing Line on:", w->id, 8);
#endif

  w->flags &= (~Imode);
  w->pos = (w->pos/w->Nj)*w->Nj;

  EXIT(tw_cc(w, w->Nj));
}

/*==========================================================================
 *			tw_clear
 *==========================================================================*/
int	tw_clear(w, direction)
/*++++++++++++
.PURPOSE Clear the window, according to the specified direction:
\begin{TeX}
\begin{itemize}
\item \_UP\_ : from the top of the screen, to the cursor (inclusive)
\item \_DOWN\_ : from the cursor (inclusive) to the end of the screen
\item \_LEFT\_ : from the left margin of the current line
		to the cursor (inclusive) 
\item \_RIGHT\_ : from the cursor (inclusive) to the end of the line
\item \_WHOLE\_ : the complete screen (the cursor goes to home, \ie [0,0]
			position).
\end{itemize}
\end{TeX}
.RETURNS OK
.REMARKS Insert Mode turned off. Clearing is limitied within markers.
---*/
	WINDOW	*w;		/* MOD: The window concerned	*/
	int	direction; /* IN: Clearing direction _WHOLE_, _UP_, _DOWN_, etc */
{
	unsigned char optimize;
	register int size, j;

  ENTER_TWA("tw_clear");

#if DEBUG
  TRACE_ED_STR2("Clearing Window:", w->id, 8);
  TRACE_ED_I("Direction: ", direction);
#endif

  DISPLAY(0);

  size = w->Ni * w->Nj, j = w->pos % w->Nj;
  optimize = 0;

  switch(direction)
  { default:			/* Whole screen is the default	*/
	w->flags &= (~Imode);
	tw_fill(w, w->marker[0], w->marker[1] - w->marker[0], w->attr_init);
	w->pos = w->marker[0];			/* Cursor at home	*/
	if ( (w->marker[0] == 0) && (w->marker[1] == size))
	{	if (w->attr_init == Screen->attr_init)	w->flags |= Clear;
		optimize = Wl|Wr|Wu|Wd;
	}
	break;

    case _LEFT_:	/* Clear to left margin	*/
	tw_cc(w, -j);
	tw_cc(w, 1 );
	FINISH;

    case _UP_:			/* Clear from top left corner	*/
	w->flags &= (~Imode); 
	tw_fill(w, w->marker[0], w->pos - w->marker[0] + 1, w->attr_init);
	if (w->marker[0] == 0) 	optimize = Wl|Wr|Wu;
	break;
  
    case _RIGHT_:	/* Clear to right margin	*/
	tw_cc(w, w->Nj - j);
	FINISH;

    case _DOWN_:		/* Clear to bottom right corner	*/
	w->flags &= (~Imode);
	tw_fill(w, w->pos, w->marker[1] - w->pos, w->attr_init);
	if (w->marker[1] == size) 	optimize = Wl|Wr|Wu;
	break;
  }
 
  DISPLAY(0);

	/* Optimize for top Window	*/
  if (w->active)
  {	if ( (w == Previous(Screen)) && (w->attr_init == Screen->attr_init) 
		&& ((w->wpos & optimize) == optimize))	/* Optimize	*/
	{	tw_uw(w,0);
		tw_uc(w);
		SetPosition(Screen->pos);
		tv_clear(direction);
	}
	else	tw_rw(w,0,NULL_WINDOW);
  }

  FINISH;
  EXIT_TWA(OK);
}

