/* W3.C		Cursor movement; Index localization		01 Nov 1987 */

#include <ws.h>

FLAG to_t_begin()		/* sets index to begin of text		*/
				/* returns FALSE since no text change	*/
{
	extern INDEX	t_begin;	/* text begin			*/
	extern INDEX	index;		/* current text position	*/
	extern INDEX	pt_index;	/* page top index		*/
	extern unsigned pt_line;	/* page top line		*/

	unsigned	line();		/* line of index		*/
	void		f_pbottom();	/* find page bottom		*/
	void		rest_page();	/* display rest page		*/
	void		set_xy();	/* sets screen cursor coord	*/
	void		to_xy();	/* positions cursor on screen	*/

	index = t_begin;
	if (pt_index != t_begin) {
		pt_index = t_begin;
		pt_line = line(pt_index);
		f_pbottom();
		rest_page(index);
	}
	set_xy();
	to_xy();
	return FALSE;
}


FLAG to_t_end()			/* sets index to end of text		*/
				/* returns FALSE since no text change	*/
{
	extern INDEX	t_end;		/* text end			*/
	extern INDEX	index;		/* current text position	*/
	extern INDEX	pt_index;	/* page top index		*/
	extern unsigned pt_line;	/* page top line		*/
	extern unsigned n_lines;	/* no of text lines		*/

	unsigned	max();		/* maximum of two int's		*/
	void		f_pbottom();	/* find page bottom		*/
	INDEX		l_index();	/* index of line		*/
	void		rest_page();	/* display rest page		*/
	void		set_xy();	/* sets screen cursor coords	*/
	void		to_xy();	/* positions cursor on screen	*/

	index = t_end;
	if ( (n_lines-pt_line) >= PAGE_LENGTH) {
		pt_line = max(1, n_lines + 1 - PAGE_LENGTH + 1);
		pt_index = l_index(pt_line);
		f_pbottom();
		rest_page(pt_index);
	}
	set_xy();
	to_xy();
	return FALSE;
}


INDEX above(ind,n)		/* returns index of char which is	*/
INDEX ind;			/*  n lines above char with index ind	*/
unsigned n;
{
	extern INDEX	t_begin;	/* text begin			*/

	unsigned	dx_bol();	/* cursor dist to begin of line	*/
	INDEX		bol_index();	/* index at begin of line	*/
	INDEX		x_right();	/* index of char right on line	*/

	static unsigned	x;

	x = dx_bol(ind);		/* current dist to begin of line */
	while (n--) {
		if ( (ind=bol_index(ind)) == t_begin) break;
		ind--;
	}
	return x_right(bol_index(ind),x);
}


INDEX below(ind,n)		/* returns index of char which is	*/
INDEX ind;			/*  n lines below char with index ind	*/
unsigned n;
{
	extern INDEX	t_end;		/* text begin			*/

	unsigned	dx_bol();	/* cursor dist to begin of line	*/
	INDEX		eol_index();	/* index at begin of line	*/
	INDEX		x_right();	/* index of char right on line	*/

	static unsigned	x;

	x = dx_bol(ind);		/* current dist to begin of line */
	while (n--) {
		if ( (ind=eol_index(ind)) == t_end) break;
		ind++;
	}
	return x_right(ind,x);
}


INDEX x_right(ind,x)		/* returns index of char which has cursor */
INDEX ind;			/* distance x from index ind on same line */
unsigned x;
{
	extern unsigned	t_end;		/* text end			*/

	unsigned	dx_bol();	/* cursor dist to begin of line	*/
	unsigned	ch_exp();	/* expanded char width		*/

	static unsigned	dx;

	if (ind>=t_end) return t_end;
	for (dx=dx_bol(ind); dx<x; ind++) {
		if (!*ind) break;		/* stop at end of line	*/
		if (*ind=='\t')
			while (++dx % TAB_POS) ;
		else
			dx += ch_exp(*ind);
	}
	return ind;
}


void find_page(ind)		/* finds page for index ind		*/
INDEX ind;
{
	extern unsigned	pt_line, pb_line;	/* page top, bottom line */

	unsigned	line();			/* text line of index	*/
	void		flip_page();		/* displays new text page*/

	static unsigned l;

	l = line(ind);
	if (l<pt_line || pb_line<l)
		flip_page(ind);
	return;
}


void flip_page(ind)		/* displays page for index ind		*/
INDEX ind;
{
	extern unsigned pt_line;	/* page top line		*/
	extern INDEX	pt_index;	/* page top index		*/

	unsigned	max();		/* maximum of two int's		*/
	unsigned	line();		/* text line of index		*/
	void		f_pbottom();	/* finds page bottom		*/
	INDEX		l_index();	/* index at begin of line	*/
	void		rest_page();	/* displays rest of page	*/

	pt_line = max(1, line(ind) - PAGE_LENGTH/2);
	pt_index = l_index(pt_line);
	f_pbottom();
	rest_page(pt_index);
	return;
}
