//////////////////////////////////////////////////////
// bottombarshow.c
//
// Lee Juhyun
//
#include <panel.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include "mainlib.h"
#include "keylib.h"

#define BUF_SIZE		256
#define BUF_LINE_SIZE	256

int size_bottombar_lines;
int size_bottombar_cols;
int size_bottombar_y;
int size_bottombar_x;

int log_flag = 1;
int log_thread_flag;
int log_key_flag = 1;

int		log_print_y;		 
int		log_print_x;
int		log_line_count = 0;		 

file_line_pointer log_start = NULL;
file_line_pointer log_cur_p = NULL;
file_line_pointer log_print = NULL;
file_line_pointer log_key_print = NULL;

pthread_t log_pid;

extern int	screen_size_cols;
extern int	screen_size_lines;
extern int	fifo;
extern int	flag;
extern 	int 	index_menu;

extern WINDOW 	*w_bottombar;
extern WINDOW 	*w_filelist;
extern PANEL	*p_bottombar;

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

void bottombar_show(void);
void init_w_bottombar(WINDOW **);
void show_w_bottombar(WINDOW *, char *, int );
void print_in_middle_bottombar(WINDOW *, int , int , int , char *, chtype);
void print_in_middle_information(WINDOW *win, int label_color);
void log_free_line();
void log_print_line();
void log_line_add(char* p);
void log_read();
void logview_key();
int	 is_log();

