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

#include <zephyr.h>
#include <sys/printk.h>
#include <board.h>
#include <drivers/gpio.h>
#include <device.h>
#include <string.h>
#include <drivers/pwm.h>
#include <debug/stack.h>

#include <display/mb_display.h>

#include <bluetooth/bluetooth.h>

#include "pong.h"

/* The micro:bit has a 5x5 LED display, using (x, y) notation the top-left
 * corner has coordinates (0, 0) and the bottom-right has (4, 4). To make
 * the game dynamics more natural, the uses a virtual 50x50 coordinate
 * system where top-left is (0, 0) and bottom-right is (49, 49).
 */

#define SCROLL_SPEED      400          /* Text scrolling speed */

#define PIXEL_SIZE        10           /* Virtual coordinates per real pixel */

#define GAME_REFRESH      K_MSEC(100)  /* Animation refresh rate of the game */

#define PADDLE_ROW        4            /* Real Y coordinate of the paddle */
#define PADDLE_MIN        0            /* Minimum paddle real X coordinate */
#define PADDLE_MAX        3            /* Maximum paddle real X coordinate */

#define BALL_VEL_Y_START  -4           /* Default ball vertical speed */

#define BALL_POS_X_MIN    0            /* Maximum ball X coordinate */
#define BALL_POS_X_MAX    49           /* Maximum ball X coordinate */
#define BALL_POS_Y_MIN    0            /* Maximum ball Y coordinate */
#define BALL_POS_Y_MAX    39           /* Maximum ball Y coordinate */

#define START_THRESHOLD   100          /* Max time between A & B press */
#define RESTART_THRESHOLD (2 * MSEC_PER_SEC) /* Time before restart is
					      *	allowed
					      */

#define REAL_TO_VIRT(r)  ((r) * 10)
#define VIRT_TO_REAL(v)  ((v) / 10)

/* Ball starting position (just to the left of the paddle mid-point) */
#define BALL_START       (struct x_y){ 4, BALL_POS_Y_MAX }

struct x_y {
	int x;
	int y;
};

enum pong_state {
	INIT,
	MULTI,
	SINGLE,
	CONNECTED,
};

static enum pong_state state = INIT;

struct pong_choice {
	int val;
	const char *str;
};

struct pong_selection {
	const struct pong_choice *choice;
	size_t choice_count;
	void (*complete)(int val);
};

static int select_idx;
static const struct pong_selection *select;

static const struct pong_choice mode_choice[] = {
	{ SINGLE,   "Single" },
	{ MULTI,    "Multi" },
};

static bool remote_lost;
static bool started;
static int64_t ended;

static struct k_work_delayable refresh;

/* Semaphore to indicate that there was an update to the display */
static K_SEM_DEFINE(disp_update, 0, 1);

/* X coordinate of the left corner of the paddle */
static volatile int paddle_x = PADDLE_MIN;

/* Ball position */
static struct x_y ball_pos = BALL_START;

/* Ball velocity */
static struct x_y ball_vel = { 0, 0 };

static int64_t a_timestamp;
static int64_t b_timestamp;

#define SOUND_PIN            EXT_P0_GPIO_PIN
#define SOUND_PERIOD_PADDLE  200
#define SOUND_PERIOD_WALL    1000

static const struct device *pwm;

static enum sound_state {
	SOUND_IDLE,    /* No sound */
	SOUND_PADDLE,  /* Ball has hit the paddle */
	SOUND_WALL,    /* Ball has hit a wall */
} sound_state;

static inline void beep(int period)
{
	pwm_pin_set_usec(pwm, SOUND_PIN, period, period / 2, 0);
}

static void sound_set(enum sound_state state)
{
	switch (state) {
	case SOUND_IDLE:
		beep(0);
		break;
	case SOUND_PADDLE:
		beep(SOUND_PERIOD_PADDLE);
		break;
	case SOUND_WALL:
		beep(SOUND_PERIOD_WALL);
		break;
	}

	sound_state = state;
}

