/** @file
 * @brief Monochrome Character Framebuffer shell module
 *
 * Provide some Character Framebuffer shell commands that can be useful for
 * testing.
 */

/*
 * Copyright (c) 2018 Diego Sueiro
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdlib.h>
#include <zephyr/shell/shell.h>
#include <zephyr/display/cfb.h>

#define HELP_NONE "[none]"
#define HELP_INIT "call \"cfb init\" first"
#define HELP_PRINT "<col: pos> <row: pos> \"<text>\""
#define HELP_DRAW_POINT "<x> <y0>"
#define HELP_DRAW_LINE "<x0> <y0> <x1> <y1>"
#define HELP_INVERT "[<x> <y> <width> <height>]"

static const struct device *const dev =
	DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
static const char * const param_name[] = {
	"height", "width", "ppt", "rows", "cols"};

static int cmd_clear(const struct shell *sh, size_t argc, char *argv[])
{
	int err;

	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	err = cfb_framebuffer_clear(dev, true);
	if (err) {
		shell_error(sh, "Framebuffer clear error=%d", err);
		return err;
	}

	err = cfb_framebuffer_finalize(dev);
	if (err) {
		shell_error(sh, "Framebuffer finalize error=%d", err);
		return err;
	}

	shell_print(sh, "Display Cleared");

	return err;
}

static int cmd_cfb_print(const struct shell *sh, int col, int row, char *str)
{
	int err;
	uint8_t ppt;

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	ppt = cfb_get_display_parameter(dev, CFB_DISPLAY_PPT);

	err = cfb_framebuffer_clear(dev, false);
	if (err) {
		shell_error(sh, "Framebuffer clear failed error=%d", err);
		return err;
	}

	err = cfb_print(dev, str, col, row * ppt);
	if (err) {
		shell_error(sh, "Failed to print the string %s error=%d",
		      str, err);
		return err;
	}

	err = cfb_framebuffer_finalize(dev);
	if (err) {
		shell_error(sh,
			    "Failed to finalize the Framebuffer error=%d", err);
		return err;
	}

	return err;
}

static int cmd_print(const struct shell *sh, size_t argc, char *argv[])
{
	int err;
	int col, row;

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	col = strtol(argv[1], NULL, 10);
	if (col > cfb_get_display_parameter(dev, CFB_DISPLAY_COLS)) {
		shell_error(sh, "Invalid col=%d position", col);
		return -EINVAL;
	}

	row = strtol(argv[2], NULL, 10);
	if (row > cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS)) {
		shell_error(sh, "Invalid row=%d position", row);
		return -EINVAL;
	}

	err = cmd_cfb_print(sh, col, row, argv[3]);
	if (err) {
		shell_error(sh, "Failed printing to Framebuffer error=%d",
			    err);
	}

	return err;
}

static int cmd_draw_text(const struct shell *sh, size_t argc, char *argv[])
{
	int err;
	int x, y;

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	x = strtol(argv[1], NULL, 10);
	y = strtol(argv[2], NULL, 10);
	err = cfb_draw_text(dev, argv[3], x, y);
	if (err) {
		shell_error(sh, "Failed text drawing to Framebuffer error=%d", err);
		return err;
	}

	err = cfb_framebuffer_finalize(dev);

	return err;
}

static int cmd_draw_point(const struct shell *sh, size_t argc, char *argv[])
{
	int err;
	struct cfb_position pos;

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	pos.x = strtol(argv[1], NULL, 10);
	pos.y = strtol(argv[2], NULL, 10);

	err = cfb_draw_point(dev, &pos);
	if (err) {
		shell_error(sh, "Failed point drawing to Framebuffer error=%d", err);
		return err;
	}

	err = cfb_framebuffer_finalize(dev);

	return err;
}

static int cmd_draw_line(const struct shell *sh, size_t argc, char *argv[])
{
	int err;
	struct cfb_position start, end;

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	start.x = strtol(argv[1], NULL, 10);
	start.y = strtol(argv[2], NULL, 10);
	end.x = strtol(argv[3], NULL, 10);
	end.y = strtol(argv[4], NULL, 10);

	err = cfb_draw_line(dev, &start, &end);
	if (err) {
		shell_error(sh, "Failed text drawing to Framebuffer error=%d", err);
		return err;
	}

	err = cfb_framebuffer_finalize(dev);

	return err;
}

static int cmd_scroll_vert(const struct shell *sh, size_t argc, char *argv[])
{
	int err = 0;
	int col, row;
	int boundary;

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	col = strtol(argv[1], NULL, 10);
	if (col > cfb_get_display_parameter(dev, CFB_DISPLAY_COLS)) {
		shell_error(sh, "Invalid col=%d position", col);
		return -EINVAL;
	}

	row = strtol(argv[2], NULL, 10);
	if (row > cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS)) {
		shell_error(sh, "Invalid row=%d position", row);
		return -EINVAL;
	}

	boundary = cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS) - row;

	for (int i = 0; i < boundary; i++) {
		err = cmd_cfb_print(sh, col, row, argv[3]);
		if (err) {
			shell_error(sh,
				    "Failed printing to Framebuffer error=%d",
				    err);
			break;
		}
		row++;
	}

	cmd_cfb_print(sh, 0, 0, "");

	return err;
}

static int cmd_scroll_horz(const struct shell *sh, size_t argc, char *argv[])
{
	int err = 0;
	int col, row;
	int boundary;

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	col = strtol(argv[1], NULL, 10);
	if (col > cfb_get_display_parameter(dev, CFB_DISPLAY_COLS)) {
		shell_error(sh, "Invalid col=%d position", col);
		return -EINVAL;
	}

	row = strtol(argv[2], NULL, 10);
	if (row > cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS)) {
		shell_error(sh, "Invalid row=%d position", row);
		return -EINVAL;
	}

	col++;
	boundary = cfb_get_display_parameter(dev, CFB_DISPLAY_COLS) - col;

	for (int i = 0; i < boundary; i++) {
		err = cmd_cfb_print(sh, col, row, argv[3]);
		if (err) {
			shell_error(sh,
				    "Failed printing to Framebuffer error=%d",
				    err);
			break;
		}
		col++;
	}

	cmd_cfb_print(sh, 0, 0, "");

	return err;
}

static int cmd_set_font(const struct shell *sh, size_t argc, char *argv[])
{
	int err;
	int idx;
	uint8_t height;
	uint8_t width;

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	idx = strtol(argv[1], NULL, 10);

	err = cfb_get_font_size(dev, idx, &width, &height);
	if (err) {
		shell_error(sh, "Invalid font idx=%d err=%d\n", idx, err);
		return err;
	}

	err = cfb_framebuffer_set_font(dev, idx);
	if (err) {
		shell_error(sh, "Failed setting font idx=%d err=%d", idx,
			    err);
		return err;
	}

	shell_print(sh, "Font idx=%d height=%d widht=%d set", idx, height,
		    width);

	return err;
}

static int cmd_set_kerning(const struct shell *sh, size_t argc, char *argv[])
{
	int err;
	char *ep = NULL;
	long kerning;

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	errno = 0;
	kerning = strtol(argv[1], &ep, 10);
	if (errno || ep == argv[1]) {
		shell_error(sh, HELP_INIT);
		return -EINVAL;
	}

	err = cfb_set_kerning(dev, kerning);
	if (err) {
		shell_error(sh, "Failed to set kerning err=%d", err);
		return err;
	}

	return err;
}

static int cmd_invert(const struct shell *sh, size_t argc, char *argv[])
{
	int err;

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	if (argc == 1) {
		uint8_t width = cfb_get_display_parameter(dev, CFB_DISPLAY_WIDTH);
		uint8_t height = cfb_get_display_parameter(dev, CFB_DISPLAY_HEIGH);

		err = cfb_invert_area(dev, 0, 0, width, height);
		if (err) {
			shell_error(sh, "Error inverting area");
			return err;
		}

		err = cfb_framebuffer_invert(dev);
		if (err) {
			return err;
		}
	} else if (argc == 5) {
		int x, y, w, h;

		x = strtol(argv[1], NULL, 10);
		y = strtol(argv[2], NULL, 10);
		w = strtol(argv[3], NULL, 10);
		h = strtol(argv[4], NULL, 10);

		err = cfb_invert_area(dev, x, y, w, h);
		if (err) {
			shell_error(sh, "Error invert area");
			return err;
		}
	} else {
		shell_help(sh);
		return 0;
	}

	if (err) {
		shell_error(sh, "Error inverting Framebuffer");
		return err;
	}

	cfb_framebuffer_finalize(dev);

	shell_print(sh, "Framebuffer Inverted");

	return err;
}

static int cmd_get_fonts(const struct shell *sh, size_t argc, char *argv[])
{
	int err = 0;
	uint8_t font_height;
	uint8_t font_width;

	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	for (int idx = 0; idx < cfb_get_numof_fonts(dev); idx++) {
		if (cfb_get_font_size(dev, idx, &font_width, &font_height)) {
			break;
		}
		shell_print(sh, "idx=%d height=%d width=%d", idx,
			    font_height, font_width);
	}

	return err;
}

static int cmd_get_device(const struct shell *sh, size_t argc, char *argv[])
{
	int err = 0;

	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	shell_print(sh, "Framebuffer Device: %s", dev->name);

	return err;
}

static int cmd_get_param_all(const struct shell *sh, size_t argc,
			     char *argv[])
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	for (unsigned int i = 0; i <= CFB_DISPLAY_COLS; i++) {
		shell_print(sh, "param: %s=%d", param_name[i],
				cfb_get_display_parameter(dev, i));

	}

	return 0;
}

static int cmd_get_param_height(const struct shell *sh, size_t argc,
			     char *argv[])
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	shell_print(sh, "param: %s=%d", param_name[CFB_DISPLAY_HEIGH],
		    cfb_get_display_parameter(dev, CFB_DISPLAY_HEIGH));

	return 0;
}

static int cmd_get_param_width(const struct shell *sh, size_t argc,
			     char *argv[])
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	shell_print(sh, "param: %s=%d", param_name[CFB_DISPLAY_WIDTH],
		    cfb_get_display_parameter(dev, CFB_DISPLAY_WIDTH));

	return 0;
}

static int cmd_get_param_ppt(const struct shell *sh, size_t argc,
			     char *argv[])
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	shell_print(sh, "param: %s=%d", param_name[CFB_DISPLAY_PPT],
		    cfb_get_display_parameter(dev, CFB_DISPLAY_PPT));

	return 0;
}

static int cmd_get_param_rows(const struct shell *sh, size_t argc,
			     char *argv[])
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	shell_print(sh, "param: %s=%d", param_name[CFB_DISPLAY_ROWS],
		    cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS));

	return 0;
}

static int cmd_get_param_cols(const struct shell *sh, size_t argc,
			     char *argv[])
{
	ARG_UNUSED(argc);
	ARG_UNUSED(argv);

	if (!dev) {
		shell_error(sh, HELP_INIT);
		return -ENODEV;
	}

	shell_print(sh, "param: %s=%d", param_name[CFB_DISPLAY_COLS],
		    cfb_get_display_parameter(dev, CFB_DISPLAY_COLS));

	return 0;
}

static int cmd_init(const struct shell *sh, size_t argc, char *argv[])
{
	int err;

	if (!device_is_ready(dev)) {
		shell_error(sh, "Display device not ready");
		return -ENODEV;
	}

	err = display_set_pixel_format(dev, PIXEL_FORMAT_MONO10);
	if (err) {
		err = display_set_pixel_format(dev, PIXEL_FORMAT_MONO01);
		if (err) {
			shell_error(sh, "Failed to set required pixel format: %d", err);
			return err;
		}
	}

	err = display_blanking_off(dev);
	if (err) {
		shell_error(sh, "Failed to turn off display blanking: %d", err);
		return err;
	}

	err = cfb_framebuffer_init(dev);
	if (err) {
		shell_error(sh, "Framebuffer initialization failed!");
		return err;
	}

	shell_print(sh, "Framebuffer initialized: %s", dev->name);
	cmd_clear(sh, argc, argv);

	return err;
}

SHELL_STATIC_SUBCMD_SET_CREATE(sub_cmd_get_param,

	SHELL_CMD_ARG(all, NULL, NULL, cmd_get_param_all, 1, 0),
	SHELL_CMD_ARG(height, NULL, NULL, cmd_get_param_height, 1, 0),
	SHELL_CMD_ARG(width, NULL, NULL, cmd_get_param_width, 1, 0),
	SHELL_CMD_ARG(ppt, NULL, NULL, cmd_get_param_ppt, 1, 0),
	SHELL_CMD_ARG(rows, NULL, NULL, cmd_get_param_rows, 1, 0),
	SHELL_CMD_ARG(cols, NULL, NULL, cmd_get_param_cols, 1, 0),
	SHELL_SUBCMD_SET_END
);

SHELL_STATIC_SUBCMD_SET_CREATE(sub_cmd_scroll,

	SHELL_CMD_ARG(vertical, NULL, HELP_PRINT, cmd_scroll_vert, 4, 0),
	SHELL_CMD_ARG(horizontal, NULL, HELP_PRINT, cmd_scroll_horz, 4, 0),
	SHELL_SUBCMD_SET_END
);

SHELL_STATIC_SUBCMD_SET_CREATE(sub_cmd_draw,
	SHELL_CMD_ARG(text, NULL, HELP_PRINT, cmd_draw_text, 4, 0),
	SHELL_CMD_ARG(point, NULL, HELP_DRAW_POINT, cmd_draw_point, 3, 0),
	SHELL_CMD_ARG(line, NULL, HELP_DRAW_LINE, cmd_draw_line, 5, 0),
	SHELL_SUBCMD_SET_END
);

SHELL_STATIC_SUBCMD_SET_CREATE(cfb_cmds,
	SHELL_CMD_ARG(init, NULL, HELP_NONE, cmd_init, 1, 0),
	SHELL_CMD_ARG(get_device, NULL, HELP_NONE, cmd_get_device, 1, 0),
	SHELL_CMD(get_param, &sub_cmd_get_param,
		  "<all, height, width, ppt, rows, cols>", NULL),
	SHELL_CMD_ARG(get_fonts, NULL, HELP_NONE, cmd_get_fonts, 1, 0),
	SHELL_CMD_ARG(set_font, NULL, "<idx>", cmd_set_font, 2, 0),
	SHELL_CMD_ARG(set_kerning, NULL, "<kerning>", cmd_set_kerning, 2, 0),
	SHELL_CMD_ARG(invert, NULL, HELP_INVERT, cmd_invert, 1, 5),
	SHELL_CMD_ARG(print, NULL, HELP_PRINT, cmd_print, 4, 0),
	SHELL_CMD(scroll, &sub_cmd_scroll, "scroll a text in vertical or "
		  "horizontal direction", NULL),
	SHELL_CMD(draw, &sub_cmd_draw, "drawing text", NULL),
	SHELL_CMD_ARG(clear, NULL, HELP_NONE, cmd_clear, 1, 0),
	SHELL_SUBCMD_SET_END
);

SHELL_CMD_REGISTER(cfb, &cfb_cmds, "Character Framebuffer shell commands",
		   NULL);
