#include <stdio.h>
#include <ncurses.h>
#include <string.h>
#include <stdlib.h>
#include <panel.h>
#include <sys/stat.h>
#include <unistd.h>
#include "fcntl.h"
#include "mainlib.h"

int 	size_fileview_lines;
int 	size_fileview_cols;
int 	size_fileview_y;
int 	size_fileview_x;

FILE* 	filedes = NULL;
int		print_y = 3;
int		print_x = 2;
int		line_count = 0;
char	file_path[512];
char	file_name[256];

file_line_pointer start = NULL;
file_line_pointer cur_p = NULL;
file_line_pointer print = NULL;

extern 	int 	screen_size_cols;
extern 	int 	screen_size_lines;
extern	int		is_vimode;

extern 	WINDOW 	*w_fileview;
extern 	PANEL	*p_fileview;

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

void fileview_show(char* filename);
void fileview_show_first(char* filename);
int fileview_box(int );
void print_in_middle_fileview(int starty, int startx, int width, char *string, chtype color);
void fileview_new();
void print_line(int );
int file_init();
void free_line();
void line_add(char* p);
int edit_file_name(char* n_file);
void fileview_mode();

void fileview_new()
{
	
	size_fileview_lines	= screen_size_lines - 15;
	size_fileview_cols	= screen_size_cols/2 ;
	size_fileview_y		= 3;
	size_fileview_x		= screen_size_cols/2;
		
	w_fileview = newwin(size_fileview_lines, size_fileview_cols,
			size_fileview_y, size_fileview_x);
	if(w_fileview == NULL)
	{
		write_log("fileview_new/w_fileview new error");
		exit_program();
	}
	
	p_fileview = new_panel(w_fileview);
	
	if(p_fileview == NULL)
	{
		write_log("fileview_new/p_fileview new error");
		exit_program();
	}

	wrefresh(w_fileview);	
	
	update_panels();
	doupdate();
	hide_panel(p_fileview);
}

int fileview_box(int color ) {
	
	char label[20];
	char label_l[size_fileview_cols-2];
	
	if(sprintf(label, "FILE VIEW (V)") < 0)
	{
		write_log("fileview_box sprintf label error");
		return -1;
	}	

	if(file_name != NULL)
	{
		if(sprintf(label_l, "[%s] [e : edit] [total : %d line]",file_name, line_count)<0)
		{
			write_log("fileview_box sprintf label_l error");
			return -1;
		}
	}
	else
	{
		if(sprintf(label_l, " e : edit total : %d line	",line_count)<0)
		{
			write_log("fileview_box sprintf label_l-1 error");
			return -1;
		}
	}


	box(w_fileview  , 0 , 0);

	refresh();

	mvwaddch(w_fileview, 2, 0, ACS_LTEE);
	mvwhline(w_fileview, 2, 1, ACS_HLINE, size_fileview_cols - 2);
	mvwhline(w_fileview, size_fileview_lines - 3, 1, ACS_HLINE, size_fileview_cols - 2);
	mvwaddch(w_fileview, 2, size_fileview_cols - 1, ACS_RTEE);

	print_in_middle_fileview(1, 0, size_fileview_cols, label, COLOR_PAIR(color));
	print_in_middle_fileview(size_fileview_lines - 2, 0, size_fileview_cols, label_l, COLOR_PAIR(color));
}

