// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2020 Google Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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.
 */

#include <libpayload.h>

#include "vboot/ui.h"
#include "vboot/util/commonparams.h"

vb2_error_t ui_draw_language_header(const struct ui_locale *locale,
				    const struct ui_state *state, int focused)
{
	int32_t x, y, y_center, w;
	const int reverse = state->locale->rtl;
	const int32_t box_width = UI_LANG_ICON_GLOBE_SIZE +
		UI_LANG_ICON_MARGIN_H * 2 + UI_LANG_TEXT_WIDTH +
		UI_LANG_ICON_ARROW_SIZE + UI_LANG_ICON_MARGIN_H;
	const int32_t box_height = UI_LANG_BOX_HEIGHT;
	const uint32_t flags = PIVOT_H_LEFT | PIVOT_V_CENTER;
	struct ui_bitmap bitmap;

	x = UI_MARGIN_H;
	y = UI_MARGIN_TOP;
	y_center = y + box_height / 2;

	VB2_TRY(ui_draw_rounded_box(x, y, box_width, box_height,
				    &ui_color_lang_header_bg,
				    0, UI_LANG_BORDER_RADIUS, reverse));

	/* Draw globe */
	x += UI_LANG_ICON_MARGIN_H;
	w = UI_LANG_ICON_GLOBE_SIZE;
	VB2_TRY(ui_get_bitmap("ic_globe.bmp", NULL, 0, &bitmap));
	VB2_TRY(ui_draw_bitmap(&bitmap, x, y_center, w, w, flags, reverse));
	x += w + UI_LANG_ICON_MARGIN_H;

	/* Draw language text */
	VB2_TRY(ui_get_language_name_bitmap(locale->code, 1, 0, &bitmap));
	VB2_TRY(ui_draw_bitmap(&bitmap, x, y_center,
			       UI_SIZE_AUTO, UI_LANG_TEXT_HEIGHT,
			       flags, reverse));
	x += UI_LANG_TEXT_WIDTH;

	/* Draw dropdown arrow */
	w = UI_LANG_ICON_ARROW_SIZE;
	VB2_TRY(ui_get_bitmap("ic_dropdown.bmp", NULL, 0, &bitmap));
	VB2_TRY(ui_draw_bitmap(&bitmap, x, y_center, w, w, flags, reverse));

	if (!focused)
		return VB2_SUCCESS;

	/* Draw box border */
	x = UI_MARGIN_H;
	y = UI_MARGIN_TOP;
	VB2_TRY(ui_draw_rounded_box(x, y, box_width, box_height,
				    &ui_color_lang_header_border,
				    UI_LANG_BORDER_THICKNESS,
				    UI_LANG_BORDER_RADIUS, reverse));

	return VB2_SUCCESS;
}

/*
 * Draw step icons.
 *
 * @param state		Current UI state.
 * @param prev_state	Previous UI state.
 *
 * @return VB2_SUCCESS on success, non-zero on error.
 */
static vb2_error_t ui_draw_step_icons(const struct ui_state *state,
				      const struct ui_state *prev_state)
{
	struct ui_bitmap bitmap;
	const struct ui_screen_info *screen = state->screen;
	const int has_error = screen->step < 0;
	const int cur_step = screen->step >= 0 ? screen->step : -screen->step;
	const int num_steps = screen->num_steps;
	int step;
	int32_t x = UI_MARGIN_H;
	const int32_t y = UI_MARGIN_TOP + UI_LANG_BOX_HEIGHT +
		UI_LANG_MARGIN_BOTTOM;
	const int32_t y_center = y + UI_ICON_HEIGHT / 2;
	const int32_t icon_size = UI_STEP_ICON_HEIGHT;
	const int reverse = state->locale->rtl;
	uint32_t flags = PIVOT_H_LEFT | PIVOT_V_CENTER;

	for (step = 1; step <= num_steps; step++) {
		if (has_error && step == cur_step)
			VB2_TRY(ui_get_bitmap("ic_error.bmp", NULL, 0,
					      &bitmap));
		else if (step < cur_step)
			VB2_TRY(ui_get_bitmap("ic_done.bmp", NULL, 0, &bitmap));
		else
			VB2_TRY(ui_get_step_icon_bitmap(step, step == cur_step,
							&bitmap));
		VB2_TRY(ui_draw_bitmap(&bitmap, x, y_center,
				       icon_size, icon_size, flags, reverse));
		x += icon_size;
		if (step == num_steps)
			break;

		/* Separator */
		x += UI_STEP_ICON_MARGIN_H;
		VB2_TRY(ui_draw_box(x, y_center,
				    UI_STEP_ICON_SEPARATOR_WIDTH, UI_SIZE_MIN,
				    &ui_color_border, reverse));
		x += UI_STEP_ICON_SEPARATOR_WIDTH + UI_STEP_ICON_MARGIN_H;
	}

	return VB2_SUCCESS;
}

