#if defined(_WIN32) && !defined(WIN32)
#define WIN32
#endif

#ifdef __EMSCRIPTEN__
#include <emscripten/emscripten.h>
#endif

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

#include "Input.hpp"
#include "Multiplayer.hpp"
#include "System.hpp"
#include "Renderer.hpp"
#include "Audio.hpp"
#include "UserCode.hpp"

#include "contrib.hpp"

#ifdef VIDEO_CAPTURE
#include "VideoCapture.hpp"
#endif

static bool running = true;

SDL_Window* window = nullptr;

System *blit_system;
Input *blit_input;
Multiplayer *blit_multiplayer;
Renderer *blit_renderer;
Audio *blit_audio;

const char *launch_path = nullptr;

#ifdef VIDEO_CAPTURE
VideoCapture *blit_capture;
unsigned int last_record_startstop = 0;
#endif

void handle_event(SDL_Event &event) {
	switch (event.type) {
		case SDL_QUIT:
			running = false;
			break;

		case SDL_WINDOWEVENT:
			if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
				blit_renderer->resize(event.window.data1, event.window.data2);
			}
			break;

		case SDL_MOUSEBUTTONUP:
		case SDL_MOUSEBUTTONDOWN:
			blit_input->handle_mouse(event.button.button, event.type == SDL_MOUSEBUTTONDOWN, event.button.x, event.button.y);
			break;

		case SDL_MOUSEMOTION:
			if (event.motion.state & SDL_BUTTON_LMASK) {
				blit_input->handle_mouse(SDL_BUTTON_LEFT, event.motion.state & SDL_MOUSEBUTTONDOWN, event.motion.x, event.motion.y);
			}
			break;

		case SDL_KEYDOWN: // fall-though
		case SDL_KEYUP:
			if (!blit_input->handle_keyboard(event.key.keysym.sym, event.type == SDL_KEYDOWN)) {
#ifdef VIDEO_CAPTURE
				switch (event.key.keysym.sym) {
				case SDLK_r:
					if (event.type == SDL_KEYDOWN && SDL_GetTicks() - last_record_startstop > 1000) {
						if (blit_capture->recording()) blit_capture->stop();
						else blit_capture->start();
						last_record_startstop = SDL_GetTicks();
					}
				}
#endif
			}
			break;

		case SDL_CONTROLLERBUTTONDOWN:
		case SDL_CONTROLLERBUTTONUP:
			blit_input->handle_controller_button(event.cbutton.button, event.type == SDL_CONTROLLERBUTTONDOWN);
			break;

		case SDL_CONTROLLERAXISMOTION:
			blit_input->handle_controller_motion(event.caxis.axis, event.caxis.value);
			break;

		case SDL_CONTROLLERDEVICEADDED:
			SDL_GameControllerOpen(event.cdevice.which);
			break;

		case SDL_CONTROLLERDEVICEREMOVED:
			SDL_GameControllerClose(SDL_GameControllerFromInstanceID(event.cdevice.which));
			break;

		case SDL_RENDER_TARGETS_RESET:
			std::cout << "Targets reset" << std::endl;
			break;

		case SDL_RENDER_DEVICE_RESET:
			std::cout << "Device reset" << std::endl;
			break;

		default:
			if(event.type == System::loop_event) {
				blit_multiplayer->update();
				blit_renderer->update(blit_system);
				blit_system->notify_redraw();
				blit_renderer->present();
#ifdef VIDEO_CAPTURE
				if (blit_capture->recording()) blit_capture->capture(blit_renderer);
#endif
			} else if (event.type == System::timer_event) {
				switch(event.user.code) {
					case 0:
						SDL_SetWindowTitle(window, metadata_title);
						break;
					case 1:
						SDL_SetWindowTitle(window, (std::string(metadata_title) + " [SLOW]").c_str());
						break;
					case 2:
						SDL_SetWindowTitle(window, (std::string(metadata_title) + " [FROZEN]").c_str());
						break;
				}
			}
			break;
	}
}

#ifdef __EMSCRIPTEN__
void em_loop() {
	SDL_Event event;
	while (SDL_PollEvent(&event)) {
		handle_event(event);
	}

	blit_multiplayer->update();
	blit_system->loop();
	blit_renderer->update(blit_system);
	blit_renderer->present();
}
#endif

