/*
 * Copyright 2015 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.
 *
 * 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
 */

#include <gbb_header.h>
#include <stdio.h>
#include <vboot_api.h>
#include <vboot/screens.h>

#include "base/algorithm.h"
#include "base/coreboot/cbfs.h"
#include "base/graphics.h"
#include "drivers/video/display.h"
#include "vboot/util/gbb.h"

/*
 * This is the base used to specify the size and the coordinate of the image.
 * For example, height = 40 means 4.0% of the canvas (=drawing area) height.
 */
#define VB_SCALE	1000
#define VB_SCALE_HALF	(VB_SCALE / 2)	/* 50.0% */

/* Height of the text image per line relative to the canvas size */
#define VB_TEXT_HEIGHT	40		/* 4.0% */

/* Indicate width or height is automatically set based on the other value */
#define VB_SIZE_AUTO	0

/* Height of the icons relative to the canvas size */
#define VB_ICON_HEIGHT	160

/* Vertical position and size of the dividers */
#define VB_DIVIDER_WIDTH	800	/* 80.0% */
#define VB_DIVIDER_V_OFFSET	160	/* 16.0% */

/* Width of the language name */
#define VB_LANGUAGE_WIDTH	100

#define RETURN_ON_ERROR(function_call) do {				\
		VbError_t rv = (function_call);				\
		if (rv)							\
			return rv;					\
	} while (0)

static char initialized = 0;
static uint32_t locale_count;
static char *supported_locales[256];

static VbError_t draw_image(const char *image_name,
			    int32_t x, int32_t y, int32_t width, int32_t height,
			    char pivot)
{
	uint8_t *image;
	size_t size;
	VbError_t rv = VBERROR_SUCCESS;

	image = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, image_name,
				      CBFS_TYPE_RAW, &size);
	if (!image)
		return VBERROR_NO_IMAGE_PRESENT;

	struct scale pos = {
		.x = { .n = x, .d = VB_SCALE, },
		.y = { .n = y, .d = VB_SCALE, },
	};
	struct scale dim = {
		.x = { .n = width, .d = VB_SCALE, },
		.y = { .n = height, .d = VB_SCALE, },
	};

	rv = draw_bitmap(image, size, &pos, pivot, &dim);
	if (rv)
		rv = VBERROR_UNKNOWN;
	free(image);

	return rv;
}

static int draw_image_locale(const char *image_name, uint32_t locale,
			     int32_t x, int32_t y,
			     int32_t width, int32_t height, char pivot)
{
	char str[256];
	snprintf(str, sizeof(str), "locale/%s/%s",
		 supported_locales[locale], image_name);
	return draw_image(str, x, y, width, height, pivot);
}

static VbError_t get_image_size(const char *image_name,
				int32_t *width, int32_t *height)
{
	uint8_t *image;
	size_t size;
	VbError_t rv;

	image = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, image_name,
				      CBFS_TYPE_RAW, &size);
	if (!image)
		return VBERROR_NO_IMAGE_PRESENT;

	struct scale dim = {
		.x = { .n = *width, .d = VB_SCALE, },
		.y = { .n = *height, .d = VB_SCALE, },
	};

	rv = get_bitmap_dimension(image, size, &dim);
	free(image);
	if (rv)
		return VBERROR_UNKNOWN;

	*width = dim.x.n * VB_SCALE / dim.x.d;
	*height = dim.y.n * VB_SCALE / dim.y.d;

	return VBERROR_SUCCESS;
}

static VbError_t get_image_size_locale(const char *image_name, uint32_t locale,
				       int32_t *width, int32_t *height)
{
	char str[256];
	snprintf(str, sizeof(str), "locale/%s/%s",
		 supported_locales[locale], image_name);
	return get_image_size(str, width, height);
}

