/**************************************************************
 *
 *	CRISP - Custom Reduced Instruction Set Programmers Editor
 *
 *	(C) Paul Fox, 1989
 *
 *    Please See COPYRIGHT notice.
 *
 **************************************************************/
#include        "list.h"

void	prev_char();

void
beginning_of_line()
{
	u_dot();
	*cur_col = 1;
	win_modify(WFMOVE);
}

/*
 * Go to end of line.
 */
void
end_of_line()
{	register LINE *lp = linep(*cur_line);
	u_dot();

	*cur_col  = current_col(llength(lp));
	win_modify(WFMOVE);
}
void
next_char()
{	int	n = argv[1].l_flags == F_INT ? argv[1].l_int : 1;
	int	crlf = (curbp->b_flag & BFBINARY) == 0;
	int	last_line;
	
	if (n < 0) {
		argv[1].l_int = -n;
		prev_char();
		return;
		}
	u_dot();
	win_modify(WFMOVE);
	last_line = numlines();
	while (n > 0 && *cur_line <= last_line) {
		LINE	*lp = linep(*cur_line);
		int offset = current_offset(*cur_col, FALSE);

		if (n + offset <= llength(lp)) {
			/***********************************************/
			/*   If  at  end  of  a  binary line, skip to  */
			/*   start of next line.		       */
			/***********************************************/
			if (crlf == 0 && n + offset == llength(lp)) {
				*cur_col = 1;
				(*cur_line)++;
				}
			else
				*cur_col = current_col(offset + n);
			break;
			}
		n -= llength(lp) - offset + crlf;
		*cur_col = 1;
		(*cur_line)++;
		}
	win_modify(WFMOVE);
	acc_assign_int(1L);
	return;
}
void
prev_char()
{	int	offset;
	LINE	*lp;
	int	n = argv[1].l_flags == F_INT ? argv[1].l_int : 1;
	int	crlf = (curbp->b_flag & BFBINARY) == 0;

	if (n < 0) {
		argv[1].l_int = -n;
		next_char();
		return;
		}		
	if (*cur_col == 1 && *cur_line == 1) {
		acc_assign_int(0L);
		return;
		}

	offset = current_offset(*cur_col, FALSE);
	u_dot();
	win_modify(WFMOVE);
	while (n > 0) {
		if (offset > n) {
			offset -= n;
			n = 0;
			}
		else if (offset) {
			n -= offset;
			offset = 0;
			}
		else {
			if (*cur_line == 1)
				break;
			(*cur_line)--;
			lp = linep(*cur_line);
			offset = lp->l_used;
			n -= crlf;
			}
		}
	acc_assign_int(1L);
	win_modify(WFMOVE);
	*cur_col = current_col(offset);
	return;
}

int
forwchar(n)
int	n;
{	int	col = *cur_col;

	u_dot();
	*cur_col += n;
	if (*cur_col < 1)
		*cur_col = 1;
	if (col != *cur_col) {
		acc_assign_int(1L);
		win_modify(WFMOVE);
		}
	else
		acc_assign_int(0L);
	return 0;
}
void
backchar(n)
int	n;
{
	u_dot();
	win_modify(WFMOVE);
	if (*cur_col == 1 && *cur_line > 1) {
		(*cur_line)--;
		end_of_line();
		return;
		}
	forwchar(-n);
}


void
gotobob()
{
	u_dot();
	win_modify(WFMOVE);
	*cur_col = *cur_line = 1;
	win_modify(WFMOVE);
}
void
gotoeob()
{

	u_dot();
	win_modify(WFMOVE);
	*cur_line = curbp->b_numlines;
	if (*cur_line > 1)
		(*cur_line)--;
	end_of_line();
}
void
forwline(n) 
int	n;
{
	int	old_line = *cur_line;

	u_dot();
	win_modify(WFMOVE);
	*cur_line += n;
	check_bounds();
	acc_assign_int((long) (*cur_line != old_line));
	win_modify(WFMOVE);
}
void
backline(n) 
int	n;
{
	forwline(-n);
}
int
numlines()
{
	return curbp->b_numlines + nrow - 3;
}
void
page_down()
{
	forwline(curwp->w_h);
}
void
page_up()
{
	backline(curwp->w_h);
}
void
gotoline(n) 
int	n;
{

	u_dot();
	win_modify(WFMOVE);

	*cur_col = 1;
	*cur_line = 1;
	forwline(n - 1);
}
void
dist_to_tab()
{
	acc_assign_int((long) (next_tab_stop(*cur_col) - *cur_col + 1));
}
void
key_down()
{
	forwline(argv[1].l_flags == F_INT ? argv[1].l_int : 1);
}
void
key_left()
{
	backchar(argv[1].l_flags == F_INT ? argv[1].l_int : 1);
}
void
key_right()
{
	forwchar(argv[1].l_flags == F_INT ? argv[1].l_int : 1);
}
void
key_up()
{
	backline(argv[1].l_flags == F_INT ? argv[1].l_int : 1);
}