int main(int argc, char *argv[]) {
  int x, y;
  bool custom_window_position = false;

  std::cout << metadata_title << " " << metadata_version << std::endl;
  std::cout << "Powered by 32Blit SDL2 runtime - github.com/32blit/32blit-sdk" << std::endl << std::endl;

	auto mp_mode = Multiplayer::Mode::Auto;
	std::string mp_address = "localhost";

	for(int i = 1; i < argc; i++) {
		std::string arg_str(argv[i]);
		if(arg_str == "--connect" && i + 1 < argc) {
			mp_mode = Multiplayer::Mode::Connect;
			mp_address = std::string(argv[i + 1]);
			i++;
		}
		else if(arg_str == "--launch_path" && i + 1 < argc) {
			launch_path = argv[++i];
		}
		else if(arg_str == "--listen")
			mp_mode = Multiplayer::Mode::Listen;
		else if(arg_str == "--position") {
			if(SDL_sscanf(argv[i+1], "%d,%d", &x, &y) == 2) {
			    custom_window_position = true;
			}
		}
		else if(arg_str == "--credits") {
			std::cout << "32Blit was made possible by:" << std::endl;
			std::cout << std::endl;
			for(auto name : contributors) {
				if(name != nullptr) {
					std::cout << " * " << name << std::endl;
				}
			}
			std::cout << std::endl;
			std::cout << "Special thanks to:" << std::endl;
			std::cout << std::endl;
			for(auto name : special_thanks) {
				if(name != nullptr) {
					std::cout << " * " << name << std::endl;
				}
			}
			std::cout << std::endl;
			SDL_Quit();
			return 0;
		}
		else if(arg_str == "--info") {
			std::cout << metadata_description << std::endl << std::endl;
			std::cout << " Category: " << metadata_category << std::endl;
			std::cout << " Author:   " << metadata_author << std::endl;
			std::cout << " URL:      " << metadata_url << std::endl << std::endl;
			SDL_Quit();
			return 0;
		}
		else if(arg_str == "--help") {
			std::cout << "Usage: " << argv[0] << " <options>" << std::endl << std::endl;
			std::cout << " --connect <addr>     -- Connect to a listening game instance." << std::endl;
			std::cout << " --listen             -- Listen for incoming connections." << std::endl;
			std::cout << " --position x,y       -- Set window position." << std::endl;
			std::cout << " --launch_path <file> -- Emulates the file associations on the console." << std::endl;
			std::cout << " --credits            -- Print contributor credits and exit." << std::endl;
			std::cout << " --info               -- Print metadata info and exit." << std::endl << std::endl;
			SDL_DestroyWindow(window);
			SDL_Quit();
			return 0;
		}
	}

	if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_GAMECONTROLLER|SDL_INIT_AUDIO) < 0) {
		std::cerr << "could not initialize SDL2: " << SDL_GetError() << std::endl;
		return 1;
	}

	window = SDL_CreateWindow(
		metadata_title,
		SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
		System::width*2, System::height*2,
		SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
	);

	if (window == nullptr) {
		std::cerr << "could not create window: " << SDL_GetError() << std::endl;
		return 1;
	}
	SDL_SetWindowMinimumSize(window, System::width, System::height);

	if(custom_window_position) {
		SDL_SetWindowPosition(window, x, y);
	}

	// Open all joysticks as game controllers
	for(int n=0; n<SDL_NumJoysticks(); n++) {
		SDL_GameControllerOpen(n);
	}

	blit_system = new System();
	blit_input = new Input(blit_system);
	blit_multiplayer = new Multiplayer(mp_mode, mp_address);
	blit_renderer = new Renderer(window, System::width, System::height);
	blit_audio = new Audio();

#ifdef VIDEO_CAPTURE
	blit_capture = new VideoCapture(argv[0]);
#endif

	blit_system->run();

#ifdef __EMSCRIPTEN__
	emscripten_set_main_loop(em_loop, 0, 1);
#else
	SDL_Event event;

	while (running && SDL_WaitEvent(&event)) {
		handle_event(event);
	}
#endif

	if (running) {
		std::cerr << "Main loop exited with error: " << SDL_GetError() << std::endl;
		running = false; // ensure timer thread quits
	}

#ifdef VIDEO_CAPTURE
	if (blit_capture->recording()) blit_capture->stop();
	delete blit_capture;
#endif

	blit_system->stop();
	delete blit_system;
	delete blit_multiplayer;
	delete blit_renderer;

	SDL_DestroyWindow(window);
	SDL_Quit();
	return 0;
}
