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

#include <zephyr.h>
#include <misc/printk.h>
#include <board.h>
#include <gpio.h>
#include <device.h>
#include <string.h>
#include <pwm.h>
#include <misc/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      K_MSEC(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   K_MSEC(100)  /* Max time between A & B press */
#define RESTART_THRESHOLD K_SECONDS(2) /* 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 s64_t ended;

static struct k_delayed_work 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 s64_t a_timestamp;
static s64_t b_timestamp;

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

static 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);
}

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)
{
	u32_t delta;
	u8_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_delayed_work_submit(&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_delayed_work_submit(&refresh, RESTART_THRESHOLD);
}

static void game_stack_dump(const struct k_thread *thread, void *user_data)
{
#if defined(CONFIG_THREAD_STACK_INFO)
	stack_analyze((char *)user_data, (char *)thread->stack_info.start,
						thread->stack_info.size);
#endif
}

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

	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_delayed_work_submit(&refresh, GAME_REFRESH);
	k_sem_give(&disp_update);
}

void pong_ball_received(s8_t x_pos, s8_t y_pos, s8_t x_vel, s8_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_delayed_work_submit(&refresh, K_NO_WAIT);
}

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

	if (ended && (k_uptime_get() - ended) > RESTART_THRESHOLD) {
		k_delayed_work_cancel(&refresh);
		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(SW0_GPIO_PIN)) {
		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_delayed_work_submit(&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;
	struct device *gpio;

	gpio = device_get_binding(SW0_GPIO_CONTROLLER);

	gpio_pin_configure(gpio, SW0_GPIO_PIN,
			   (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
			    GPIO_INT_ACTIVE_LOW));
	gpio_pin_configure(gpio, SW1_GPIO_PIN,
			   (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
			    GPIO_INT_ACTIVE_LOW));
	gpio_init_callback(&button_cb, button_pressed,
			   BIT(SW0_GPIO_PIN) | BIT(SW1_GPIO_PIN));
	gpio_add_callback(gpio, &button_cb);

	gpio_pin_enable_callback(gpio, SW0_GPIO_PIN);
	gpio_pin_enable_callback(gpio, SW1_GPIO_PIN);
}

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

	configure_buttons();

	k_delayed_work_init(&refresh, game_refresh);

	pwm = device_get_binding(CONFIG_PWM_NRF5_SW_0_DEV_NAME);

	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,
				 K_FOREVER, &img, 1);
	}
}