static void pong_select(const struct pong_selection *sel)
{
	struct mb_display *disp = mb_display_get();

	if (select) {
		printk("Other selection still busy\n");
		return;
	}

	select = sel;
	select_idx = 0;

	mb_display_print(disp, MB_DISPLAY_MODE_DEFAULT | MB_DISPLAY_FLAG_LOOP,
			 SCROLL_SPEED, "%s", select->choice[select_idx].str);
}

static void pong_select_change(void)
{
	struct mb_display *disp = mb_display_get();

	select_idx = (select_idx + 1) % select->choice_count;
	mb_display_print(disp, MB_DISPLAY_MODE_DEFAULT | MB_DISPLAY_FLAG_LOOP,
			 SCROLL_SPEED, "%s", select->choice[select_idx].str);
}

static void pong_select_complete(void)
{
	struct mb_display *disp = mb_display_get();
	void (*complete)(int val) = select->complete;
	int val = select->choice[select_idx].val;

	mb_display_stop(disp);

	select = NULL;
	complete(val);
}

static void game_init(bool initiator)
{
	started = false;
	ended = 0;

	ball_pos = BALL_START;
	if (!initiator) {
		ball_pos.y = -1;
	}

	paddle_x = PADDLE_MIN;

	a_timestamp = 0;
	b_timestamp = 0;
}

static void mode_selected(int val)
{
	struct mb_display *disp = mb_display_get();

	state = val;

	switch (state) {
	case SINGLE:
		game_init(true);
		k_sem_give(&disp_update);
		break;
	case MULTI:
		ble_connect();
		mb_display_print(disp,
				 MB_DISPLAY_MODE_DEFAULT | MB_DISPLAY_FLAG_LOOP,
				 SCROLL_SPEED, "Connecting...");
		break;
	default:
		printk("Unknown state %d\n", state);
		return;
	}
}

static const struct pong_selection mode_selection = {
	.choice = mode_choice,
	.choice_count = ARRAY_SIZE(mode_choice),
	.complete = mode_selected,
};

static bool ball_visible(void)
{
	return (ball_pos.y >= BALL_POS_Y_MIN);
}

static void check_start(void)
{
	uint32_t delta;
	uint8_t rnd;

	if (!a_timestamp || !b_timestamp) {
		return;
	}

	if (a_timestamp > b_timestamp) {
		delta = a_timestamp - b_timestamp;
	} else {
		delta = b_timestamp - a_timestamp;
	}

	printk("delta %u ms\n", delta);

	if (delta > START_THRESHOLD) {
		return;
	}

	ball_vel.y = BALL_VEL_Y_START;

	bt_rand(&rnd, sizeof(rnd));
	rnd %= 8;

	if (a_timestamp > b_timestamp) {
		ball_vel.x = 2 + rnd;
	} else {
		ball_vel.x = -2 - rnd;
	}

	started = true;
	remote_lost = false;
	k_work_reschedule(&refresh, K_NO_WAIT);
}

static void game_ended(bool won)
{
	struct mb_display *disp = mb_display_get();

	if (sound_state != SOUND_IDLE) {
		sound_set(SOUND_IDLE);
	}

	remote_lost = won;
	ended = k_uptime_get();
	started = false;

	if (won) {
		struct mb_image img = MB_IMAGE({ 0, 1, 0, 1, 0 },
					       { 0, 1, 0, 1, 0 },
					       { 0, 0, 0, 0, 0 },
					       { 1, 0, 0, 0, 1 },
					       { 0, 1, 1, 1, 0 });
		mb_display_image(disp, MB_DISPLAY_MODE_SINGLE,
				 RESTART_THRESHOLD, &img, 1);
		printk("You won!\n");
	} else {
		struct mb_image img = MB_IMAGE({ 0, 1, 0, 1, 0 },
					       { 0, 1, 0, 1, 0 },
					       { 0, 0, 0, 0, 0 },
					       { 0, 1, 1, 1, 0 },
					       { 1, 0, 0, 0, 1 });
		mb_display_image(disp, MB_DISPLAY_MODE_SINGLE,
				 RESTART_THRESHOLD, &img, 1);
		printk("You lost!\n");
	}

	k_work_reschedule(&refresh, K_MSEC(RESTART_THRESHOLD));
}

