#include <chrono>
#include <iostream>
#include <random>
#include "SDL.h"

#include "File.hpp"
#include "System.hpp"
#include "32blit.hpp"
#include "UserCode.hpp"
#include "JPEG.hpp"

#include "engine/api_private.hpp"

// blit framebuffer memory
uint8_t framebuffer[320 * 240 * 3];
blit::Surface __fb_hires((uint8_t *)framebuffer, blit::PixelFormat::RGB, blit::Size(320, 240));
blit::Surface __fb_hires_pal((uint8_t *)framebuffer, blit::PixelFormat::P, blit::Size(320, 240));
blit::Surface __fb_lores((uint8_t *)framebuffer, blit::PixelFormat::RGB, blit::Size(160, 120));

static blit::Pen palette[256];

// blit debug callback
void debug(std::string message) {
	std::cout << message << std::endl;
}

int blit_debugf(const char * psFormatString, va_list args)
{
	return vprintf(psFormatString, args);
}

// blit screenmode callback
blit::ScreenMode _mode = blit::ScreenMode::lores;
blit::Surface &set_screen_mode(blit::ScreenMode new_mode) {
	_mode = new_mode;
    switch(_mode) {
      case blit::ScreenMode::lores:
        blit::screen = __fb_lores;
        break;
      case blit::ScreenMode::hires:
        blit::screen = __fb_hires;
        break;
      case blit::ScreenMode::hires_palette:
        blit::screen = __fb_hires_pal;
        break;
    }

	return blit::screen;
}

static void set_screen_palette(const blit::Pen *colours, int num_cols) {
	memcpy(palette, colours, num_cols * sizeof(blit::Pen));
}

// blit timer callback
std::chrono::steady_clock::time_point start;
uint32_t now() {
	auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start);
	return (uint32_t)elapsed.count();
}

// blit random callback
#ifdef __MINGW32__
// Windows/MinGW doesn't support a non-deterministic source of randomness, so we fall back upon the age-old time seed once more
// Without this, random_device() will always return the same number and thus our mersenne twister will always produce the same sequence.
std::mt19937 random_generator(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count());
#else
std::random_device random_device;
std::mt19937 random_generator(random_device());
#endif
std::uniform_int_distribution<uint32_t> random_distribution;
uint32_t blit_random() {
	return random_distribution(random_generator);
}


// us timer used by profiler

void enable_us_timer()
{
	// Enable/initialise timer
}

uint32_t get_us_timer()
{
	// get current time in us
	uint64_t ticksPerUs = SDL_GetPerformanceFrequency() / 1000000;
	return SDL_GetPerformanceCounter() / ticksPerUs;
}

uint32_t get_max_us_timer()
{
	// largest us value timer can produce for wrapping
	return UINT32_MAX;
}

// SDL events
const Uint32 System::timer_event = SDL_RegisterEvents(2);
const Uint32 System::loop_event = System::timer_event + 1;

// Thread bouncers
static int system_timer_thread(void *ptr) {
	// Bounce back in to the class.
	System *sys = (System *)ptr;
	return sys->timer_thread();
}

static int system_loop_thread(void *ptr) {
	// Bounce back in to the class.
	System *sys = (System *)ptr;
	return sys->update_thread();
}


System::System() {
	m_input = SDL_CreateMutex();
	s_timer_stop = SDL_CreateSemaphore(0);
	s_loop_update = SDL_CreateSemaphore(0);
	s_loop_redraw = SDL_CreateSemaphore(0);
	s_loop_ended = SDL_CreateSemaphore(0);

	__fb_hires_pal.palette = palette;
}

System::~System() {
	SDL_DestroyMutex(m_input);
	SDL_DestroySemaphore(s_timer_stop);
	SDL_DestroySemaphore(s_loop_update);
	SDL_DestroySemaphore(s_loop_redraw);
	SDL_DestroySemaphore(s_loop_ended);
}