void bottombar_show(void) {

	char title[16] = "Log view (F)";

	size_bottombar_lines	= 11;
	size_bottombar_cols	= screen_size_cols/4*3;
	size_bottombar_y	= screen_size_lines - 11;
	size_bottombar_x	= 0;
	log_print_y = size_bottombar_y + 3;
	log_print_x = size_bottombar_x + 2;
	
	w_bottombar = newwin(size_bottombar_lines, size_bottombar_cols,
			size_bottombar_y, size_bottombar_x);

	if(w_bottombar == NULL)
	{
		write_log("bottombar_show/w_bottombar new error");
		exit_program();	
	}
	
	show_w_bottombar(w_bottombar, title , 2);
	print_in_middle_information(w_bottombar, 2);

	if( pthread_create(&log_pid , NULL, log_read, NULL) )
	{
		write_log("bottombar_show/pthread_create error");
		exit_program();
	}

	log_thread_flag = TRUE;

	p_bottombar = new_panel(w_bottombar);

	if(p_bottombar == NULL)
	{
		write_log("bottombar_show/p_bottombar new error");
		exit_program();
	}
	
}
void show_w_bottombar(WINDOW *win, char *label, int label_color) {
	int startx, starty, height, width;

	startx = size_bottombar_cols;
       	starty = 3;
	width = size_bottombar_cols;
	height = 3; 

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

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

void print_in_middle_information(WINDOW *win, int label_color) {
	int width;
	char label[255];
	char temp[255];

	width = size_bottombar_cols;

	sprintf(label, "USER: %s@%s  HOME: %s", getlogin(), getenv("HOSTNAME"), getenv("HOME"));
	
	print_in_middle_bottombar(win, size_bottombar_lines -2 , 0, width, label, COLOR_PAIR(label_color));

}
void print_in_middle_bottombar(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 log_read()
{
	char buf[STRING_MAX];
	char *p;	
	int b_size = size_bottombar_cols-2;
	int size = b_size -2;
	char temp[b_size];
	int i=0;
	char* lasts;
	

	while(log_flag)
	{
		if(read(fifo, buf, STRING_MAX) != 0)
		{
			i = 0;
			p = strtok_r(buf, "\n", &lasts);
			
			if(strlen(p) > size)
			{
				while( size < strlen(p+ size*i) )
				{
					memset(temp, 0, b_size);
					memcpy(temp, p+size*i , size);
					//temp[size-1] = 0;
					log_line_add(temp);
					i++;
				}
				log_line_add(p+ (size)*i );
			}
			else
				log_line_add(p);			

			if(log_key_flag)
			{
				log_key_print = log_print;
				log_print_line(log_print);	
				refresh();
			}
		}
	}
}

void log_line_add(char* p)
{
	file_line_pointer temp;
	
	temp = (file_line_pointer)malloc (sizeof(file_line)+1);
	temp->data = (char*)malloc( (size_bottombar_cols-2)* sizeof(char));
	memset(temp->data, ' ', (size_bottombar_cols-2) );
	memcpy(temp->data, p, strlen(p));	

	*(temp->data + size_bottombar_cols - 3) = 0;

	if(log_line_count < BUF_LINE_SIZE)
	{
		log_line_count++;

		if(log_line_count > size_bottombar_lines - 6)
				log_print =  log_print->next;

		if(log_start)
		{
			temp->next = NULL;
			log_cur_p->next = temp;
			temp->pre = log_cur_p;
			log_cur_p = temp;
		}
		else
		{
			temp->pre = NULL;
			temp->next = NULL;
			log_start = temp;
			log_cur_p = temp;
			log_print = temp;
		}
	}
	else
	{
		temp->next = NULL;
		log_cur_p->next = temp;
		temp->pre = log_cur_p;
		log_cur_p = temp;
		temp = log_start;
		log_start = log_start->next;
		free(temp);
	}
}

void log_print_line(file_line_pointer print_start)
{

	file_line_pointer temp;
	int i;
	temp = print_start;

	for(i= 0 ; (temp != NULL) && (i < size_bottombar_lines - 6) ; i++)
	{
		mvprintw(log_print_y + i , log_print_x, "%s", temp->data);
		temp = temp->next;
	}
	wrefresh(w_bottombar);
	refresh();
}

void log_free_line()
{
	file_line_pointer temp;
	
	log_cur_p = NULL;
	log_print = NULL;
	log_key_print = NULL;

	while(log_start)
	{
		temp = log_start;
		log_start = log_start->next;

		free(temp);
	}
	log_start = NULL;
}

void logview_key()
{
	int key_mode = 1;
	int c;
	char title[20] = "Log view (F4)";
	char label[80];

	if (sprintf(label, "                                      ") < 0) {
		write_log("Error filelist_key/sprintf(TAB)");
		exit_program();
	}

	if (show_w_filelist(label, 2) == -1) {
		write_log("Error filelist_key/show_w_filelist(TAB)");
		exit_program();
	}

	if (sprintf(label, "FILE LIST") < 0) {
		write_log("Error filelist_key/sprintf(TAB)");
		exit_program();
	}

	if (show_w_filelist(label, 2) == -1) {
		write_log("Error filelist_key/show_w_filelist(TAB)");
		exit_program();
	}	
	
	show_w_bottombar(w_bottombar, title , 1);
	print_in_middle_information(w_bottombar, 1);	
	wrefresh(w_bottombar);
	log_print_line(log_key_print);

	wrefresh(w_bottombar);
	wrefresh(w_filelist);
	refresh();

	while(key_mode && (c = getch()))
	{
		switch(c)                                                                        
		{   			
			case KEY_RIGHT:				   
			case KEY_DOWN:
				if(log_key_print && log_key_print->next && log_print != log_key_print)
				{
					log_key_print = log_key_print->next;
					
					log_print_line(log_key_print);					
				}				
				break;                                               
			case KEY_UP:
			case KEY_LEFT:
				if(log_key_print && log_key_print->pre)
				{
					log_key_print = log_key_print->pre;
					
					log_print_line(log_key_print);
				}
				break;
			case KEY_USER_TAB :
			case 'c':
				show_w_bottombar(w_bottombar, title , 2);
				print_in_middle_information(w_bottombar, 2 );
				
				log_print_line(log_key_print);

				keypad(w_filelist, TRUE);

				flag = FI_MODE;

				index_menu = -1;

				sprintf(label, "                                      ");
				show_w_filelist(label, 1);
				wrefresh(w_filelist);

				sprintf(label, "Push TAB, U can use menu");
				show_w_filelist(label, 1);
			
				wrefresh(w_filelist);

				key_mode = FALSE;
				refresh();
				break;
			default:                                
				break;     					
		} 
	}
}

int is_log()
{
	if(log_thread_flag)
	{
		log_flag = 0;
		if(pthread_join(log_pid, NULL))
		{
			write_log("is_log/pthread_join error");
			return -1;
		}
		log_thread_flag = 0;
	}

	return 0;
}