static int draw_icon(const char *image_name)
{
	return draw_image(image_name,
			  VB_SCALE_HALF, VB_SCALE_HALF,
			  VB_SIZE_AUTO, VB_ICON_HEIGHT,
			  PIVOT_H_CENTER|PIVOT_V_BOTTOM);
}

static int draw_text(const char *text, int32_t x, int32_t y,
		     int32_t height, char pivot)
{
	int32_t w, h;
	char str[256];
	while (*text) {
		sprintf(str, "font/idx%03d_%02x.bmp", *text, *text);
		w = 0;
		h = height;
		RETURN_ON_ERROR(get_image_size(str, &w, &h));
		RETURN_ON_ERROR(draw_image(str,
				x, y, VB_SIZE_AUTO, height, pivot));
		x += w;
		text++;
	}
	return VBERROR_SUCCESS;
}

static int get_text_width(const char *text, int32_t *width, int32_t *height)
{
	int32_t w, h;
	char str[256];
	while (*text) {
		sprintf(str, "font/idx%03d_%02x.bmp", *text, *text);
		w = 0;
		h = *height;
		RETURN_ON_ERROR(get_image_size(str, &w, &h));
		*width += w;
		text++;
	}
	return VBERROR_SUCCESS;
}

static VbError_t vboot_draw_footer(uint32_t locale)
{
	int32_t x, y, w1, h1, w2, h2;

	/*
	 * Draw help URL line: 'For help visit http://.../'. It consits of
	 * two parts: 'For help visit', which is locale dependent, and a URL.
	 * Since the widths vary, we need to get the widths first then calculate
	 * the horizontal positions of the images.
	 */
	w1 = 0;
	h1 = VB_TEXT_HEIGHT;
	RETURN_ON_ERROR(get_image_size_locale("for_help_left.bmp", locale,
					      &w1, &h1));
	w2 = 0;
	h2 = VB_TEXT_HEIGHT;
	RETURN_ON_ERROR(get_image_size("Url.bmp", &w2, &h2));

	/* Calculate horizontal position to centralize the combined images */
	x = (VB_SCALE - w1 - w2) / 2;
	y = VB_SCALE - VB_DIVIDER_V_OFFSET;
	RETURN_ON_ERROR(draw_image_locale("for_help_left.bmp", locale,
			x, y, VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_LEFT|PIVOT_V_TOP));
	x += w1;
	RETURN_ON_ERROR(draw_image("Url.bmp",
			x, y, VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_LEFT|PIVOT_V_TOP));

	/*
	 * Draw model line: 'Model XYZ'. It consists of two parts: 'Model',
	 * which is locale dependent, and 'XYZ', a model name. Model name
	 * consists of individual font images: 'X' 'Y' 'Z'.
	 */
	const char *hwid = gbb_read_hwid(NULL);
	if (!hwid)
		hwid = "NOT FOUND";

	w1 = 0;
	h1 = VB_TEXT_HEIGHT;
	RETURN_ON_ERROR(get_image_size_locale("model.bmp", locale, &w1, &h1));

	w2 = 0;
	h2 = VB_TEXT_HEIGHT;
	RETURN_ON_ERROR(get_text_width(hwid, &w2, &h2));

	/* Calculate horizontal position to centralize the combined images */
	x = (VB_SCALE - w1 - w2) / 2;
	y += VB_TEXT_HEIGHT;
	RETURN_ON_ERROR(draw_image_locale("model.bmp", locale,
			x, y, VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_LEFT|PIVOT_V_TOP));
	x += w1;
	RETURN_ON_ERROR(draw_text(hwid, x, y, VB_TEXT_HEIGHT,
			PIVOT_H_LEFT|PIVOT_V_TOP));

	return VBERROR_SUCCESS;
}

/*
 * Draws the language section at the top right corner. The language text image
 * is placed in the middle surrounded by arrows on each side.
 */
