// SPDX-License-Identifier: GPL-2.0+
/*
 * Implementation of a scene, a collection of text/image/menu items in an expo
 *
 * Copyright 2022 Google LLC
 * Written by Simon Glass <sjg@chromium.org>
 */

#define LOG_CATEGORY	LOGC_EXPO

#include <common.h>
#include <dm.h>
#include <expo.h>
#include <malloc.h>
#include <mapmem.h>
#include <menu.h>
#include <video.h>
#include <video_console.h>
#include <linux/input.h>
#include "scene_internal.h"

int scene_new(struct expo *exp, const char *name, uint id, struct scene **scnp)
{
	struct scene *scn;

	scn = calloc(1, sizeof(struct scene));
	if (!scn)
		return log_msg_ret("expo", -ENOMEM);
	scn->name = strdup(name);
	if (!scn->name) {
		free(scn);
		return log_msg_ret("name", -ENOMEM);
	}

	INIT_LIST_HEAD(&scn->obj_head);
	scn->id = resolve_id(exp, id);
	scn->expo = exp;
	list_add_tail(&scn->sibling, &exp->scene_head);

	*scnp = scn;

	return scn->id;
}

void scene_obj_destroy(struct scene_obj *obj)
{
	if (obj->type == SCENEOBJT_MENU)
		scene_menu_destroy((struct scene_obj_menu *)obj);
	free(obj->name);
	free(obj);
}

void scene_destroy(struct scene *scn)
{
	struct scene_obj *obj, *next;

	list_for_each_entry_safe(obj, next, &scn->obj_head, sibling)
		scene_obj_destroy(obj);

	free(scn->name);
	free(scn);
}

int scene_title_set(struct scene *scn, uint id)
{
	scn->title_id = id;

	return 0;
}

int scene_obj_count(struct scene *scn)
{
	struct scene_obj *obj;
	int count = 0;

	list_for_each_entry(obj, &scn->obj_head, sibling)
		count++;

	return count;
}

void *scene_obj_find(struct scene *scn, uint id, enum scene_obj_t type)
{
	struct scene_obj *obj;

	list_for_each_entry(obj, &scn->obj_head, sibling) {
		if (obj->id == id &&
		    (type == SCENEOBJT_NONE || obj->type == type))
			return obj;
	}

	return NULL;
}

void *scene_obj_find_by_name(struct scene *scn, const char *name)
{
	struct scene_obj *obj;

	list_for_each_entry(obj, &scn->obj_head, sibling) {
		if (!strcmp(name, obj->name))
			return obj;
	}

	return NULL;
}

int scene_obj_add(struct scene *scn, const char *name, uint id,
		  enum scene_obj_t type, uint size, struct scene_obj **objp)
{
	struct scene_obj *obj;

	obj = calloc(1, size);
	if (!obj)
		return log_msg_ret("obj", -ENOMEM);
	obj->name = strdup(name);
	if (!obj->name) {
		free(obj);
		return log_msg_ret("name", -ENOMEM);
	}

	obj->id = resolve_id(scn->expo, id);
	obj->scene = scn;
	obj->type = type;
	list_add_tail(&obj->sibling, &scn->obj_head);
	*objp = obj;

	return obj->id;
}

int scene_img(struct scene *scn, const char *name, uint id, char *data,
	      struct scene_obj_img **imgp)
{
	struct scene_obj_img *img;
	int ret;

	ret = scene_obj_add(scn, name, id, SCENEOBJT_IMAGE,
			    sizeof(struct scene_obj_img),
			    (struct scene_obj **)&img);
	if (ret < 0)
		return log_msg_ret("obj", -ENOMEM);

	img->data = data;

	if (imgp)
		*imgp = img;

	return img->obj.id;
}

int scene_txt(struct scene *scn, const char *name, uint id, uint str_id,
	      struct scene_obj_txt **txtp)
{
	struct scene_obj_txt *txt;
	int ret;

	ret = scene_obj_add(scn, name, id, SCENEOBJT_TEXT,
			    sizeof(struct scene_obj_txt),
			    (struct scene_obj **)&txt);
	if (ret < 0)
		return log_msg_ret("obj", -ENOMEM);

	txt->str_id = str_id;

	if (txtp)
		*txtp = txt;

	return txt->obj.id;
}

