#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>

#include "config.h"
#include "intl.h"
#include "asktty.h"

#define READBUF 4096

static struct termios *tty = NULL;
static void (*old_sighandler)(int) = NULL;

void tty_restore(void) {
	if(tty)
		tcsetattr(STDIN_FILENO, TCSANOW, tty);
}

static void sighandler(int sig) {
	tty_restore();
	printf(_("Interrupted\n"));
	if(old_sighandler)
		old_sighandler(sig);
	exit(128+sig);
}

void tty_init(void) {
	static struct termios t;
	void (*old_sig)(int);

	if(!tcgetattr(STDIN_FILENO, &t)) {
		tty = &t;
		old_sig = signal(SIGINT, sighandler);
		if(old_sig != SIG_ERR)
			old_sighandler = old_sig;
	}
}

int tty_ask(char *choices, char *fmt, ...) {
	va_list ap;
	struct termios tmp;
	int r;
	unsigned char c[READBUF];
        char *choice;

	for(;;) {
		va_start(ap, fmt);
		vfprintf(stdout, fmt, ap);
		va_end(ap);
		fflush(stdout);

		if(tty) {
			tmp = *tty;
			tmp.c_lflag &= ~ICANON;
			tmp.c_iflag &= ~ICRNL;
			tmp.c_lflag &= ~ECHO;
			tmp.c_cc[VTIME] = 0;
			tmp.c_cc[VMIN] = 1;
			tcsetattr(STDIN_FILENO, TCSANOW, &tmp);
		}

		r = read(STDIN_FILENO, c, READBUF);

		tty_restore();

		if(r < 0) {
			printf(_("Interrupted\n"));
			return -1;
		}

		if(!r || strchr(" \r", *c))
			*c = choices[0];
		else
			*c = tolower(*c);

		if((choice = strchr(choices, *c))) {
			printf("%c\n", toupper(*c));
			fflush(stdout);
			return choice - choices;
		}

		printf("\a\r\033[K");
	}
	return -1;
}
