/* W7.C		More cursor movement				01 Nov 1987 */

#include <ws.h>


FLAG page_up()		/* goes to preceding page			*/
			/* returns FALSE since no text change		*/
{
	extern unsigned	pt_line;	/* page top line		*/
	extern INDEX	pt_index;	/* page top index		*/
	extern INDEX	index;		/* current text position	*/

	unsigned	min();		/* minimum of two int's		*/
	INDEX		above();	/* index above current position	*/
	void		f_pbottom();	/* find page bottom		*/
	void		rest_page();	/* display rest of page		*/
	void		set_xy();	/* sets cursor coordinates	*/

	static unsigned	d;

	d = min(pt_line, PAGE_LENGTH) - 1;
	if (d>0) {
		pt_line -= d;
		index = above(index,d);
		pt_index = above(pt_index,d);
		f_pbottom();
		rest_page(pt_index);
	} else
		index = above(index,line(index)-1);
	set_xy();
	return FALSE;
}


FLAG page_down()	/* goes to next page				*/
			/* returns FALSE since no text change		*/
{
	extern unsigned	n_lines;	/* no. of text lines		*/
	extern unsigned	pt_line;	/* page top line		*/
	extern INDEX	pt_index;	/* page top index		*/
	extern INDEX	index;		/* current text position	*/

	unsigned	min();		/* minimum of two int's		*/
	INDEX		below();	/* index below current position	*/
	void		f_pbottom();	/* finds page bottom		*/
	void		rest_page();	/* displays rest of page	*/
	void		set_xy();	/* sets cursor coordinates	*/

	static unsigned	d;

	if ((d = min(n_lines-pt_line, PAGE_LENGTH) - 1) == 0) return FALSE;
	index = below(index,d);
	pt_line += d;
	pt_index = below(pt_index,d);
	f_pbottom();
	rest_page(pt_index);
	set_xy();
	return FALSE;
}


FLAG scr_up()		/* scrolls page up one line			*/
			/* returns FALSE since no text change		*/
{
	extern INDEX	index;		/* current text position	*/
	extern unsigned pt_line;	/* page top line		*/

	FLAG		up_scroll();	/* scrolls page up		*/
	unsigned	line();		/* current text line		*/
	FLAG		line_down();	/* goes to next line		*/
	void		set_xy();	/* sets cursor coordinates	*/

	if (up_scroll(1) && line(index)<pt_line)
		line_down();
	else
		set_xy();
	return FALSE;
}


FLAG scr_down()		/* scrolls page down one line			*/
			/* returns FALSE since no text change		*/
{
	extern INDEX	index;		/* current text position	*/
	extern unsigned pb_line;	/* page bottom line		*/

	FLAG		down_scroll();	/* scrolls page down		*/
	unsigned	line();		/* current text line		*/
	FLAG		line_up();	/* goes to preceding line	*/
	void		set_xy();	/* sets cursor coordinates	*/

	if (down_scroll(1) && line(index)>pb_line)
		line_up();
	else
		set_xy();
	return FALSE;
}


FLAG up_scroll(n)	/* scrolls text page up n lines			*/
unsigned n;		/* returns FALSE iff at end of text		*/
{
	extern unsigned	n_lines;		/* no. of text lines	     */
	extern unsigned	pt_line, pb_line;	/* page top, bottom line     */
	extern INDEX	pt_index, pb_index;	/* page top, bottom index    */

	unsigned	min();			/* minimum of two int's	     */
	INDEX		eol_index();		/* index at end of line	     */
	void		f_pbottom();		/* finds page bottom	     */
	void		CursorTo();		/* positions cursor on screen*/
	void		DelLine();		/* deletes (removes) a line  */
	INDEX		rest_line();		/* displays rest of line     */

	static unsigned	i;

	if ( (i=min(n, n_lines-pt_line)) <= 0) return FALSE;
	while (i--) {
		pt_line++;
		pt_index = eol_index(pt_index) + 1;
		f_pbottom();
		CursorTo(LEFT_SCREEN,TOP_SCREEN);
		DelLine();
		if (pb_line-pt_line+1==PAGE_LENGTH) {
			CursorTo(LEFT_SCREEN,BOTTOM_SCREEN);
			rest_line(pb_index);		/* never mind value */
		}
	}
	return TRUE;
}


FLAG down_scroll(n)	/* scrolls text page down n lines		*/
unsigned n;		/* returns FALSE iff at begin of text		*/
{
	extern unsigned pt_line, pb_line;	/* page top, bottom line     */
	extern INDEX	pt_index, pb_index;	/* page top, bottom index    */

	unsigned	min();			/* minimum of two int's      */
	void		f_pb_line();		/* finds page bottom line    */
	void		CursorTo();		/* positions cursor on screen*/
	INDEX		bol_index();		/* index at begin of line    */
	void		f_pb_index();		/* finds page bottom index   */
	void		InsLine();		/* inserts a line	     */
	INDEX		rest_line();		/* displays rest of line     */

	static unsigned	i;

	if ( (i=min(n, pt_line-1)) <= 0) return FALSE;
	CursorTo(LEFT_SCREEN,TOP_SCREEN);
	while (i--) {
		pt_line--;
		f_pb_line();
		pt_index = bol_index(pt_index-1);
		f_pb_index();
		InsLine();
		rest_line(pt_index);		/* never mind the value	*/
	}
	return TRUE;
}