int scene_txt_str(struct scene *scn, const char *name, uint id, uint str_id,
		  const char *str, struct scene_obj_txt **txtp)
{
	struct scene_obj_txt *txt;
	int ret;

	ret = expo_str(scn->expo, name, str_id, str);
	if (ret < 0)
		return log_msg_ret("str", ret);
	else if (ret != str_id)
		return log_msg_ret("id", -EEXIST);

	ret = scene_obj_add(scn, name, id, SCENEOBJT_TEXT,
			    sizeof(struct scene_obj_txt),
			    (struct scene_obj **)&txt);
	if (ret < 0)
		return log_msg_ret("obj", -ENOMEM);

	txt->str_id = str_id;

	if (txtp)
		*txtp = txt;

	return txt->obj.id;
}

int scene_txt_set_font(struct scene *scn, uint id, const char *font_name,
		       uint font_size)
{
	struct scene_obj_txt *txt;

	txt = scene_obj_find(scn, id, SCENEOBJT_TEXT);
	if (!txt)
		return log_msg_ret("find", -ENOENT);
	txt->font_name = font_name;
	txt->font_size = font_size;

	return 0;
}

int scene_obj_set_pos(struct scene *scn, uint id, int x, int y)
{
	struct scene_obj *obj;

	obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
	if (!obj)
		return log_msg_ret("find", -ENOENT);
	obj->dim.x = x;
	obj->dim.y = y;

	return 0;
}

int scene_obj_set_size(struct scene *scn, uint id, int w, int h)
{
	struct scene_obj *obj;

	obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
	if (!obj)
		return log_msg_ret("find", -ENOENT);
	obj->dim.w = w;
	obj->dim.h = h;

	return 0;
}

int scene_obj_set_hide(struct scene *scn, uint id, bool hide)
{
	int ret;

	ret = scene_obj_flag_clrset(scn, id, SCENEOF_HIDE,
				    hide ? SCENEOF_HIDE : 0);
	if (ret)
		return log_msg_ret("flg", ret);

	return 0;
}

int scene_obj_flag_clrset(struct scene *scn, uint id, uint clr, uint set)
{
	struct scene_obj *obj;

	obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
	if (!obj)
		return log_msg_ret("find", -ENOENT);
	obj->flags &= ~clr;
	obj->flags |= set;

	return 0;
}

int scene_obj_get_hw(struct scene *scn, uint id, int *widthp)
{
	struct scene_obj *obj;

	obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
	if (!obj)
		return log_msg_ret("find", -ENOENT);

	switch (obj->type) {
	case SCENEOBJT_NONE:
	case SCENEOBJT_MENU:
		break;
	case SCENEOBJT_IMAGE: {
		struct scene_obj_img *img = (struct scene_obj_img *)obj;
		ulong width, height;
		uint bpix;

		video_bmp_get_info(img->data, &width, &height, &bpix);
		if (widthp)
			*widthp = width;
		return height;
	}
	case SCENEOBJT_TEXT: {
		struct scene_obj_txt *txt = (struct scene_obj_txt *)obj;
		struct expo *exp = scn->expo;
		struct vidconsole_bbox bbox;
		const char *str;
		int len, ret;

		str = expo_get_str(exp, txt->str_id);
		if (!str)
			return log_msg_ret("str", -ENOENT);
		len = strlen(str);

		/* if there is no console, make it up */
		if (!exp->cons) {
			if (widthp)
				*widthp = 8 * len;
			return 16;
		}

		ret = vidconsole_measure(scn->expo->cons, txt->font_name,
					 txt->font_size, str, &bbox);
		if (ret)
			return log_msg_ret("mea", ret);
		if (widthp)
			*widthp = bbox.x1;

		return bbox.y1;
	}
	}

	return 0;
}

/**
 * scene_obj_render() - Render an object
 *
 */
