/*===========================================================================
  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 twindel.c
.AUTHOR    	Francois Ochsenbein [ESO-IPG]
.LANGUAGE  	C
.KEYWORDS	Window Management
.ENVIRONMENT 	TermWindows
.COMMENTS	This module includes functions to insert or delete lines/chars.
\begin{TeX}
\end{TeX}
.VERSION  1.0	29-Aug-1986:	Creation

.VERSION  2.0	03-Dec-1986	New terminal-independant graphic characters
			with output buffering version.
.VERSION  2.1	29-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 tw_st(), tw_goto(), tw_chars(), tw_fill(), tw_r(), tw_copw();
extern int tv_buffer();

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



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

MID_STATIC int chars[2] = {0, 0};
static int J;

	MONITOR(TWINDEL);


/*======================================================================
 *			tw_dc
 *======================================================================*/
int tw_dc(w, nchar)
/*+++
.PURPOSE Delete n chars on a specified window, pushing characters to the
	left.
.RETURNS OK / NOK (Not all characters deleted)
.REMARKS A negative number of times asks to delete chars at the left of
	the cursor ( the cursor moves in this case).
	The hardware `delete char' capability is not used.
	Deleting is limited witin markers.
---*/
	WINDOW	*w;		/* MOD: The window concerned	*/
	int nchar;	/* IN: Number of chars to delete	*/
{
	register int 	n, d;

  ENTER_TWA("tw_dc");

  DISPLAY(0);
#if DEBUG
  TRACE_ED_STR2("Deleting Chars on Window: ", w->id, 8);
  TRACE_ED_I("Chars: ", nchar);
#endif

  n = nchar;
  tw_chars(w, chars);

  if (n < 0)
  {	n = -n;
	if (n > chars[0])	n = chars[0], status = NOK;
	w->pos -= n;
	tw_chars(w, chars);
  }
  else	if (n > chars[1])
  	n = chars[1], status = NOK;

  if (n == 0)	 	Return;

	/* Copy the chars which are kept 		*/

  d = w->pos;
  d = tw_copw(w, d, w, d+n, chars[1] - n);

	/* Fill with blanks the rest of the line(s) 	*/

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

  DISPLAY(0);

  EXIT_TWA(status);
}

/*==========================================================================
 *			tw_dl
 *==========================================================================*/
int	tw_dl(w, lines)
/*+++
.PURPOSE Delete lines (moving up lines below) on a window,
	including the current line
.RETURNS OK / NOK (not all lines deleted)
.REMARKS On return, the cursor is at the beginning of the current line.
	If lines<0, lines on top of the current line are deleted.
---*/
	WINDOW	*w;	/* MOD: The window concerned			*/
	int lines;	/* IN: Upper line of the scrolling region	*/
{
	int i, n, L;

  ENTER_TWA("tw_dl");

  TRACE_ED_I("Delete Lines: ", lines);

  n = lines, J = w->Nj, i = w->pos/J;

  if ( (i + n) < 0)		n = -i, status = NOK;

  if ( (i + n) >= w->Ni)	n = w->Ni - i, status = NOK;

  if (n == 0)	 	Return;

  if (n < 0)		i += n;
  w->pos = i * J;
  if (n == 0) FINISH;		/* The move to the line beginning is done */

  n = ABSOLUTE(n);		/* Number of deleted lines	*/

	/* Update in Memory: First copy moved lines	*/

  L = (w->Ni - n) * J - w->pos;	/* Chars to copy	*/
  L = tw_copw(w, w->pos, w, w->pos + n*J, L);
  DISPLAY(0);

	/* ... and clear bottom lines			*/
  tw_fill(w, L, n*J, w->attr_init);

  DISPLAY(0);

  EXIT_TWA(status);
}

/*==========================================================================
 *			tw_il
 *==========================================================================*/
int	tw_il(w, lines)
/*+++
.PURPOSE Insert blank lines (moving down lines below) on a window.
.RETURNS OK
.REMARKS On return, the cursor is at the beginning of the current (blank) line.
	If lines<0, lines are inserted on top of the current line.
---*/
	WINDOW	*w;		/* MOD: The window concerned	*/
	int lines;		/* IN: Upper line of the scrolling region	*/
{
	int 	i, n, L;

  ENTER_TWA("tw_il");

  TRACE_ED_I("Insert lines: ", lines);

  J = w->Nj, i = w->pos/J;

  if (lines < 0) 	tw_goto(w, i + lines, 0), n = -lines;
  else 			tw_goto(w, i, 0), n = lines;

  if (n == 0) 	Return;		/* The move to the line beginning is done */

  if ( (n + i) > w->Ni)		n = w->Ni - i;

	/* Update in Memory: First copy moved lines	*/

  L = (w->Ni - n) * J - w->pos;	/* Chars to copy	*/
  tw_copw(w, w->pos + n*J, w, w->pos, L);

	/* ... and clear lines				*/
  tw_fill(w, w->pos, n*J, w->attr_init);

  DISPLAY(2);

  EXIT_TWA(status);
}

