/*
 * Copyright (c) 2017 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * References:
 *
 * https://www.microbit.co.uk/device/screen
 * https://lancaster-university.github.io/microbit-docs/ubit/display/
 */

#include <zephyr.h>
#include <init.h>
#include <gpio.h>
#include <device.h>
#include <string.h>
#include <misc/printk.h>

#include <display/mb_display.h>

#include "mb_font.h"

#define MODE_MASK    BIT_MASK(16)

/* Onboard LED Row 1 */
#define LED_ROW1_GPIO_PIN   13
#define LED_ROW1_GPIO_PORT  DT_GPIO_P0_DEV_NAME

/* Onboard LED Row 2 */
#define LED_ROW2_GPIO_PIN   14
#define LED_ROW2_GPIO_PORT  DT_GPIO_P0_DEV_NAME

/* Onboard LED Row 3 */
#define LED_ROW3_GPIO_PIN   15
#define LED_ROW3_GPIO_PORT  DT_GPIO_P0_DEV_NAME

/* Onboard LED Column 1 */
#define LED_COL1_GPIO_PIN   4
#define LED_COL1_GPIO_PORT  DT_GPIO_P0_DEV_NAME

/* Onboard LED Column 2 */
#define LED_COL2_GPIO_PIN   5
#define LED_COL2_GPIO_PORT  DT_GPIO_P0_DEV_NAME

/* Onboard LED Column 3 */
#define LED_COL3_GPIO_PIN   6
#define LED_COL3_GPIO_PORT  DT_GPIO_P0_DEV_NAME

/* Onboard LED Column 4 */
#define LED_COL4_GPIO_PIN   7
#define LED_COL4_GPIO_PORT  DT_GPIO_P0_DEV_NAME

/* Onboard LED Column 5 */
#define LED_COL5_GPIO_PIN   8
#define LED_COL5_GPIO_PORT  DT_GPIO_P0_DEV_NAME

/* Onboard LED Column 6 */
#define LED_COL6_GPIO_PIN   9
#define LED_COL6_GPIO_PORT  DT_GPIO_P0_DEV_NAME

/* Onboard LED Column 7 */
#define LED_COL7_GPIO_PIN   10
#define LED_COL7_GPIO_PORT  DT_GPIO_P0_DEV_NAME

/* Onboard LED Column 8 */
#define LED_COL8_GPIO_PIN   11
#define LED_COL8_GPIO_PORT  DT_GPIO_P0_DEV_NAME

/* Onboard LED Column 9 */
#define LED_COL9_GPIO_PIN   12
#define LED_COL9_GPIO_PORT  DT_GPIO_P0_DEV_NAME


#define DISPLAY_ROWS 3
#define DISPLAY_COLS 9

#define SCROLL_OFF   0
#define SCROLL_START 1

#define SCROLL_DEFAULT_DURATION K_MSEC(80)

struct mb_display {
	struct device  *dev;         /* GPIO device */

	struct k_timer  timer;       /* Rendering timer */

	u8_t            img_count;   /* Image count */

	u8_t            cur_img;     /* Current image or character to show */

	u8_t            scroll:3,    /* Scroll shift */
			first:1,     /* First frame of a scroll sequence */
			loop:1,      /* Loop to beginning */
			text:1,      /* We're showing a string (not image) */
			img_sep:1;   /* One column image separation */

	/* The following variables track the currently shown image */
	u8_t            cur;         /* Currently rendered row */
	u32_t           row[3];      /* Content (columns) for each row */
	s64_t           expiry;      /* When to stop showing current image */
	s32_t           duration;    /* Duration for each shown image */

	union {
		const struct mb_image *img; /* Array of images to show */
		const char            *str; /* String to be shown */
	};

	/* Buffer for printed strings */
	char            str_buf[CONFIG_MICROBIT_DISPLAY_STR_MAX];
};

struct x_y {
	u8_t x:4,
	     y:4;
};

/* Where the X,Y coordinates of each row/col are found.
 * The top left corner has the coordinates 0,0.
 */
static const struct x_y map[DISPLAY_ROWS][DISPLAY_COLS] = {
	{{0, 0}, {2, 0}, {4, 0}, {4, 3}, {3, 3}, {2, 3}, {1, 3}, {0, 3}, {1, 2} },
	{{4, 2}, {0, 2}, {2, 2}, {1, 0}, {3, 0}, {3, 4}, {1, 4}, {0, 0}, {0, 0} },
	{{2, 4}, {4, 4}, {0, 4}, {0, 1}, {1, 1}, {2, 1}, {3, 1}, {4, 1}, {3, 2} },
};

/* Mask of all the column bits */
static const u32_t col_mask = (((~0UL) << LED_COL1_GPIO_PIN) &
			       ((~0UL) >> (31 - LED_COL9_GPIO_PIN)));