static void game_stack_dump(const struct k_thread *thread, void *user_data)
{
	ARG_UNUSED(user_data);

	log_stack_usage(thread);
}

static void game_refresh(struct k_work *work)
{
	if (sound_state != SOUND_IDLE) {
		sound_set(SOUND_IDLE);
		k_thread_foreach(game_stack_dump, NULL);
	}

	if (state == INIT) {
		pong_select(&mode_selection);
		return;
	}

	if (ended) {
		game_init(state == SINGLE || remote_lost);
		k_sem_give(&disp_update);
		return;
	}

	ball_pos.x += ball_vel.x;
	ball_pos.y += ball_vel.y;

	/* Ball went over to the other side */
	if (ball_vel.y < 0 && ball_pos.y < BALL_POS_Y_MIN) {
		if (state == SINGLE) {
			ball_pos.y = -ball_pos.y;
			ball_vel.y = -ball_vel.y;
			sound_set(SOUND_WALL);
		} else {
			ble_send_ball(BALL_POS_X_MAX - ball_pos.x, ball_pos.y,
				      -ball_vel.x, -ball_vel.y);
			k_sem_give(&disp_update);
			return;
		}
	}

	/* Check for side-wall collision */
	if (ball_pos.x < BALL_POS_X_MIN) {
		ball_pos.x = -ball_pos.x;
		ball_vel.x = -ball_vel.x;
		sound_set(SOUND_WALL);
	} else if (ball_pos.x > BALL_POS_X_MAX) {
		ball_pos.x = (2 * BALL_POS_X_MAX) - ball_pos.x;
		ball_vel.x = -ball_vel.x;
		sound_set(SOUND_WALL);
	}

	/* Ball approaching paddle */
	if (ball_vel.y > 0 && ball_pos.y > BALL_POS_Y_MAX) {
		if (ball_pos.x < REAL_TO_VIRT(paddle_x) ||
		    ball_pos.x >= REAL_TO_VIRT(paddle_x + 2)) {
			game_ended(false);
			if (state == CONNECTED) {
				ble_send_lost();
			}
			return;
		}

		ball_pos.y = (2 * BALL_POS_Y_MAX) - ball_pos.y;

		/* Make the game play gradually harder */
		if (ball_vel.y < PIXEL_SIZE) {
			ball_vel.y++;
		}

		ball_vel.y = -ball_vel.y;

		sound_set(SOUND_PADDLE);
	}

	k_work_reschedule(&refresh, GAME_REFRESH);
	k_sem_give(&disp_update);
}

void pong_ball_received(int8_t x_pos, int8_t y_pos, int8_t x_vel, int8_t y_vel)
{
	printk("ball_received(%d, %d, %d, %d)\n", x_pos, y_pos, x_vel, y_vel);

	ball_pos.x = x_pos;
	ball_pos.y = y_pos;
	ball_vel.x = x_vel;
	ball_vel.y = y_vel;

	k_work_reschedule(&refresh, K_NO_WAIT);
}

