/*
 * 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/cbfs/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;
}
