//////////////////////////////////////////////////////
// insbarshow.c
//
// Lee Juhyun
//

#include <panel.h>
#include <string.h>
#include <pthread.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <ncurses.h>

#define BILLION 1000000000L

int 		size_insbar_lines;
int 		size_insbar_cols;
int 		size_insbar_y;
int 		size_insbar_x;
int		size_screen_cols;
int		size_screen_lines;
timer_t 	timerid;
int		bool_timer = -1;

extern 	int 	screen_size_cols;
extern 	int 	screen_size_lines;

extern 	WINDOW 	*w_insbar;
extern 	PANEL	*p_insbar;

extern int write_log(char *);
extern int exit_program(void);

void insbar_show(void);
void init_w_insbar(WINDOW **);
void show_w_insbar(WINDOW *, char *, int );
void show_w_insbar_string(WINDOW *);
void print_in_middle_insbar(WINDOW *, int , int , int , char *, chtype);
void print_in_right_insbar(WINDOW *, int, int , char *, chtype);
void print_in_left_insbar(WINDOW *, int , char *, chtype);
void print_in_timer(char *, chtype);


static void interrupt(int signo, siginfo_t *info, void *context) {
	int errsave;
	//struct tm tcurrent;
	
	//tcurrent = localtime_r(time(NULL), &tcurrent);
	time_t tcurrent;
	
	char temptime[80];
	
	tcurrent = time(NULL);

	sprintf(temptime, "%s", ctime(&tcurrent));
	temptime[strlen(temptime) - 1] = '\0';

	errsave = errno;
	
	print_in_timer(temptime, COLOR_PAIR(1));
	refresh();

	errno = errsave;
}

static int setinterrupt() {
	struct sigaction act;

	act.sa_flags = SA_SIGINFO;
	act.sa_sigaction = interrupt;
	if ((sigemptyset(&act.sa_mask) == -1) ||
			(sigaction(SIGALRM, &act, NULL) == -1))
		return -1;
	return 0 ;
}

static int setperiodic(double sec) {
	struct itimerspec value;

	if (timer_create(CLOCK_REALTIME, NULL, &timerid) == -1)
		return -1;
	value.it_interval.tv_sec = (long)sec;
	value.it_interval.tv_nsec = (sec - value.it_interval.tv_sec)*BILLION;
	if (value.it_interval.tv_nsec >= BILLION) {
		value.it_interval.tv_sec++;
		value.it_interval.tv_nsec -= BILLION;
	}
	value.it_value = value.it_interval;
	
	bool_timer = 0;

	return timer_settime(timerid, 0, &value, NULL);
}

void *timer_process(void *arg) {
	if (setinterrupt() == -1) {

		return;
	}

	if (setperiodic(1.0) == -1) {

		return;
	}

	for( ; ;)
		pause();
}

int istimer(void) {
	
	if (bool_timer == -1)
		return -1;
	return 0;
}

int stop_timer(void) {

	if (istimer() == 0) {
		timer_delete(timerid);
		bool_timer = -1;
	}

	return 0;
}

int start_timer(void) {

	if (istimer() == -1) {
		setperiodic(1.0);
	}

	return 0;
}



void insbar_show(void) {

	pthread_t tid;
	
	size_insbar_lines	= 11;
	size_insbar_cols	= screen_size_cols/4*1;
	size_insbar_y		= screen_size_lines - 11;
	size_insbar_x		= screen_size_cols/4*3;;
	size_screen_lines	= screen_size_lines;
	size_screen_cols	= screen_size_cols;

	
	if((w_insbar = newwin(size_insbar_lines, size_insbar_cols,
			size_insbar_y, size_insbar_x)) == NULL)
	{
		write_log("Error insbar_show/newwin");
		exit_program();
	}

	show_w_insbar(w_insbar, "-Basic command-", 1);
	show_w_insbar_string(w_insbar);

	
	if((p_insbar = new_panel(w_insbar))==NULL)
	{
		write_log("Error insbar_show/new_panel");
		exit_program();
	}
	if (pthread_create(&tid, NULL, timer_process, NULL)) {
		return;
	}
}


