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

  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 "lowlevel/lowlevel.h"
#include "history.h"
#include "terminal.h"


extern int terminal_height;
extern int blinking_state;
#ifdef JUMP_SCROLL
extern int scroll_delayed;
#endif

wchar_t altchar_get(wchar_t);

extern int linewrap_pending;
extern int cursor_x, cursor_y;
void cursor_advance ();
void cursor_move (int, int);


wchar_t last_char;
int mode = 0;
int fgcolor, bgcolor;


void text_set_mode (int mask)
{
	debug (DEBUG_FUNCTION, "called with no args");
	mode |= mask;
	debug (DEBUG_FUNCTION, "Leaving");
}

void text_unset_mode (int mask)
{
	debug (DEBUG_FUNCTION, "called with no args");
	mode &= ~mask;
	debug (DEBUG_FUNCTION, "Leaving");
}

void text_set_bgcolor (unsigned int color)
{
	debug (DEBUG_FUNCTION, "called with no args");
	bgcolor = color == 9 ? default_bgcolor : color;
	debug (DEBUG_FUNCTION, "Leaving");
}

void text_set_fgcolor (unsigned int color)
{
	debug (DEBUG_FUNCTION, "called with no args");
	fgcolor = color == 9 ? default_fgcolor : color;
	debug (DEBUG_FUNCTION, "Leaving");
}

void text_write_char (wchar_t charcode)
{
	cell_t current_char;
	int dummy_color;
	
	debug (DEBUG_FUNCTION, "called with args (charcode=0x%X)", (int)charcode);

	if (linewrap_pending) {
		cursor_move (0, cursor_y + 1);
	}
	last_char = charcode;

	if (mode & MODE_ALTCHARSET) {
		current_char.charcode = altchar_get(charcode);
	} else {
		current_char.charcode = charcode;
	}
	if (mode & MODE_REVERSE) {
		current_char.bgcolor = fgcolor;
		current_char.fgcolor = bgcolor;
	} else {
		current_char.fgcolor = fgcolor;
		current_char.bgcolor = bgcolor;
	}
	if (mode & MODE_BOLD) {
		current_char.fgcolor += 8;
	}
	if (mode & MODE_INVISIBLE) {
		/*current_char.fgcolor = current_char.bgcolor;*/
		current_char.charcode = 32;
	}
	/*current_char.mode = mode & (MODE_UNDERLINE | MODE_BLINK);*/
	current_char.mode = mode;
	history_write_char (cursor_x, cursor_y, current_char);
	
	if ((current_char.mode & MODE_BLINK) && !blinking_state) {
		dummy_color = current_char.bgcolor;
		current_char.bgcolor = current_char.fgcolor;
		current_char.fgcolor = dummy_color;
	}
#ifdef JUMP_SCROLL
	if (!scroll_delayed) {
		render_write_char (cursor_x, cursor_y,
		                   current_char.charcode,
		                   current_char.fgcolor, current_char.bgcolor,
		                   current_char.mode & MODE_UNDERLINE);
	}
#else
	render_write_char (cursor_x, cursor_y,
	                   current_char.charcode,
	                   current_char.fgcolor, current_char.bgcolor,
	                   current_char.mode & MODE_UNDERLINE);
#endif
	cursor_advance ();
	debug (DEBUG_FUNCTION, "Leaving");
}

/* Repeat last character count times */
void text_repeat_char (unsigned int count)
{
	debug (DEBUG_FUNCTION, "called with args (count=%d)", count);
	while (count) {
		text_write_char (last_char);
		count--;
	}
	debug (DEBUG_FUNCTION, "Leaving");
}

void text_write_area (int x, int y, int w, int h)
{
	int i, j, length, has_blink;
	cell_t dummy;
	int dummy_color;
	cell_t *line_p;
	
	debug (DEBUG_FUNCTION, "called with args (x=%d, y=%d, w=%d, h=%d)", x, y, w, h);
	for (j=y; j<(y+h<terminal_height?y+h:terminal_height); j++) {
		history_get_line(j, &line_p, &length, &has_blink);
		for (i=x; i<(length<x+w?length:x+w); i++) {
			dummy = line_p[i];
			if ((dummy.mode & MODE_BLINK) && !blinking_state) {
				dummy_color = dummy.bgcolor;
				dummy.bgcolor = dummy.fgcolor;
				dummy.fgcolor = dummy_color;
			}
#ifdef JUMP_SCROLL
			if (!scroll_delayed) {
				render_write_char (i, j,
				                   dummy.charcode,
				                   dummy.fgcolor, dummy.bgcolor,
				                   dummy.mode & MODE_UNDERLINE);
			}
#else
			render_write_char (i, j,
			                   dummy.charcode,
			                   dummy.fgcolor, dummy.bgcolor,
			                   dummy.mode & MODE_UNDERLINE);
#endif
		}
		render_erase_chars (i, j, x + w - i);
	}
	debug (DEBUG_FUNCTION, "Leaving");
}