static vb2_error_t draw_footer(const struct ui_state *state)
{
	char hwid[VB2_GBB_HWID_MAX_SIZE];
	uint32_t size = sizeof(hwid);
	char *p;
	const char *locale_code = state->locale->code;
	const int reverse = state->locale->rtl;
	const uint32_t flags = PIVOT_H_LEFT | PIVOT_V_TOP;
	const int32_t text_height = UI_FOOTER_TEXT_HEIGHT;
	int32_t x, y, vspacing;
	int32_t col2_width;
	const int32_t w = UI_SIZE_AUTO;
	const int32_t footer_y = UI_SCALE - UI_MARGIN_BOTTOM - UI_FOOTER_HEIGHT;
	const int32_t footer_height = UI_FOOTER_HEIGHT;
	struct ui_bitmap bitmap;

	/* hwid */
	if (vb2api_gbb_read_hwid(vboot_get_context(), hwid, &size) ==
	    VB2_SUCCESS) {
		/* Truncate everything after the first whitespace. */
		p = strchr(hwid, ' ');
		if (p)
			*p = '\0';
	} else {
		strcpy(hwid, "NOT FOUND");
	}

	/* Column 1 */
	x = UI_MARGIN_H;
	y = footer_y;
	VB2_TRY(ui_get_bitmap("qr_rec.bmp", NULL, 0, &bitmap));
	VB2_TRY(ui_draw_bitmap(&bitmap, x, y, footer_height, footer_height,
			       flags, reverse));
	x += footer_height + UI_FOOTER_COL1_MARGIN_RIGHT;

	/* Column 2: 4 lines of text */
	y = footer_y;
	vspacing = footer_height - text_height * 4 -
		UI_FOOTER_COL2_LINE_SPACING * 2;
	VB2_TRY(ui_get_bitmap("model.bmp", locale_code, 0, &bitmap));
	VB2_TRY(ui_draw_bitmap(&bitmap, x, y, w, text_height, flags, reverse));
	y += text_height + UI_FOOTER_COL2_LINE_SPACING;
	VB2_TRY(ui_draw_text(hwid, x, y, text_height, flags, UI_CHAR_STYLE_DARK,
			     reverse));
	y += text_height + vspacing;
	VB2_TRY(ui_get_bitmap("help_center.bmp", locale_code, 0, &bitmap));
	VB2_TRY(ui_draw_bitmap(&bitmap, x, y, w, text_height, flags, reverse));
	y += text_height + UI_FOOTER_COL2_LINE_SPACING;
	VB2_TRY(ui_get_bitmap("rec_url.bmp", locale_code, 0, &bitmap));
	VB2_TRY(ui_draw_bitmap(&bitmap, x, y, w, text_height, flags, reverse));
	VB2_TRY(ui_get_bitmap_width(&bitmap, text_height, &col2_width));
	x += col2_width + UI_FOOTER_COL2_MARGIN_RIGHT;

	/* Separator */
	VB2_TRY(ui_draw_box(x, footer_y, UI_SIZE_MIN, footer_height,
			    &ui_color_border, reverse));

	/* Column 3: 2 lines of text */
	int32_t icon_width;
	const int32_t icon_height = UI_FOOTER_COL3_ICON_HEIGHT;
	x += UI_FOOTER_COL3_MARGIN_LEFT;
	y = footer_y;
	vspacing = footer_height - text_height * 2 - icon_height -
		UI_FOOTER_COL3_PARA_SPACING;
	VB2_TRY(ui_get_bitmap("navigate0.bmp", locale_code, 0, &bitmap));
	VB2_TRY(ui_draw_bitmap(&bitmap, x, y, w, text_height, flags, reverse));
	y += text_height + vspacing;

	VB2_TRY(ui_get_bitmap("navigate1.bmp", locale_code, 0, &bitmap));
	VB2_TRY(ui_draw_bitmap(&bitmap, x, y, w, text_height, flags, reverse));
	y += text_height + UI_FOOTER_COL3_PARA_SPACING;

	const char *const icon_files[] = {
		"nav-key_enter.bmp",
		"nav-key_up.bmp",
		"nav-key_down.bmp",
	};

	for (int i = 0; i < ARRAY_SIZE(icon_files); i++) {
		VB2_TRY(ui_get_bitmap(icon_files[i], NULL, 0, &bitmap));
		VB2_TRY(ui_draw_bitmap(&bitmap, x, y, w, icon_height,
				       flags, reverse));
		VB2_TRY(ui_get_bitmap_width(&bitmap, icon_height, &icon_width));
		x += icon_width + UI_FOOTER_COL3_ICON_SPACING;
	}

	return VB2_SUCCESS;
}