static int scene_obj_render(struct scene_obj *obj, bool text_mode)
{
	struct scene *scn = obj->scene;
	struct expo *exp = scn->expo;
	const struct expo_theme *theme = &exp->theme;
	struct udevice *dev = exp->display;
	struct udevice *cons = text_mode ? NULL : exp->cons;
	int x, y, ret;

	x = obj->dim.x;
	y = obj->dim.y;

	switch (obj->type) {
	case SCENEOBJT_NONE:
		break;
	case SCENEOBJT_IMAGE: {
		struct scene_obj_img *img = (struct scene_obj_img *)obj;

		if (!cons)
			return -ENOTSUPP;
		ret = video_bmp_display(dev, map_to_sysmem(img->data), x, y,
					true);
		if (ret < 0)
			return log_msg_ret("img", ret);
		break;
	}
	case SCENEOBJT_TEXT: {
		struct scene_obj_txt *txt = (struct scene_obj_txt *)obj;
		const char *str;

		if (!cons)
			return -ENOTSUPP;

		if (txt->font_name || txt->font_size) {
			ret = vidconsole_select_font(cons,
						     txt->font_name,
						     txt->font_size);
		} else {
			ret = vidconsole_select_font(cons, NULL, 0);
		}
		if (ret && ret != -ENOSYS)
			return log_msg_ret("font", ret);
		str = expo_get_str(exp, txt->str_id);
		if (str) {
			struct video_priv *vid_priv;
			struct vidconsole_colour old;
			enum colour_idx fore, back;

			if (CONFIG_IS_ENABLED(SYS_WHITE_ON_BLACK)) {
				fore = VID_BLACK;
				back = VID_WHITE;
			} else {
				fore = VID_LIGHT_GRAY;
				back = VID_BLACK;
			}

			vid_priv = dev_get_uclass_priv(dev);
			if (obj->flags & SCENEOF_POINT) {
				vidconsole_push_colour(cons, fore, back, &old);
				video_fill_part(dev, x - theme->menu_inset, y,
						x + obj->dim.w,
						y + obj->dim.h,
						vid_priv->colour_bg);
			}
			vidconsole_set_cursor_pos(cons, x, y);
			vidconsole_put_string(cons, str);
			if (obj->flags & SCENEOF_POINT)
				vidconsole_pop_colour(cons, &old);
		}
		break;
	}
	case SCENEOBJT_MENU: {
		struct scene_obj_menu *menu = (struct scene_obj_menu *)obj;

		if (exp->popup && (obj->flags & SCENEOF_OPEN)) {
			if (!cons)
				return -ENOTSUPP;

			/* draw a background behind the menu items */
			scene_menu_render(menu);
		}
		/*
		 * With a vidconsole, the text and item pointer are rendered as
		 * normal objects so we don't need to do anything here. The menu
		 * simply controls where they are positioned.
		 */
		if (cons)
			return -ENOTSUPP;

		ret = scene_menu_display(menu);
		if (ret < 0)
			return log_msg_ret("img", ret);

		break;
	}
	}

	return 0;
}

int scene_arrange(struct scene *scn)
{
	struct scene_obj *obj;
	int ret;

	list_for_each_entry(obj, &scn->obj_head, sibling) {
		if (obj->type == SCENEOBJT_MENU) {
			struct scene_obj_menu *menu;

			menu = (struct scene_obj_menu *)obj,
			ret = scene_menu_arrange(scn, menu);
			if (ret)
				return log_msg_ret("arr", ret);
		}
	}

	return 0;
}

int scene_render_deps(struct scene *scn, uint id)
{
	struct scene_obj *obj;
	int ret;

	if (!id)
		return 0;
	obj = scene_obj_find(scn, id, SCENEOBJT_NONE);
	if (!obj)
		return log_msg_ret("obj", -ENOENT);

	if (!(obj->flags & SCENEOF_HIDE)) {
		ret = scene_obj_render(obj, false);
		if (ret && ret != -ENOTSUPP)
			return log_msg_ret("ren", ret);

		if (obj->type == SCENEOBJT_MENU)
			scene_menu_render_deps(scn,
					       (struct scene_obj_menu *)obj);
	}

	return 0;
}

int scene_render(struct scene *scn)
{
	struct expo *exp = scn->expo;
	struct scene_obj *obj;
	int ret;

	list_for_each_entry(obj, &scn->obj_head, sibling) {
		if (!(obj->flags & SCENEOF_HIDE)) {
			ret = scene_obj_render(obj, exp->text_mode);
			if (ret && ret != -ENOTSUPP)
				return log_msg_ret("ren", ret);
		}
	}

	/* render any highlighted object on top of the others */
	if (scn->highlight_id && !exp->text_mode) {
		ret = scene_render_deps(scn, scn->highlight_id);
		if (ret && ret != -ENOTSUPP)
			return log_msg_ret("dep", ret);
	}

	return 0;
}

/**
 * send_key_obj() - Handle a keypress for moving between objects
 *
 * @scn: Scene to receive the key
 * @key: Key to send (KEYCODE_UP)
 * @event: Returns resulting event from this keypress
 * Returns: 0 if OK, -ve on error
 */