void System::run() {
	running = true;

	start = std::chrono::steady_clock::now();

	blit::api.now = ::now;
	blit::api.random = ::blit_random;
	blit::api.debug = ::debug;
	blit::api.debugf = ::blit_debugf;
	blit::api.set_screen_mode = ::set_screen_mode;
	blit::api.set_screen_palette = ::set_screen_palette;
	blit::update = ::update;
	blit::render = ::render;

	setup_base_path();

	blit::api.open_file = ::open_file;
	blit::api.read_file = ::read_file;
	blit::api.write_file = ::write_file;
	blit::api.close_file = ::close_file;
	blit::api.get_file_length = ::get_file_length;
	blit::api.list_files = ::list_files;
	blit::api.file_exists = ::file_exists;
	blit::api.directory_exists = ::directory_exists;
	blit::api.create_directory = ::create_directory;
	blit::api.rename_file = ::rename_file;
	blit::api.remove_file = ::remove_file;

	blit::api.enable_us_timer = ::enable_us_timer;
	blit::api.get_us_timer = ::get_us_timer;
	blit::api.get_max_us_timer = ::get_max_us_timer;

	blit::api.decode_jpeg_buffer = blit_decode_jpeg_buffer;
	blit::api.decode_jpeg_file = blit_decode_jpeg_file;

	::set_screen_mode(blit::lores);

#ifdef __EMSCRIPTEN__
	::init();
#else
	t_system_loop = SDL_CreateThread(system_loop_thread, "Loop", (void *)this);
	t_system_timer = SDL_CreateThread(system_timer_thread, "Timer", (void *)this);
#endif
}

int System::timer_thread() {
	// Signal the system loop every 20 msec.
	int dropped = 0;
	SDL_Event event = {};
	event.type = timer_event;

	while (SDL_SemWaitTimeout(s_timer_stop, 20)) {
		if (SDL_SemValue(s_loop_update)) {
			dropped++;
			if(dropped > 100) {
				dropped = 100;
				event.user.code = 2;
				SDL_PushEvent(&event);
			} else {
				event.user.code = 1;
				SDL_PushEvent(&event);
			}
		} else {
			SDL_SemPost(s_loop_update);
			dropped = 0;
			event.user.code = 0;
			SDL_PushEvent(&event);
		}
	}
	return 0;
}

int System::update_thread() {
	// Run the blit user code once every time we are signalled.
	SDL_Event event = {};
	event.type = loop_event;

	::init(); // Run init here because the user can make it hang.

	while (true) {
		SDL_SemWait(s_loop_update);
		if(!running) break;
		loop();
		if(!running) break;
		SDL_PushEvent(&event);
		SDL_SemWait(s_loop_redraw);
	}
	SDL_SemPost(s_loop_ended);
	return 0;
}

void System::loop()
{
	SDL_LockMutex(m_input);
	blit::buttons = shadow_buttons;
	blit::tilt.x = shadow_tilt[0];
	blit::tilt.y = shadow_tilt[1];
	blit::tilt.z = shadow_tilt[2];
	blit::joystick.x = shadow_joystick[0];
	blit::joystick.y = shadow_joystick[1];
	SDL_UnlockMutex(m_input);
	blit::tick(::now());
}

Uint32 System::mode() {
	return _mode;
}

void System::update_texture(SDL_Texture *texture) {
	blit::render(::now());
	if (_mode == blit::ScreenMode::lores) {
		SDL_UpdateTexture(texture, nullptr, __fb_lores.data, 160 * 3);
	}
	else if(_mode == blit::ScreenMode::hires) {
		SDL_UpdateTexture(texture, nullptr, __fb_hires.data, 320 * 3);
	} else {
		uint8_t col_fb[320 * 240 * 3];

		auto in = __fb_hires_pal.data, out = col_fb;

		for(int i = 0; i < 320 * 240; i++) {
			uint8_t index = *(in++);
			(*out++) = palette[index].r;
			(*out++) = palette[index].g;
			(*out++) = palette[index].b;
		}

		SDL_UpdateTexture(texture, nullptr, col_fb, 320 * 3);
	}
}

void System::notify_redraw() {
	SDL_SemPost(s_loop_redraw);
}

void System::set_joystick(int axis, float value) {
	if (axis < 2) {
		SDL_LockMutex(m_input);
		shadow_joystick[axis] = value;
		SDL_UnlockMutex(m_input);
	}
}

void System::set_tilt(int axis, float value) {
	if (axis < 3) {
		SDL_LockMutex(m_input);
		shadow_tilt[axis] = value;
		SDL_UnlockMutex(m_input);
	}
}

void System::set_button(int button, bool state) {
	SDL_LockMutex(m_input);
	if (state) {
		shadow_buttons |= button;
	} else {
		shadow_buttons &= ~button;
	}
	SDL_UnlockMutex(m_input);
}

void System::stop() {
	int returnValue;
	running = false;

	if(SDL_SemWaitTimeout(s_loop_ended, 500)) {
		fprintf(stderr, "User code appears to have frozen. Detaching thread.\n");
		SDL_DetachThread(t_system_loop);
	} else {
		SDL_WaitThread(t_system_loop, &returnValue);
	}

	SDL_SemPost(s_timer_stop);
	SDL_WaitThread(t_system_timer, &returnValue);
}