/*
 * Get button width, based on the longest text of all the buttons.
 *
 * @param menu			Menu items.
 * @param state			UI state.
 * @param button_width		Button width to be calculated.
 *
 * @return VB2_SUCCESS on success, non-zero on error.
 */
static vb2_error_t ui_get_button_width(const struct ui_menu *menu,
				       const struct ui_state *state,
				       int32_t *button_width)
{
	int i;
	struct ui_bitmap bitmap;
	int32_t text_width;
	int32_t max_text_width = 0;

	for (i = 0; i < menu->num_items; i++) {
		if (state->disabled_item_mask & (1 << i))
			continue;
		if (menu->items[i].type != UI_MENU_ITEM_TYPE_PRIMARY)
			continue;
		VB2_TRY(ui_get_bitmap(menu->items[i].file, state->locale->code,
				      0, &bitmap));
		VB2_TRY(ui_get_bitmap_width(&bitmap, UI_BUTTON_TEXT_HEIGHT,
					    &text_width));
		max_text_width = MAX(text_width, max_text_width);
	}

	*button_width = max_text_width + UI_BUTTON_TEXT_PADDING_H * 2;
	return VB2_SUCCESS;
}

/*
 * Draw a button.
 *
 * @param image_name	Image name.
 * @param locale_code	Language code of current locale.
 * @param x		x-coordinate of the top-left corner.
 * @param y		y-coordinate of the top-left corner.
 * @param width		Width of the box.
 * @param height	Height of the box.
 * @param reverse	Whether to reverse the x-coordinate relative to the
 *			canvas.
 * @param focused	1 for focused and 0 for non-focused.
 *
 * @return VB2_SUCCESS on success, non-zero on error.
 */
static vb2_error_t ui_draw_button(const char *image_name,
				  const char *locale_code,
				  int32_t x, int32_t y,
				  int32_t width, int32_t height,
				  int reverse, int focused)
{
	struct ui_bitmap bitmap;
	const int32_t x_center = x + width / 2;
	const int32_t y_center = y + height / 2;
	const uint32_t flags = PIVOT_H_CENTER | PIVOT_V_CENTER;

	/* Clear button area */
	VB2_TRY(ui_draw_rounded_box(x, y, width, height,
				    focused ? &ui_color_button : &ui_color_bg,
				    0, UI_BUTTON_BORDER_RADIUS,
				    reverse));

	/* Draw button text */
	VB2_TRY(ui_get_bitmap(image_name, locale_code, focused, &bitmap));
	VB2_TRY(ui_draw_bitmap(&bitmap, x_center, y_center,
			       UI_SIZE_AUTO, UI_BUTTON_TEXT_HEIGHT,
			       flags, reverse));

	/* Draw button borders */
	VB2_TRY(ui_draw_rounded_box(x, y, width, height,
				    &ui_color_button_border,
				    UI_BUTTON_BORDER_THICKNESS,
				    UI_BUTTON_BORDER_RADIUS, reverse));

	return VB2_SUCCESS;
}

/*
 * Draw a link button, where the style is different from a primary button.
 *
 * @param item		Menu item.
 * @param locale_code	Language code of current locale.
 * @param x		x-coordinate of the top-left corner.
 * @param y		y-coordinate of the top-left corner.
 * @param height	Height of the box.
 * @param reverse	Whether to reverse the x-coordinate relative to the
 *			canvas.
 * @param focused	1 for focused and 0 for non-focused.
 *
 * @return VB2_SUCCESS on success, non-zero on error.
 */