static VbError_t vboot_draw_language(uint32_t locale)
{
	int32_t w, h, x;

	/* This width is used to calculate the position of language.bmp */
	w = 0;
	h = VB_TEXT_HEIGHT;
	RETURN_ON_ERROR(get_image_size("arrow_right.bmp", &w, &h));

	/*
	 * Right arrow starts from the right edge of the divider, which is
	 * positioned horizontally in the center.
	 */
	x = VB_SCALE_HALF + VB_DIVIDER_WIDTH / 2;
	RETURN_ON_ERROR(draw_image("arrow_right.bmp",
			x, VB_DIVIDER_V_OFFSET, VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_RIGHT|PIVOT_V_BOTTOM));

	/* Since widths of language.bmp vary, we have to use the center pivot */
	x -= (w + VB_LANGUAGE_WIDTH / 2);
	RETURN_ON_ERROR(draw_image_locale("language.bmp", locale,
			x, VB_DIVIDER_V_OFFSET, VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_CENTER|PIVOT_V_BOTTOM));

	/* Left arrow starts from the right edge of language.bmp */
	x -= VB_LANGUAGE_WIDTH / 2;
	RETURN_ON_ERROR(draw_image("arrow_left.bmp",
			x, VB_DIVIDER_V_OFFSET, VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_RIGHT|PIVOT_V_BOTTOM));

	return VBERROR_SUCCESS;
}

static VbError_t vboot_draw_base_screen(uint32_t locale)
{
	const struct rgb_color white = { 0xff, 0xff, 0xff };

	if (clear_screen(&white))
		return VBERROR_UNKNOWN;
	RETURN_ON_ERROR(draw_image("chrome_logo.bmp",
			(VB_SCALE - VB_DIVIDER_WIDTH)/2,
			/* '-10' to keep the logo lifted up from the divider */
			VB_DIVIDER_V_OFFSET - 10,
			VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_LEFT|PIVOT_V_BOTTOM));

	RETURN_ON_ERROR(vboot_draw_language(locale));

	RETURN_ON_ERROR(draw_image("divider_top.bmp",
			VB_SCALE_HALF, VB_DIVIDER_V_OFFSET,
			VB_DIVIDER_WIDTH, VB_SIZE_AUTO,
			PIVOT_H_CENTER|PIVOT_V_TOP));
	RETURN_ON_ERROR(draw_image("divider_btm.bmp",
			VB_SCALE_HALF, VB_SCALE - VB_DIVIDER_V_OFFSET,
			VB_DIVIDER_WIDTH, VB_SIZE_AUTO,
			PIVOT_H_CENTER|PIVOT_V_BOTTOM));

	RETURN_ON_ERROR(vboot_draw_footer(locale));

	return VBERROR_SUCCESS;
}

static VbError_t vboot_draw_blank(uint32_t locale)
{
	video_console_clear();
	return VBERROR_SUCCESS;
}

static VbError_t vboot_draw_developer_warning(uint32_t locale)
{
	RETURN_ON_ERROR(vboot_draw_base_screen(locale));
	RETURN_ON_ERROR(draw_icon("VerificationOff.bmp"));
	RETURN_ON_ERROR(draw_image_locale("verif_off.bmp", locale,
			VB_SCALE_HALF, VB_SCALE_HALF,
			VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_CENTER|PIVOT_V_TOP));
	RETURN_ON_ERROR(draw_image_locale("devmode.bmp", locale,
			VB_SCALE_HALF, VB_SCALE_HALF + VB_TEXT_HEIGHT,
			VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_CENTER|PIVOT_V_TOP));
	return VBERROR_SUCCESS;
}

static VbError_t vboot_draw_recovery_remove(uint32_t locale)
{
	RETURN_ON_ERROR(vboot_draw_base_screen(locale));
	RETURN_ON_ERROR(draw_image_locale("remove.bmp", locale,
			VB_SCALE_HALF, VB_SCALE_HALF - VB_ICON_HEIGHT,
			VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_CENTER|PIVOT_V_BOTTOM));
	RETURN_ON_ERROR(draw_image("RemoveDevices.bmp",
			VB_SCALE_HALF, VB_SCALE_HALF,
			VB_SIZE_AUTO, VB_ICON_HEIGHT * 2,
			PIVOT_H_CENTER|PIVOT_V_CENTER));
	return VBERROR_SUCCESS;
}

