/*******************************************************************************

  Copyright(c) 2003-2004 Aurelien Reynaud.

  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., 59
  Temple Place - Suite 330, Boston, MA  02111-1307, USA.

  The full GNU General Public License is included in this distribution in the
  file called COPYING.

*******************************************************************************/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ggiterm.h"
#include "debug.h"
#include "terminal.h"
#include "history.h"
#include "lowlevel/lowlevel.h"


void scroll_up (int);
#ifdef JUMP_SCROLL
void scroll_up_resync();
extern int scroll_delayed;
#endif

extern int region_bottom;
extern int terminal_width, terminal_height;

int cursor_mode = 0;
int cursor_x, cursor_y;
int autowrap = 1;
int linewrap_pending;


void cursor_set_autowrap ()
{
	autowrap = 1;
}

void cursor_unset_autowrap ()
{
	autowrap = 0;
}

void cursor_move (int x, int y)
{
	debug (DEBUG_FUNCTION, "called with arg (x=%d, y=%d)", x, y);
#ifdef JUMP_SCROLL
	if (y < cursor_y) {
		scroll_up_resync();
	}
#endif
	cursor_x = x;
	cursor_y = y;
	while (cursor_y >= region_bottom) {
		scroll_up (1);
		cursor_y--;
	}
	if (cursor_x < 0) {
		cursor_x = 0;
	}
	linewrap_pending = 0;
	if (autowrap) {
		if (cursor_x > terminal_width-1) {
			cursor_x = terminal_width-1;
			linewrap_pending = 1;
		}
	}
	else {
		if (cursor_x > terminal_width) {
			cursor_x = terminal_width;
		}
	}
	debug (DEBUG_FUNCTION, "Leaving");
}

void cursor_advance ()
{
	debug (DEBUG_FUNCTION, "called with no args");
	cursor_move (cursor_x + 1, cursor_y);
	debug (DEBUG_FUNCTION, "Leaving");
}


void cursor_set_mode (int mask)
{
	cell_t cursor;
	
	debug (DEBUG_FUNCTION, "called with args (mask=0x%X)", mask);
	if ((cursor_mode & mask) == mask)
		return; /* Do nothing if mode is already set */
	cursor_mode |= mask;
	if (cursor_x < terminal_width && cursor_y < terminal_height) {
		cursor = history_get_char (cursor_x, cursor_y);
		if (cursor_mode & (CURSOR_HIDE | CURSOR_INVISIBLE)
#ifdef JUMP_SCROLL
			&& !scroll_delayed
#endif
		) {
			render_write_char (cursor_x, cursor_y,
			                   cursor.charcode,
			                   cursor.fgcolor, cursor.bgcolor,
			                   cursor.mode & MODE_UNDERLINE);
		}
	}
	debug (DEBUG_FUNCTION, "Leaving");
}

void cursor_unset_mode (int mask)
{
	cell_t cursor;
	
	debug (DEBUG_FUNCTION, "called with args (mask=0x%X)", mask);
	if ((cursor_mode & mask) == 0)
		return; /* Do nothing if mode not set */
	cursor_mode &= ~mask;
	if (cursor_x < terminal_width && cursor_y < terminal_height) {
		cursor = history_get_char (cursor_x, cursor_y);
		if (!(cursor_mode & (CURSOR_HIDE | CURSOR_INVISIBLE))
#ifdef JUMP_SCROLL
		    && !scroll_delayed
#endif
		    ) {
			render_write_char(cursor_x, cursor_y,
			                  cursor.charcode,
			                  cursor.bgcolor, cursor.fgcolor,
			                  cursor.mode & MODE_UNDERLINE);
		}
	}
	debug (DEBUG_FUNCTION, "Leaving");
}

void cursor_get_position (int *column, int *line)
{
	debug (DEBUG_FUNCTION, "called with args (*column, *line)");
	*column = cursor_x;
	*line = cursor_y;
	debug (DEBUG_FUNCTION, "Leaving");
}
