/*
 * (C) Copyright 2001-2014
 * DENX Software Engineering -- wd@denx.de
 * Compulab Ltd - http://compulab.co.il/
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <lcd.h>
#include <video_font.h>		/* Get font data, width and height */

#define CONSOLE_ROW_SIZE	(VIDEO_FONT_HEIGHT * lcd_line_length)
#define CONSOLE_ROW_FIRST	lcd_console_address
#define CONSOLE_SIZE		(CONSOLE_ROW_SIZE * console_rows)

static short console_curr_col;
static short console_curr_row;
static short console_cols;
static short console_rows;
static void *lcd_console_address;

void lcd_init_console(void *address, int rows, int cols)
{
	console_curr_col = 0;
	console_curr_row = 0;
	console_cols = cols;
	console_rows = rows;
	lcd_console_address = address;
}

void lcd_set_col(short col)
{
	console_curr_col = col;
}

void lcd_set_row(short row)
{
	console_curr_row = row;
}

void lcd_position_cursor(unsigned col, unsigned row)
{
	console_curr_col = min_t(short, col, console_cols - 1);
	console_curr_row = min_t(short, row, console_rows - 1);
}

int lcd_get_screen_rows(void)
{
	return console_rows;
}

int lcd_get_screen_columns(void)
{
	return console_cols;
}

static void lcd_drawchars(ushort x, ushort y, uchar *str, int count)
{
	uchar *dest;
	ushort row;
	int fg_color, bg_color;

	dest = (uchar *)(lcd_console_address +
			 y * lcd_line_length + x * NBITS(LCD_BPP) / 8);

	for (row = 0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) {
		uchar *s = str;
		int i;
#if LCD_BPP == LCD_COLOR16
		ushort *d = (ushort *)dest;
#elif LCD_BPP == LCD_COLOR32
		u32 *d = (u32 *)dest;
#else
		uchar *d = dest;
#endif

		fg_color = lcd_getfgcolor();
		bg_color = lcd_getbgcolor();
		for (i = 0; i < count; ++i) {
			uchar c, bits;

			c = *s++;
			bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];

			for (c = 0; c < 8; ++c) {
				*d++ = (bits & 0x80) ? fg_color : bg_color;
				bits <<= 1;
			}
		}
	}
}

static inline void lcd_putc_xy(ushort x, ushort y, uchar c)
{
	lcd_drawchars(x, y, &c, 1);
}

static void console_scrollup(void)
{
	const int rows = CONFIG_CONSOLE_SCROLL_LINES;
	int bg_color = lcd_getbgcolor();

	/* Copy up rows ignoring those that will be overwritten */
	memcpy(CONSOLE_ROW_FIRST,
	       lcd_console_address + CONSOLE_ROW_SIZE * rows,
	       CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows);

	/* Clear the last rows */
#if (LCD_BPP != LCD_COLOR32)
	memset(lcd_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows,
	       bg_color, CONSOLE_ROW_SIZE * rows);
#else
	u32 *ppix = lcd_console_address +
		    CONSOLE_SIZE - CONSOLE_ROW_SIZE * rows;
	u32 i;
	for (i = 0;
	    i < (CONSOLE_ROW_SIZE * rows) / NBYTES(panel_info.vl_bpix);
	    i++) {
		*ppix++ = bg_color;
	}
#endif
	lcd_sync();
	console_curr_row -= rows;
}

static inline void console_back(void)
{
	if (--console_curr_col < 0) {
		console_curr_col = console_cols - 1;
		if (--console_curr_row < 0)
			console_curr_row = 0;
	}

	lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
		    console_curr_row * VIDEO_FONT_HEIGHT, ' ');
}

static inline void console_newline(void)
{
	console_curr_col = 0;

	/* Check if we need to scroll the terminal */
	if (++console_curr_row >= console_rows)
		console_scrollup();
	else
		lcd_sync();
}

void lcd_putc(const char c)
{
	if (!lcd_is_enabled) {
		serial_putc(c);

		return;
	}

	switch (c) {
	case '\r':
		console_curr_col = 0;

		return;
	case '\n':
		console_newline();

		return;
	case '\t':	/* Tab (8 chars alignment) */
		console_curr_col +=  8;
		console_curr_col &= ~7;

		if (console_curr_col >= console_cols)
			console_newline();

		return;
	case '\b':
		console_back();

		return;
	default:
		lcd_putc_xy(console_curr_col * VIDEO_FONT_WIDTH,
			    console_curr_row * VIDEO_FONT_HEIGHT, c);
		if (++console_curr_col >= console_cols)
			console_newline();
	}
}

void lcd_puts(const char *s)
{
	if (!lcd_is_enabled) {
		serial_puts(s);

		return;
	}

	while (*s)
		lcd_putc(*s++);

	lcd_sync();
}

void lcd_printf(const char *fmt, ...)
{
	va_list args;
	char buf[CONFIG_SYS_PBSIZE];

	va_start(args, fmt);
	vsprintf(buf, fmt, args);
	va_end(args);

	lcd_puts(buf);
}