static VbError_t vboot_draw_recovery_no_good(uint32_t locale)
{
	RETURN_ON_ERROR(vboot_draw_base_screen(locale));
	RETURN_ON_ERROR(draw_image_locale("yuck.bmp", locale,
			VB_SCALE_HALF, VB_SCALE_HALF,
			VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_CENTER|PIVOT_V_BOTTOM));
	/*
	 * TODO: We need a mechanism to let boards customize these. For example,
	 * some boards have only USB.
	 */
	RETURN_ON_ERROR(draw_image("BadSD.bmp",
			VB_SCALE_HALF, VB_SCALE_HALF,
			VB_SIZE_AUTO, VB_ICON_HEIGHT,
			PIVOT_H_RIGHT|PIVOT_V_TOP));
	RETURN_ON_ERROR(draw_image("BadUSB.bmp",
			VB_SCALE_HALF, VB_SCALE_HALF,
			VB_SIZE_AUTO, VB_ICON_HEIGHT,
			PIVOT_H_LEFT|PIVOT_V_TOP));
	return VBERROR_SUCCESS;
}

static VbError_t vboot_draw_recovery_insert(uint32_t locale)
{
	RETURN_ON_ERROR(vboot_draw_base_screen(locale));
	RETURN_ON_ERROR(draw_icon("Warning.bmp"));
	RETURN_ON_ERROR(draw_image_locale("insert.bmp", locale,
			VB_SCALE_HALF, VB_SCALE_HALF,
			VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_CENTER|PIVOT_V_TOP));
	return VBERROR_SUCCESS;
}

static VbError_t vboot_draw_recovery_to_dev(uint32_t locale)
{
	RETURN_ON_ERROR(vboot_draw_base_screen(locale));
	RETURN_ON_ERROR(draw_image_locale("todev.bmp", locale,
			VB_SCALE_HALF, VB_SCALE_HALF,
			VB_SIZE_AUTO, VB_TEXT_HEIGHT * 4,
			PIVOT_H_CENTER|PIVOT_V_CENTER));
	return VBERROR_SUCCESS;
}

static VbError_t vboot_draw_developer_to_norm(uint32_t locale)
{
	RETURN_ON_ERROR(vboot_draw_base_screen(locale));
	RETURN_ON_ERROR(draw_icon("VerificationOff.bmp"));
	RETURN_ON_ERROR(draw_image_locale("verif_off.bmp", locale,
			VB_SCALE_HALF, VB_SCALE_HALF,
			VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_CENTER|PIVOT_V_TOP));
	RETURN_ON_ERROR(draw_image_locale("tonorm.bmp", locale,
			VB_SCALE_HALF, VB_SCALE_HALF + VB_TEXT_HEIGHT,
			VB_SIZE_AUTO, VB_TEXT_HEIGHT * 3,
			PIVOT_H_CENTER|PIVOT_V_TOP));
	return VBERROR_SUCCESS;
}

static VbError_t vboot_draw_wait(uint32_t locale)
{
	RETURN_ON_ERROR(vboot_draw_base_screen(locale));
	RETURN_ON_ERROR(draw_image_locale("update.bmp", locale,
			VB_SCALE_HALF, VB_SCALE_HALF,
			VB_SIZE_AUTO, VB_TEXT_HEIGHT * 3,
			PIVOT_H_CENTER|PIVOT_V_CENTER));
	return VBERROR_SUCCESS;
}