static inline const struct mb_image *get_font(char ch)
{
	if (ch < MB_FONT_START || ch > MB_FONT_END) {
		return &mb_font[' ' - MB_FONT_START];
	}

	return &mb_font[ch - MB_FONT_START];
}

#define GET_PIXEL(img, x, y) ((img)->row[y] & BIT(x))

/* Precalculate all three rows of an image and start the rendering. */
static void start_image(struct mb_display *disp, const struct mb_image *img)
{
	int row, col;

	for (row = 0; row < DISPLAY_ROWS; row++) {
		disp->row[row] = 0U;

		for (col = 0; col < DISPLAY_COLS; col++) {
			if (GET_PIXEL(img, map[row][col].x, map[row][col].y)) {
				disp->row[row] |= BIT(LED_COL1_GPIO_PIN + col);
			}
		}

		disp->row[row] = ~disp->row[row] & col_mask;
		disp->row[row] |= BIT(LED_ROW1_GPIO_PIN + row);
	}

	disp->cur = 0U;

	if (disp->duration == K_FOREVER) {
		disp->expiry = K_FOREVER;
	} else {
		disp->expiry = k_uptime_get() + disp->duration;
	}

	k_timer_start(&disp->timer, K_NO_WAIT, K_MSEC(4));
}

#define ROW_PIN(n) (LED_ROW1_GPIO_PIN + (n))

static inline void update_pins(struct mb_display *disp, u32_t val)
{
	u32_t pin, prev = (disp->cur + 2) % 3;

	/* Disable the previous row */
	gpio_pin_write(disp->dev, ROW_PIN(prev), 0);

	/* Set the column pins to their correct values */
	for (pin = LED_COL1_GPIO_PIN; pin <= LED_COL9_GPIO_PIN; pin++) {
		gpio_pin_write(disp->dev, pin, !!(val & BIT(pin)));
	}

	/* Enable the new row */
	gpio_pin_write(disp->dev, ROW_PIN(disp->cur), 1);
}

static void reset_display(struct mb_display *disp)
{
	k_timer_stop(&disp->timer);

	disp->str = NULL;
	disp->cur_img = 0U;
	disp->img = NULL;
	disp->img_count = 0U;
	disp->scroll = SCROLL_OFF;
}

static const struct mb_image *current_img(struct mb_display *disp)
{
	if (disp->scroll && disp->first) {
		return get_font(' ');
	}

	if (disp->text) {
		return get_font(disp->str[disp->cur_img]);
	} else {
		return &disp->img[disp->cur_img];
	}
}

static const struct mb_image *next_img(struct mb_display *disp)
{
	if (disp->text) {
		if (disp->first) {
			return get_font(disp->str[0]);
		} else if (disp->str[disp->cur_img]) {
			return get_font(disp->str[disp->cur_img + 1]);
		} else {
			return get_font(' ');
		}
	} else {
		if (disp->first) {
			return &disp->img[0];
		} else if (disp->cur_img < (disp->img_count - 1)) {
			return &disp->img[disp->cur_img + 1];
		} else {
			return get_font(' ');
		}
	}
}

static inline bool last_frame(struct mb_display *disp)
{
	if (disp->text) {
		return (disp->str[disp->cur_img] == '\0');
	} else {
		return (disp->cur_img >= disp->img_count);
	}
}

static inline u8_t scroll_steps(struct mb_display *disp)
{
	return 5 + disp->img_sep;
}

static void update_scroll(struct mb_display *disp)
{
	if (disp->scroll < scroll_steps(disp)) {
		struct mb_image img;
		int i;

		for (i = 0; i < 5; i++) {
			const struct mb_image *i1 = current_img(disp);
			const struct mb_image *i2 = next_img(disp);

			img.row[i] = ((i1->row[i] >> disp->scroll) |
				      (i2->row[i] << (scroll_steps(disp) -
						      disp->scroll)));
		}

		disp->scroll++;
		start_image(disp, &img);
	} else {
		if (disp->first) {
			disp->first = 0U;
		} else {
			disp->cur_img++;
		}

		if (last_frame(disp)) {
			if (!disp->loop) {
				reset_display(disp);
				return;
			}

			disp->cur_img = 0U;
			disp->first = 1U;
		}

		disp->scroll = SCROLL_START;
		start_image(disp, current_img(disp));
	}
}

static void update_image(struct mb_display *disp)
{
	disp->cur_img++;

	if (last_frame(disp)) {
		if (!disp->loop) {
			reset_display(disp);
			return;
		}

		disp->cur_img = 0U;
	}

	start_image(disp, current_img(disp));
}

static void show_row(struct k_timer *timer)
{
	struct mb_display *disp = CONTAINER_OF(timer, struct mb_display, timer);

	update_pins(disp, disp->row[disp->cur]);
	disp->cur = (disp->cur + 1) % DISPLAY_ROWS;

	if (disp->cur == 0U && disp->expiry != K_FOREVER &&
	    k_uptime_get() > disp->expiry) {
		if (disp->scroll) {
			update_scroll(disp);
		} else {
			update_image(disp);
		}
	}
}