static void button_pressed(const struct device *dev, struct gpio_callback *cb,
			   uint32_t pins)
{
	/* Filter out spurious presses */
	if (pins & BIT(DT_GPIO_PIN(DT_ALIAS(sw0), gpios))) {
		printk("A pressed\n");
		if (k_uptime_delta(&a_timestamp) < 100) {
			printk("Too quick A presses\n");
			return;
		}
	} else {
		printk("B pressed\n");
		if (k_uptime_delta(&b_timestamp) < 100) {
			printk("Too quick B presses\n");
			return;
		}
	}

	if (ended && (k_uptime_get() - ended) > RESTART_THRESHOLD) {
		int busy = k_work_cancel_delayable(&refresh);

		if (busy != 0) {
			printk("WARNING: Data-race (work and event)\n");
		}

		game_init(state == SINGLE || remote_lost);
		k_sem_give(&disp_update);
		return;
	}

	if (state == MULTI) {
		ble_cancel_connect();
		state = INIT;
		pong_select(&mode_selection);
		return;
	}

	if (pins & BIT(DT_GPIO_PIN(DT_ALIAS(sw0), gpios))) {
		if (select) {
			pong_select_change();
			return;
		}

		if (!started) {
			check_start();
		}

		if (paddle_x > PADDLE_MIN) {
			paddle_x--;
			if (!started) {
				ball_pos.x -= PIXEL_SIZE;
			}

			k_sem_give(&disp_update);
		}
	} else {
		if (select) {
			pong_select_complete();
			return;
		}

		if (!started) {
			check_start();
		}

		if (paddle_x < PADDLE_MAX) {
			paddle_x++;
			if (!started) {
				ball_pos.x += PIXEL_SIZE;
			}

			k_sem_give(&disp_update);
		}
	}
}

void pong_conn_ready(bool initiator)
{
	state = CONNECTED;
	game_init(initiator);
	k_sem_give(&disp_update);
}

void pong_remote_disconnected(void)
{
	state = INIT;
	k_work_reschedule(&refresh, K_SECONDS(1));
}

void pong_remote_lost(void)
{
	printk("Remote lost!\n");
	game_ended(true);
}

static void configure_buttons(void)
{
	static struct gpio_callback button_cb_data;
	const struct device *gpio;

	gpio = device_get_binding(DT_GPIO_LABEL(DT_ALIAS(sw0), gpios));

	gpio_pin_configure(gpio, DT_GPIO_PIN(DT_ALIAS(sw0), gpios),
			   DT_GPIO_FLAGS(DT_ALIAS(sw0), gpios) | GPIO_INPUT);
	gpio_pin_configure(gpio, DT_GPIO_PIN(DT_ALIAS(sw1), gpios),
			   DT_GPIO_FLAGS(DT_ALIAS(sw1), gpios) | GPIO_INPUT);

	gpio_pin_interrupt_configure(gpio, DT_GPIO_PIN(DT_ALIAS(sw0), gpios),
				     GPIO_INT_EDGE_TO_ACTIVE);

	gpio_pin_interrupt_configure(gpio, DT_GPIO_PIN(DT_ALIAS(sw1), gpios),
				     GPIO_INT_EDGE_TO_ACTIVE);

	gpio_init_callback(&button_cb_data, button_pressed,
			   BIT(DT_GPIO_PIN(DT_ALIAS(sw0), gpios)) |
			   BIT(DT_GPIO_PIN(DT_ALIAS(sw1), gpios)));

	gpio_add_callback(gpio, &button_cb_data);
}

void main(void)
{
	struct mb_display *disp = mb_display_get();

	configure_buttons();

	k_work_init_delayable(&refresh, game_refresh);

	pwm = device_get_binding(DT_LABEL(DT_INST(0, nordic_nrf_sw_pwm)));

	ble_init();

	pong_select(&mode_selection);

	printk("Started\n");

	while (1) {
		struct mb_image img = { };

		k_sem_take(&disp_update, K_FOREVER);

		if (ended) {
			continue;
		}

		img.row[PADDLE_ROW] = (BIT(paddle_x) | BIT(paddle_x + 1));

		if (ball_visible()) {
			img.row[VIRT_TO_REAL(ball_pos.y)] =
				BIT(VIRT_TO_REAL(ball_pos.x));
		}

		mb_display_image(disp, MB_DISPLAY_MODE_SINGLE,
				 SYS_FOREVER_MS, &img, 1);
	}
}