static VbError_t vboot_draw_to_norm_confirmed(uint32_t locale)
{
	RETURN_ON_ERROR(vboot_draw_base_screen(locale));
	RETURN_ON_ERROR(draw_icon("VerificationOn.bmp"));
	RETURN_ON_ERROR(draw_image_locale("verif_on.bmp", locale,
			VB_SCALE_HALF, VB_SCALE_HALF,
			VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_CENTER|PIVOT_V_TOP));
	RETURN_ON_ERROR(draw_image_locale("reboot_erase.bmp", locale,
			VB_SCALE_HALF, VB_SCALE_HALF + VB_TEXT_HEIGHT,
			VB_SIZE_AUTO, VB_TEXT_HEIGHT,
			PIVOT_H_CENTER|PIVOT_V_TOP));
	return VBERROR_SUCCESS;
}

static VbError_t vboot_draw_os_broken(uint32_t locale)
{
	RETURN_ON_ERROR(vboot_draw_base_screen(locale));
	RETURN_ON_ERROR(draw_image_locale("os_broken.bmp", locale,
			VB_SCALE_HALF, VB_SCALE_HALF,
			VB_SIZE_AUTO, VB_TEXT_HEIGHT * 2,
			PIVOT_H_CENTER|PIVOT_V_CENTER));
	return VBERROR_SUCCESS;
}

/* we may export this in the future for the board customization */
struct vboot_screen_descriptor {
	uint32_t id;				/* VB_SCREEN_* */
	VbError_t (*draw)(uint32_t locale);	/* draw function */
	const char *mesg;			/* fallback message */
};

static const struct vboot_screen_descriptor vboot_screens[] = {
	{
		.id = VB_SCREEN_BLANK,
		.draw = vboot_draw_blank,
		.mesg = NULL,
	},
	{
		.id = VB_SCREEN_DEVELOPER_WARNING,
		.draw = vboot_draw_developer_warning,
		.mesg = "OS verification is OFF\n"
			"Press SPACE to re-enable.\n",
	},
	{
		.id = VB_SCREEN_RECOVERY_REMOVE,
		.draw = vboot_draw_recovery_remove,
		.mesg = "Please remove all external devices to begin recovery\n",
	},
	{
		.id = VB_SCREEN_RECOVERY_NO_GOOD,
		.draw = vboot_draw_recovery_no_good,
		.mesg = "The device you inserted does not contain Chrome OS.\n",
	},
	{
		.id = VB_SCREEN_RECOVERY_INSERT,
		.draw = vboot_draw_recovery_insert,
		.mesg = "Chrome OS is missing or damaged.\n"
			"Please insert a recovery USB stick or SD card.\n",
	},
	{
		.id = VB_SCREEN_RECOVERY_TO_DEV,
		.draw = vboot_draw_recovery_to_dev,
		.mesg = "To turn OS verificaion OFF, press ENTER.\n"
			"Your system will reboot and local data will be cleared.\n"
			"To go back, press ESC.\n",
	},
	{
		.id = VB_SCREEN_DEVELOPER_TO_NORM,
		.draw = vboot_draw_developer_to_norm,
		.mesg = "OS verification is OFF\n"
			"Press ENTER to confirm you wish to turn OS verification on.\n"
			"Your system will reboot and local data will be cleared.\n"
			"To go back, press ESC.\n",
	},
	{
		.id = VB_SCREEN_WAIT,
		.draw = vboot_draw_wait,
		.mesg = "Your system is applying a critical update.\n"
			"Please do not turn off.\n",
	},
	{
		.id = VB_SCREEN_TO_NORM_CONFIRMED,
		.draw = vboot_draw_to_norm_confirmed,
		.mesg = "OS verification is ON\n"
			"Your system will reboot and local data will be cleared.\n",
	},
	{
		.id = VB_SCREEN_OS_BROKEN,
		.draw = vboot_draw_os_broken,
		.mesg = "Chrome OS may be broken.\n"
			"Remove media and initiate recovery.\n",
	},
};

