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

int	start_line, start_col;
int	end_line, end_col;
int	mark_type;
extern	int	display_ctrl;

void
drop_anchor()
{
	ANCHOR	*ap = (ANCHOR *) chk_alloc(sizeof (ANCHOR));
	int	previous_anchor = curbp->b_alist != NULL;

	u_raise();
	ap->a_line = *cur_line;
	ap->a_offset = *cur_col;
	ap->a_type = argv[1].l_flags == F_NULL ? 
			(u_int16) MK_NORMAL : 
			(u_int16) (argv[1].l_int & 0xffff);
	ll_push(curbp->b_alist, (char *) ap);
	curbp->b_anchor = ap;
	win_modify(previous_anchor ? WFHARD : WFMOVE);
}
void
raise_anchor()
{
	acc_assign_int(0L);
	if (curbp->b_anchor == NULL)
		return;
	u_drop();
	acc_assign_int(1L);
	if (ll_pop(curbp->b_alist))
		curbp->b_anchor = (ANCHOR *) ll_elem(ll_first(curbp->b_alist));
	else
		curbp->b_anchor = NULL;
	win_modify(WFHARD);
}
void
mark()
{
	if (curbp->b_anchor)
		raise_anchor();
	else
		drop_anchor();
}
void
write_block()
{	char 	*cp;
	FILE	*fp;
	char	buf[BUFSIZ];
	int	pipe_open;
	char	*open_mode = argv[2].l_int == 0 ? "w" : "a";
	char	*mem = NULL;
	int	pipe_msg = argv[4].l_flags == F_NULL ? TRUE : (int) argv[4].l_int;
	
	acc_assign_int(0L);
	if (check_mark())
		return;

	/***********************************************/
	/*   Dont  need  to  worry about screen being  */
	/*   screwed   up   if  we're  running  on  a  */
	/*   windowing system.			       */
	/***********************************************/
	if (display_ctrl & DC_WINDOW)
		pipe_msg = FALSE;
	cp = get_arg1("Write marked area as: ", buf, sizeof buf);
	if (cp == NULL)
		return;
	/***********************************************/
	/*   If  first  1  or  two characters are the  */
	/*   '>'  or  '>>'  characters  then override  */
	/*   the  argv[2]  parameter allowing user to  */
	/*   select the append mode.		       */
	/***********************************************/
	if (*cp == '>') {
		open_mode = "a";
		if (*++cp == '>')
			cp++;
		}
	/***********************************************/
	/*   If  first  character  of  file name is a  */
	/*   pipe  symbol,  then  open  up  a pipe to  */
	/*   write  the  data.  This allows people to  */
	/*   send things to the print spooler.	       */
	/***********************************************/
	if (*cp == '|') {
		pipe_open = TRUE;
		fp = popen(cp + 1, open_mode);
		/***********************************************/
		/*   User  may  want  to see stdio and stderr  */
		/*   output  from  command  so  put  terminal  */
		/*   back into normal non-raw mode.	       */
		/***********************************************/
		if (fp != NULL && pipe_msg)
			get_ready_to_stop(TRUE);
		}
	else {
		pipe_open = FALSE;
		cp = expand_filename(cp);
		fp = fopen(cp, open_mode);
		}
	if (fp == NULL) {
		ewprintf("Write failed.");
		acc_assign_int(-1L);
		if (mem)
			chk_free((void *) mem);
		return;
		}
	copyregion(fp, pipe_open ? (char *) NULL : "Writing", FALSE);
	if (pipe_open) {
		pclose(fp);
		if (pipe_msg) {
			write(1, "Press any <Enter> to continue: ", 30);
			read(0, buf, sizeof buf);
			resume_after_stopping(TRUE);
			}
		}
	else {
		fclose(fp);
		infof("Write successful.");
		}
	/***********************************************/
	/*   Allow   user   to   keep  the  hilighted  */
	/*   region if the 3rd argument is specified.  */
	/***********************************************/
	if (argv[3].l_int == 0)
		raise_anchor();
	acc_assign_int(1L);
	if (mem)
		chk_free((void *) mem);
	
}
void
inq_marked()
{
	if (get_marked_areas((WINDOW *) NULL)) {
		acc_assign_int((long) mark_type);
		argv_assign(1, (long) start_line);
		argv_assign(2, (long) start_col);
		argv_assign(3, (long) end_line);
		if (argv[4].l_flags != F_NULL) {
			if (mark_type == MK_LINE)
				end_col = get_longest_line();
			int_assign(argv[4].l_sym, (long) end_col);
			}
		}
	else
		acc_assign_int(0L);
}
int
get_longest_line()
{
	int ln = start_line;
	int max_ecol = 0;
	int old_cur_line = *cur_line;
	int	col;

	while (ln <= end_line) {
		LINE *lp = linep(ln);
		*cur_line = ln++;
		col = current_col((int) llength(lp));
		if (col > max_ecol)
			max_ecol = col;
		}
	*cur_line = old_cur_line;
	return max_ecol;
}
void
swap_anchor()
{
	int	col = *cur_col;

	if (curbp->b_anchor) {
		*cur_line = curbp->b_anchor->a_line;
		curbp->b_anchor->a_line = *cur_line;
		*cur_col = curbp->b_anchor->a_offset;
		curbp->b_anchor->a_offset = col;
		}
}
int
get_marked_areas(wp)
WINDOW	*wp;
{	ANCHOR	*ap;
	int	tmpl;

	if (wp == NULL)
		ap = curbp->b_anchor;
	else
		ap = wp->w_bufp->b_anchor;
	if (ap == NULL) {
		start_line = *cur_line;
		end_line = curbp->b_numlines;
		return FALSE;
		}
	mark_type = ap->a_type;
	start_line = ap->a_line;
	start_col = ap->a_offset;
	end_line = wp ? wp->w_line : *cur_line;
	end_col = wp ? wp->w_col : *cur_col;

	if (mark_type == MK_COLUMN) {
		if (start_line > end_line)
			SWAP(start_line, end_line, tmpl);
		if (start_col > end_col)
			SWAP(start_col, end_col, tmpl);
		return TRUE;
		}
	if (start_line > end_line) {
		SWAP(start_line, end_line, tmpl);	
		SWAP(start_col, end_col, tmpl);
		}
	if (start_line == end_line && start_col > end_col)
		SWAP(start_col, end_col, tmpl);
	if (mark_type == MK_LINE) {
		end_col = 32767;
		start_col = 1;
		}
	else if (mark_type == MK_NONINC)
		end_col--;
	return TRUE;
}