static vb2_error_t ui_draw_link(const struct ui_menu_item *item,
				const char *locale_code,
				int32_t x, int32_t y, int32_t height,
				int reverse, int focused)
{
	struct ui_bitmap bitmap;
	int32_t text_width, width;
	const int32_t x_base = x;
	const int32_t y_center = y + height / 2;
	const uint32_t flags = PIVOT_H_LEFT | PIVOT_V_CENTER;
	const char *arrow_file;

	/* Get button width */
	VB2_TRY(ui_get_bitmap(item->file, locale_code, focused, &bitmap));
	VB2_TRY(ui_get_bitmap_width(&bitmap, UI_BUTTON_TEXT_HEIGHT,
				    &text_width));
	width = UI_LINK_TEXT_PADDING_LEFT +
		UI_LINK_ICON_SIZE + UI_LINK_ICON_MARGIN_R +
		text_width + UI_LINK_ARROW_MARGIN_H;
	if (!item->no_arrow)
		width += UI_LINK_ARROW_SIZE + UI_LINK_ARROW_MARGIN_H;

	/* Clear button area */
	VB2_TRY(ui_draw_rounded_box(x_base, y, width, height,
				    focused ? &ui_color_link_bg :
				    &ui_color_bg,
				    0, UI_BUTTON_BORDER_RADIUS,
				    reverse));

	/* Draw button icon */
	x += UI_LINK_TEXT_PADDING_LEFT;
	if (item->icon_file) {
		VB2_TRY(ui_get_bitmap(item->icon_file, NULL, focused, &bitmap));
		VB2_TRY(ui_draw_bitmap(&bitmap, x, y_center,
				       UI_LINK_ICON_SIZE, UI_LINK_ICON_SIZE,
				       flags, reverse));
	}
	x += UI_LINK_ICON_SIZE + UI_LINK_ICON_MARGIN_R;

	/* Draw button text */
	VB2_TRY(ui_get_bitmap(item->file, locale_code, focused, &bitmap));
	VB2_TRY(ui_draw_bitmap(&bitmap, x, y_center,
			       UI_SIZE_AUTO, UI_BUTTON_TEXT_HEIGHT,
			       flags, reverse));
	x += text_width;

	/* Draw arrow */
	x += UI_LINK_ARROW_MARGIN_H;
	if (!item->no_arrow) {
		arrow_file = reverse ? "ic_dropleft.bmp" : "ic_dropright.bmp";
		VB2_TRY(ui_get_bitmap(arrow_file, NULL, focused, &bitmap));
		VB2_TRY(ui_draw_bitmap(&bitmap, x, y_center,
				       UI_LINK_ARROW_SIZE, UI_LINK_ARROW_SIZE,
				       flags, reverse));
		x += UI_LINK_ARROW_SIZE + UI_LINK_ARROW_MARGIN_H;
	}

	/* Draw button borders */
	if (focused)
		VB2_TRY(ui_draw_rounded_box(x_base, y, width, height,
					    &ui_color_button_border,
					    UI_LINK_BORDER_THICKNESS,
					    UI_BUTTON_BORDER_RADIUS, reverse));

	return VB2_SUCCESS;
}

vb2_error_t ui_draw_desc(const struct ui_desc *desc,
			 const struct ui_state *state,
			 int32_t *y)
{
	int i;
	struct ui_bitmap bitmap;
	const char *locale_code = state->locale->code;
	const int reverse = state->locale->rtl;
	int32_t x;
	const int32_t w = UI_SIZE_AUTO;
	const int32_t h = UI_DESC_TEXT_HEIGHT;
	uint32_t flags = PIVOT_H_LEFT | PIVOT_V_TOP;

	x = UI_MARGIN_H;

	for (i = 0; i < desc->count; i++) {
		if (i > 0)
			*y += UI_DESC_TEXT_LINE_SPACING;
		VB2_TRY(ui_get_bitmap(desc->files[i], locale_code, 0, &bitmap));
		VB2_TRY(ui_draw_bitmap(&bitmap, x, *y, w, h, flags, reverse));
		*y += h;
	}

	return VB2_SUCCESS;
}