void print_in_middle_fileview(int starty, int startx, int width, char *string, chtype color) {
	int length, x, y;
	float temp;

	if(w_fileview == NULL)
		w_fileview = stdscr;
	getyx(w_fileview, 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(w_fileview, color);
	mvwprintw(w_fileview, y, x, "%s", string);
	wattroff(w_fileview,color);
	refresh();
}

void fileview_mode()
{
	int c;	
	is_vimode = TRUE;
	
	print_line(1);
	keypad(w_fileview, TRUE);		

	show_panel(p_fileview);

	update_panels();
	doupdate();
	
	
	while( (c = getch()) && is_vimode )
	{
		if(fileview_key(c) == -1)
		{
			write_log("sileview_show/fileview_key");
			exit_program();
		}
		wrefresh(w_fileview);
	}

}

void fileview_show(char* filename)
{
	int c;	
	is_vimode = TRUE;
	
	
	free_line();
	
	if(edit_file_name(filename) == -1)
	{
		write_log("fileview_show/edit_file_name error");
		exit_program();
	}	
	
	if (file_init() == -1)
	{
		write_log("fileview_show/file_init");
		exit_program();
	}	
	
	print_line(1);
	keypad(w_fileview, TRUE);		

	show_panel(p_fileview);

	update_panels();
	doupdate();

	wrefresh(w_fileview);
	refresh();
	
	while( (c = getch()) && is_vimode )
	{
		if(fileview_key(c) == -1)
		{
			write_log("sileview_show/fileview_key");
			exit_program();
		}
		wrefresh(w_fileview);
	}

	
	

}

void fileview_show_first(char* filename)
{
	int c;	
	is_vimode = TRUE;

	if(edit_file_name(filename) == -1)
	{
		write_log("fileview_show_first/edit_file_name error");
		exit_program();
	}
	
	if (file_init() == -1)
	{
		write_log("fileview_show_first/file_init error");
		exit_program();
	}	
	print_line(2);	

	show_panel(p_fileview);
	update_panels();
	doupdate();

	

}

int file_init()
{
	int i=0;	
	int b_size = size_fileview_cols - 3;
	char temp[b_size+1];
	ssize_t r_size;
	file_line_pointer ftemp;
	char* p;
	char* lasts;

	line_count = 0;
	memset( temp, 0, b_size);

	if( (filedes = fopen(file_path, "r")) == NULL )
	{
		write_log("file_init/file open error");
		line_add("File is not found");
		return 0;
	}

	fseek( filedes, 0, SEEK_SET);

	while((fgets(temp , b_size, filedes)) != NULL)
	{
		p = strtok_r(temp, "\n", &lasts);

		if(p)
			line_add(p);

		while(p != NULL)
		{
			p = strtok_r(NULL, "\n", &lasts);
			if(p)			
				line_add(p);
		}
	}
	
	if(fclose(filedes) == -1)
	{
		write_log("file_init/file close error");
		return -1;
	}

	return 0;

}

void line_add(char* p)
{
	file_line_pointer temp;

	temp = (file_line_pointer)malloc (sizeof(file_line)+1);
	temp->data = (char*)malloc(strlen(p)* sizeof(char));
	memset(temp->data, 0, strlen(p));
	memcpy(temp->data, p, strlen(p));

	line_count++;

	if(start)
	{
		temp->next = NULL;
		cur_p->next = temp;
		temp->pre = cur_p;
		cur_p = temp;
	}
	else
	{
		temp->pre = NULL;
		temp->next = NULL;
		start = temp;
		cur_p = temp;
		print = temp;
	}
}

void print_line(int color)
{
	file_line_pointer temp;
	int i;
	temp = print;
	werase(w_fileview);	

	for(i= 0 ; (temp != NULL) && (i < size_fileview_lines - 6)  ; i++)
	{
		mvwprintw(w_fileview, print_y + i , print_x, "%s", temp->data);
		temp = temp->next;
	}
	fileview_box(color);	
	refresh();
}

void free_line()
{
	file_line_pointer temp;
	
	while(start)
	{
		temp = start;
		start = start->next;

		free(temp);
	}	
	start = NULL;	
	cur_p = NULL;
	print = NULL;	
	line_count = 0;
	

}

int edit_file_name(char* n_file)
{
	char temppath[255];
	char* temp;
	
	if(!n_file)
	{		
		return -1;
	}

	memset(file_path, 0, 512);
	memset(file_name, 0, 256);

	if(n_file[0] == '~')
	{
		strcpy(temppath, getenv("HOME"));
		strcat(temppath, n_file+1 );	
		strcpy(file_path, temppath);
	}
	else
		strcpy(file_path, n_file);

	temp = strrchr(n_file, '/');

	if(temp != NULL)
		strcpy(file_name, temp+1);
	else 
		strcpy(file_name, n_file);

	if(strlen(file_name) > (size_fileview_cols-40))
	{
		*(file_name + size_fileview_cols - 39) = '~';
		*(file_name + size_fileview_cols - 40) = 0;
	}

	return 0;
}