static void send_key_obj(struct scene *scn, struct scene_obj *obj, int key,
			 struct expo_action *event)
{
	switch (key) {
	case BKEY_UP:
		while (obj != list_first_entry(&scn->obj_head, struct scene_obj,
					       sibling)) {
			obj = list_entry(obj->sibling.prev,
					 struct scene_obj, sibling);
			if (obj->type == SCENEOBJT_MENU) {
				event->type = EXPOACT_POINT_OBJ;
				event->select.id = obj->id;
				log_debug("up to obj %d\n", event->select.id);
				break;
			}
		}
		break;
	case BKEY_DOWN:
		while (!list_is_last(&obj->sibling, &scn->obj_head)) {
			obj = list_entry(obj->sibling.next, struct scene_obj,
					 sibling);
			if (obj->type == SCENEOBJT_MENU) {
				event->type = EXPOACT_POINT_OBJ;
				event->select.id = obj->id;
				log_debug("down to obj %d\n", event->select.id);
				break;
			}
		}
		break;
	case BKEY_SELECT:
		if (obj->type == SCENEOBJT_MENU) {
			event->type = EXPOACT_OPEN;
			event->select.id = obj->id;
			log_debug("open obj %d\n", event->select.id);
		}
		break;
	case BKEY_QUIT:
		event->type = EXPOACT_QUIT;
		log_debug("obj quit\n");
		break;
	}
}

int scene_send_key(struct scene *scn, int key, struct expo_action *event)
{
	struct scene_obj_menu *menu;
	struct scene_obj *obj;
	int ret;

	event->type = EXPOACT_NONE;

	/*
	 * In 'popup' mode, arrow keys move betwen objects, unless a menu is
	 * opened
	 */
	if (scn->expo->popup) {
		obj = NULL;
		if (scn->highlight_id) {
			obj = scene_obj_find(scn, scn->highlight_id,
					     SCENEOBJT_NONE);
		}
		if (!obj)
			return 0;

		if (!(obj->flags & SCENEOF_OPEN)) {
			send_key_obj(scn, obj, key, event);
			return 0;
		}

		menu = (struct scene_obj_menu *)obj,
		ret = scene_menu_send_key(scn, menu, key, event);
		if (ret)
			return log_msg_ret("key", ret);
		return 0;
	}

	list_for_each_entry(obj, &scn->obj_head, sibling) {
		if (obj->type == SCENEOBJT_MENU) {
			struct scene_obj_menu *menu;

			menu = (struct scene_obj_menu *)obj,
			ret = scene_menu_send_key(scn, menu, key, event);
			if (ret)
				return log_msg_ret("key", ret);
			break;
		}
	}

	return 0;
}

int scene_calc_dims(struct scene *scn, bool do_menus)
{
	struct scene_obj *obj;
	int ret;

	list_for_each_entry(obj, &scn->obj_head, sibling) {
		switch (obj->type) {
		case SCENEOBJT_NONE:
		case SCENEOBJT_TEXT:
		case SCENEOBJT_IMAGE: {
			int width;

			if (!do_menus) {
				ret = scene_obj_get_hw(scn, obj->id, &width);
				if (ret < 0)
					return log_msg_ret("get", ret);
				obj->dim.w = width;
				obj->dim.h = ret;
			}
			break;
		}
		case SCENEOBJT_MENU: {
			struct scene_obj_menu *menu;

			if (do_menus) {
				menu = (struct scene_obj_menu *)obj;

				ret = scene_menu_calc_dims(menu);
				if (ret)
					return log_msg_ret("men", ret);
			}
			break;
		}
		}
	}

	return 0;
}

int scene_apply_theme(struct scene *scn, struct expo_theme *theme)
{
	struct scene_obj *obj;
	int ret;

	/* Avoid error-checking optional items */
	scene_txt_set_font(scn, scn->title_id, NULL, theme->font_size);

	list_for_each_entry(obj, &scn->obj_head, sibling) {
		switch (obj->type) {
		case SCENEOBJT_NONE:
		case SCENEOBJT_IMAGE:
		case SCENEOBJT_MENU:
			break;
		case SCENEOBJT_TEXT:
			scene_txt_set_font(scn, obj->id, NULL,
					   theme->font_size);
			break;
		}
	}

	ret = scene_arrange(scn);
	if (ret)
		return log_msg_ret("arr", ret);

	return 0;
}

void scene_set_highlight_id(struct scene *scn, uint id)
{
	scn->highlight_id = id;
}

void scene_highlight_first(struct scene *scn)
{
	struct scene_obj *obj;

	list_for_each_entry(obj, &scn->obj_head, sibling) {
		switch (obj->type) {
		case SCENEOBJT_MENU:
			scene_set_highlight_id(scn, obj->id);
			return;
		default:
			break;
		}
	}
}

int scene_set_open(struct scene *scn, uint id, bool open)
{
	int ret;

	ret = scene_obj_flag_clrset(scn, id, SCENEOF_OPEN,
				    open ? SCENEOF_OPEN : 0);
	if (ret)
		return log_msg_ret("flg", ret);

	return 0;
}
