#include <newt.h>
#include <signal.h>
#include <stdbool.h>

#include "../../util/cache.h"
#include "../../util/debug.h"
#include "../browser.h"
#include "../helpline.h"
#include "../ui.h"
#include "../util.h"
#include "../libslang.h"
#include "../keysyms.h"

pthread_mutex_t ui__lock = PTHREAD_MUTEX_INITIALIZER;

static volatile int ui__need_resize;

extern struct perf_error_ops perf_tui_eops;

void ui__refresh_dimensions(bool force)
{
	if (force || ui__need_resize) {
		ui__need_resize = 0;
		pthread_mutex_lock(&ui__lock);
		SLtt_get_screen_size();
		SLsmg_reinit_smg();
		pthread_mutex_unlock(&ui__lock);
	}
}

static void ui__sigwinch(int sig __used)
{
	ui__need_resize = 1;
}

static void ui__setup_sigwinch(void)
{
	static bool done;

	if (done)
		return;

	done = true;
	pthread__unblock_sigwinch();
	signal(SIGWINCH, ui__sigwinch);
}

int ui__getch(int delay_secs)
{
	struct timeval timeout, *ptimeout = delay_secs ? &timeout : NULL;
	fd_set read_set;
	int err, key;

	ui__setup_sigwinch();

	FD_ZERO(&read_set);
	FD_SET(0, &read_set);

	if (delay_secs) {
		timeout.tv_sec = delay_secs;
		timeout.tv_usec = 0;
	}

        err = select(1, &read_set, NULL, NULL, ptimeout);

	if (err == 0)
		return K_TIMER;

	if (err == -1) {
		if (errno == EINTR)
			return K_RESIZE;
		return K_ERROR;
	}

	key = SLang_getkey();
	if (key != K_ESC)
		return key;

	FD_ZERO(&read_set);
	FD_SET(0, &read_set);
	timeout.tv_sec = 0;
	timeout.tv_usec = 20;
        err = select(1, &read_set, NULL, NULL, &timeout);
	if (err == 0)
		return K_ESC;

	SLang_ungetkey(key);
	return SLkp_getkey();
}

static void newt_suspend(void *d __used)
{
	newtSuspend();
	raise(SIGTSTP);
	newtResume();
}

static void ui__signal(int sig)
{
	ui__exit(false);
	psignal(sig, "perf");
	exit(0);
}

int ui__init(void)
{
	int err;

	newtInit();
	err = SLkp_init();
	if (err < 0) {
		pr_err("TUI initialization failed.\n");
		goto out;
	}

	SLkp_define_keysym((char *)"^(kB)", SL_KEY_UNTAB);

	newtSetSuspendCallback(newt_suspend, NULL);
	ui_helpline__init();
	ui_browser__init();

	signal(SIGSEGV, ui__signal);
	signal(SIGFPE, ui__signal);
	signal(SIGINT, ui__signal);
	signal(SIGQUIT, ui__signal);
	signal(SIGTERM, ui__signal);

	perf_error__register(&perf_tui_eops);
out:
	return err;
}

void ui__exit(bool wait_for_ok)
{
	if (wait_for_ok)
		ui__question_window("Fatal Error",
				    ui_helpline__last_msg,
				    "Press any key...", 0);

	SLtt_set_cursor_visibility(1);
	SLsmg_refresh();
	SLsmg_reset_smg();
	SLang_reset_tty();

	perf_error__unregister(&perf_tui_eops);
}