// 윈도우 생성
void show_w_insbar(WINDOW *win, char *label, int label_color) {
	int startx, starty, height, width;

	//getbegyx(win, starty, startx);
	//getbegyx(win, height, width);
	startx = size_insbar_cols;
       	starty = 3;
	width = size_insbar_cols;
	height = 3; 

	box(win, 0, 0);
	mvwaddch(win, size_insbar_lines - 3, 0, ACS_LTEE);
	mvwhline(win, size_insbar_lines - 3, 1, ACS_HLINE, width - 2);
	mvwaddch(win, size_insbar_lines - 3, width - 1, ACS_RTEE);

	print_in_middle_insbar(win, 1, 0, width, label, COLOR_PAIR(label_color));
}

// 윈도우 생성
void show_w_insbar_string(WINDOW *win ) {

	print_in_left_insbar(w_insbar, 2, "  c", COLOR_PAIR(3));
	print_in_left_insbar(w_insbar, 3, "  d", COLOR_PAIR(3));
	print_in_left_insbar(w_insbar, 4, "  r", COLOR_PAIR(3));
	print_in_left_insbar(w_insbar, 5, "  m", COLOR_PAIR(3));
	print_in_left_insbar(w_insbar, 6, "  k", COLOR_PAIR(3));
	print_in_left_insbar(w_insbar, 7, "  n", COLOR_PAIR(3));
	
	print_in_right_insbar(w_insbar, 2,  size_insbar_cols, "Copy File & Dir", COLOR_PAIR(4));
	print_in_right_insbar(w_insbar, 3,  size_insbar_cols, "Remove File & Dir", COLOR_PAIR(4));
	print_in_right_insbar(w_insbar, 4,  size_insbar_cols, "Rename File & Dir", COLOR_PAIR(4));
	print_in_right_insbar(w_insbar, 5,  size_insbar_cols, "Move File & Dir", COLOR_PAIR(4));
	print_in_right_insbar(w_insbar, 6,  size_insbar_cols, "Make Directory", COLOR_PAIR(4));
	print_in_right_insbar(w_insbar, 7,  size_insbar_cols, "Change Directory", COLOR_PAIR(4));


}


// 윈도우 생성
void print_in_middle_insbar(WINDOW *win, int starty, int startx, int width, char *string, chtype color) {
	int length, x, y;
	float temp;

	if(win == NULL)
		win = stdscr;
	getyx(win, y, x);
	if(startx != 0)
		x = startx;
	if(starty != 0)
		y = starty;
	if(width == 0)
		width = 80;

	length = strlen(string);
	temp = (width - length)/2;
	x = startx + (int)temp;
	wattron(win, color);
	mvwprintw(win, y, x, "%s", string);
	wattroff(win,color);
	refresh();
}

// 윈도우 생성
void print_in_right_insbar(WINDOW *win, int starty, int width, char *string, chtype color) {
	int length, x, y;
	float temp;
	
	x = width - strlen(string) - 1;
	y = starty;

	wattron(win, color);
	mvwprintw(win, y, x, "%s", string);
	wattroff(win,color);
	refresh();
}

// 윈도우 생성
void print_in_left_insbar(WINDOW *win, int starty, char *string, chtype color) {
	int length, x, y;
	float temp;
	
	x = 1;
	y = starty;

	wattron(win, color);
	mvwprintw(win, y, x, "%s", string);
	wattroff(win,color);
	refresh();
}

void print_in_timer(char *string, chtype color) {
	int length, x, y;
	float temp;

	length = strlen(string);
	temp = (size_insbar_cols - length)/2;
	x = size_screen_cols - size_insbar_cols + (int)temp;
	y = size_insbar_y + 9;
	attron(color);
	mvprintw(y, x, "%s", string);
	attroff(color);
	refresh();
}