static const struct vboot_screen_descriptor *get_screen_descriptor(uint32_t id)
{
	int i;
	for (i = 0; i < ARRAY_SIZE(vboot_screens); i++) {
		if (vboot_screens[i].id == id)
			return &vboot_screens[i];
	}
	return NULL;
}

static void print_fallback_message(const struct vboot_screen_descriptor *desc)
{
	const struct rgb_color white = { 0xff, 0xff, 0xff };

	if (desc->mesg)
		graphics_print_single_text_block(desc->mesg, &white, 0, 15,
						 VIDEO_PRINTF_ALIGN_CENTER);
	else
		clear_screen(&white);
}

static VbError_t draw_screen(uint32_t screen_type, uint32_t locale)
{
	VbError_t rv = VBERROR_UNKNOWN;
	const struct vboot_screen_descriptor *desc;

	desc = get_screen_descriptor(screen_type);
	if (!desc) {
		printf("Not a valid screen type: 0x%x\n", screen_type);
		return VBERROR_INVALID_SCREEN_INDEX;
	}

	if (locale >= locale_count) {
		printf("Unsupported locale (%d)\n", locale);
		print_fallback_message(desc);
		return VBERROR_INVALID_PARAMETER;
	}

	/* if no drawing function is registered, fallback msg will be printed */
	if (desc->draw)
		rv = desc->draw(locale);
	if (rv)
		print_fallback_message(desc);

	return rv;
}

static void vboot_init_locale(void)
{
	char *locales, *loc_start, *loc;
	size_t size;

	locale_count = 0;

	/* Load locale list from cbfs */
	locales = cbfs_get_file_content(CBFS_DEFAULT_MEDIA, "locales",
					CBFS_TYPE_RAW, &size);
	if (!locales || !size) {
		printf("%s: locale list not found", __func__);
		return;
	}

	/* Copy the file and null-terminate it */
	loc_start = malloc(size + 1);
	if (!loc_start) {
		printf("%s: out of memory\n", __func__);
		free(locales);
		return;
	}
	memcpy(loc_start, locales, size);
	loc_start[size] = '\0';

	/* Parse the list */
	printf("%s: Supported locales:", __func__);
	loc = loc_start;
	while (loc - loc_start < size
			&& locale_count < ARRAY_SIZE(supported_locales)) {
		char *lang = strsep(&loc, "\n");
		if (!lang || !strlen(lang))
			break;
		printf(" %s,", lang);
		supported_locales[locale_count] = lang;
		locale_count++;
	}
	free(locales);
	printf(" (%d locales)\n", locale_count);
}

static VbError_t vboot_init_screen(void)
{
	vboot_init_locale();

	if (graphics_init())
		return VBERROR_UNKNOWN;

	initialized = 1;

	return VBERROR_SUCCESS;
}

int vboot_draw_screen(uint32_t screen, uint32_t locale)
{
	static uint32_t current_screen = VB_SCREEN_BLANK;
	static uint32_t current_locale = 0;

	printf("%s: screen=0x%x locale=%d\n", __func__, screen, locale);

	if (!initialized) {
		if (vboot_init_screen())
			return VBERROR_UNKNOWN;
	}

	/* If requested screen is the same as the current one, we're done. */
	if (screen == current_screen && locale == current_locale)
		return VBERROR_SUCCESS;

	/* If the screen is blank, turn off the backlight; else turn it on. */
	backlight_update(VB_SCREEN_BLANK == screen ? 0 : 1);

	/* TODO: draw only locale dependent part if current_screen == screen */
	RETURN_ON_ERROR(draw_screen(screen, locale));

	current_screen = screen;
	current_locale = locale;

	return VBERROR_SUCCESS;
}

int vboot_get_locale_count(void)
{
	if (!initialized) {
		if (vboot_init_screen())
			return VBERROR_UNKNOWN;
	}
	return locale_count;
}