static void clear_display(struct k_timer *timer)
{
	struct mb_display *disp = CONTAINER_OF(timer, struct mb_display, timer);

	update_pins(disp, col_mask);
}

static struct mb_display display = {
	.timer = _K_TIMER_INITIALIZER(display.timer, show_row, clear_display),
};

static void start_scroll(struct mb_display *disp, s32_t duration)
{
	/* Divide total duration by number of scrolling steps */
	if (duration) {
		disp->duration = duration / scroll_steps(disp);
	} else {
		disp->duration = SCROLL_DEFAULT_DURATION;
	}

	disp->scroll = SCROLL_START;
	disp->first = 1U;
	disp->cur_img = 0U;
	start_image(disp, get_font(' '));
}

static void start_single(struct mb_display *disp, s32_t duration)
{
	disp->duration = duration;

	if (disp->text) {
		start_image(disp, get_font(disp->str[0]));
	} else {
		start_image(disp, disp->img);
	}
}

void mb_display_image(struct mb_display *disp, u32_t mode, s32_t duration,
		      const struct mb_image *img, u8_t img_count)
{
	reset_display(disp);

	__ASSERT(img && img_count > 0, "Invalid parameters");

	disp->text = 0U;
	disp->img_count = img_count;
	disp->img = img;
	disp->img_sep = 0U;
	disp->cur_img = 0U;
	disp->loop = !!(mode & MB_DISPLAY_FLAG_LOOP);

	switch (mode & MODE_MASK) {
	case MB_DISPLAY_MODE_DEFAULT:
	case MB_DISPLAY_MODE_SINGLE:
		start_single(disp, duration);
		break;
	case MB_DISPLAY_MODE_SCROLL:
		start_scroll(disp, duration);
		break;
	default:
		__ASSERT(0, "Invalid display mode");
	}
}

void mb_display_stop(struct mb_display *disp)
{
	reset_display(disp);
}

void mb_display_print(struct mb_display *disp, u32_t mode,
		      s32_t duration, const char *fmt, ...)
{
	va_list ap;

	reset_display(disp);

	va_start(ap, fmt);
	vsnprintk(disp->str_buf, sizeof(disp->str_buf), fmt, ap);
	va_end(ap);

	if (disp->str_buf[0] == '\0') {
		return;
	}

	disp->str = disp->str_buf;
	disp->text = 1U;
	disp->img_sep = 1U;
	disp->cur_img = 0U;
	disp->loop = !!(mode & MB_DISPLAY_FLAG_LOOP);

	switch (mode & MODE_MASK) {
	case MB_DISPLAY_MODE_DEFAULT:
	case MB_DISPLAY_MODE_SCROLL:
		start_scroll(disp, duration);
		break;
	case MB_DISPLAY_MODE_SINGLE:
		start_single(disp, duration);
		break;
	default:
		__ASSERT(0, "Invalid display mode");
	}
}

struct mb_display *mb_display_get(void)
{
	return &display;
}

static int mb_display_init(struct device *dev)
{
	ARG_UNUSED(dev);

	display.dev = device_get_binding(DT_GPIO_P0_DEV_NAME);

	__ASSERT(dev, "No GPIO device found");

	gpio_pin_configure(display.dev, LED_ROW1_GPIO_PIN, GPIO_DIR_OUT);
	gpio_pin_configure(display.dev, LED_ROW2_GPIO_PIN, GPIO_DIR_OUT);
	gpio_pin_configure(display.dev, LED_ROW3_GPIO_PIN, GPIO_DIR_OUT);
	gpio_pin_configure(display.dev, LED_COL1_GPIO_PIN, GPIO_DIR_OUT);
	gpio_pin_configure(display.dev, LED_COL2_GPIO_PIN, GPIO_DIR_OUT);
	gpio_pin_configure(display.dev, LED_COL3_GPIO_PIN, GPIO_DIR_OUT);
	gpio_pin_configure(display.dev, LED_COL4_GPIO_PIN, GPIO_DIR_OUT);
	gpio_pin_configure(display.dev, LED_COL5_GPIO_PIN, GPIO_DIR_OUT);
	gpio_pin_configure(display.dev, LED_COL6_GPIO_PIN, GPIO_DIR_OUT);
	gpio_pin_configure(display.dev, LED_COL7_GPIO_PIN, GPIO_DIR_OUT);
	gpio_pin_configure(display.dev, LED_COL8_GPIO_PIN, GPIO_DIR_OUT);
	gpio_pin_configure(display.dev, LED_COL9_GPIO_PIN, GPIO_DIR_OUT);

	return 0;
}

SYS_INIT(mb_display_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE);