vb2_error_t ui_draw_default(const struct ui_state *state,
			    const struct ui_state *prev_state)
{
	int i;
	const struct ui_screen_info *screen = state->screen;
	const struct ui_menu *menu = &screen->menu;
	const char *locale_code = state->locale->code;
	const int reverse = state->locale->rtl;
	int focused;
	int32_t x, y;
	const int32_t w = UI_SIZE_AUTO;
	uint32_t flags = PIVOT_H_LEFT | PIVOT_V_TOP;
	const char *icon_file;
	struct ui_bitmap bitmap;

	if (!prev_state ||
	    prev_state->locale != state->locale ||
	    prev_state->error_code != state->error_code) {
		/*
		 * Clear the whole screen if previous drawing failed, if there
		 * is no previous screen, or if locale changed.
		 */
		clear_screen(&ui_color_bg);
	} else if (prev_state->screen != state->screen) {
		/* Clear everything above the footer for new screen. */
		const int32_t box_height = UI_SCALE - UI_MARGIN_BOTTOM -
			UI_FOOTER_HEIGHT;
		/* TODO(b/147424699): Do not clear and redraw language header */
		VB2_TRY(ui_draw_box(0, 0, UI_SCALE, box_height,
				    &ui_color_bg, 0));
	}

	/* Language dropdown header */
	if (menu->num_items > 0 &&
	    menu->items[0].type == UI_MENU_ITEM_TYPE_LANGUAGE) {
		focused = state->selected_item == 0;
		if (!prev_state ||
		    prev_state->screen != state->screen ||
		    prev_state->locale != state->locale ||
		    prev_state->error_code != state->error_code ||
		    (prev_state->selected_item == 0) != focused) {
			VB2_TRY(ui_draw_language_header(state->locale, state,
							focused));
		}
	}

	/*
	 * Draw the footer if previous screen doesn't have a footer, or if
	 * locale changed.
	 */
	if (!screen->no_footer &&
	    (!prev_state ||
	     prev_state->screen->no_footer ||
	     prev_state->locale != state->locale ||
	     prev_state->error_code != state->error_code))
		VB2_TRY(draw_footer(state));

	/* Icon */
	switch (screen->icon) {
	case UI_ICON_TYPE_INFO:
		icon_file = "ic_info.bmp";
		break;
	case UI_ICON_TYPE_ERROR:
		icon_file = "ic_error.bmp";
		break;
	case UI_ICON_TYPE_DEV_MODE:
		icon_file = "ic_dev_mode.bmp";
		break;
	case UI_ICON_TYPE_RESTART:
		icon_file = "ic_restart.bmp";
		break;
	default:
		icon_file = NULL;
		break;
	}

	x = UI_MARGIN_H;
	y = UI_MARGIN_TOP + UI_LANG_BOX_HEIGHT + UI_LANG_MARGIN_BOTTOM;
	if (screen->icon == UI_ICON_TYPE_STEP) {
		VB2_TRY(ui_draw_step_icons(state, prev_state));
	} else if (icon_file) {
		VB2_TRY(ui_get_bitmap(icon_file, NULL, 0, &bitmap));
		VB2_TRY(ui_draw_bitmap(&bitmap, x, y, w, UI_ICON_HEIGHT,
				       flags, reverse));
	}
	y += UI_ICON_HEIGHT + UI_ICON_MARGIN_BOTTOM;

	/* Title */
	if (screen->title) {
		VB2_TRY(ui_get_bitmap(screen->title, locale_code, 0, &bitmap));
		VB2_TRY(ui_draw_bitmap(&bitmap, x, y, w, UI_TITLE_TEXT_HEIGHT,
				       flags, reverse));
	}
	y += UI_TITLE_TEXT_HEIGHT + UI_TITLE_MARGIN_BOTTOM;

	/* Description */
	if (screen->draw_desc)
		VB2_TRY(screen->draw_desc(state, prev_state, &y));
	else
		VB2_TRY(ui_draw_desc(&screen->desc, state, &y));
	y += UI_DESC_MARGIN_BOTTOM;

	/* Primary buttons */
	int32_t button_width;
	VB2_TRY(ui_get_button_width(menu, state, &button_width));

	for (i = 0; i < menu->num_items; i++) {
		if (state->disabled_item_mask & (1 << i))
			continue;
		if (menu->items[i].type != UI_MENU_ITEM_TYPE_PRIMARY)
			continue;
		/*
		 * TODO(b/147424699): No need to redraw every button when
		 * navigating between menu.
		 */
		VB2_TRY(ui_draw_button(menu->items[i].file, locale_code,
				       x, y, button_width, UI_BUTTON_HEIGHT,
				       reverse, state->selected_item == i));
		y += UI_BUTTON_HEIGHT + UI_BUTTON_MARGIN_V;
	}

	/* Secondary (link) buttons */
	x = UI_MARGIN_H - UI_LINK_TEXT_PADDING_LEFT;
	y = UI_SCALE - UI_MARGIN_BOTTOM - UI_FOOTER_HEIGHT -
		UI_FOOTER_MARGIN_TOP - UI_BUTTON_HEIGHT;
	for (i = menu->num_items - 1; i >= 0; i--) {
		if (state->disabled_item_mask & (1 << i))
			continue;
		if (menu->items[i].type != UI_MENU_ITEM_TYPE_SECONDARY)
			continue;
		VB2_TRY(ui_draw_link(&menu->items[i], locale_code,
				     x, y, UI_BUTTON_HEIGHT, reverse,
				     state->selected_item == i));
		y -= UI_BUTTON_HEIGHT + UI_BUTTON_MARGIN_V;
	}

	return VB2_SUCCESS;
}
