#include <ncurses.h>
#include <panel.h>
#include <menu.h>
#include <form.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>

#include "mainlib.h"
#include "varlib.h"
#include "keylib.h"
// 전역 변수
extern	menu_t 	*menudata;	// 메뉴 정보
shortkey_t	*shortkey;

int	index_menu = -1;	// 현재 선택 메뉴, 플래그
int 	flag = FI_MODE;		// 모드 프래그

int		is_vimode;

extern int fifo;
extern int log_flag;

// 윈도우 설정
// 이주현
WINDOW 		*w_titlebar;		// 상단 타이틀 바 
WINDOW 		*w_filelist;		// 중앙 파일리스트 
WINDOW 		*w_bottombar;		// 하단 바
WINDOW		*w_insbar;		// 기본 명령어 윈도우
WINDOW		*w_fileinfo;		// 파일 정보
WINDOW 		**w_submenu;		// 서브 메뉴 윈도우
WINDOW		*w_logo;
WINDOW 		*w_firstview;		//파일 내용 출력 윈도우
// 이태영                                                                        
WINDOW 		*w_fileview;		//파일 내용 출력 윈도우
// 이재승
WINDOW 		*w_dirtree;		// 디렉토리 트리 출력 윈도우
	
// 패널 설정
// 이주현
PANEL	 	*p_titlebar; 		// 상단 타이틀 바 패널
PANEL 		*p_filelist;		// 중앙 파일리스트 패널
PANEL 		*p_bottombar; 		// 하단 바
PANEL		*p_insbar;		// 기본 명령어 윈도우
PANEL 		*p_fileinfo;		// 파일 정보
PANEL 		**p_submenu;		// 서브 메뉴 패널
PANEL_DATA	*pd_submenu;
PANEL_DATA	*temp_submenu;
PANEL		*p_logo;
WINDOW 		*p_firstview;		//파일 내용 출력 윈도우
// 이태영
PANEL		*p_fileview;		//파일 내용 출력 패널
// 이재승
PANEL		*p_dirtree;		// 디렉토리 트리 출력 윈도우

// 메뉴 설정
// 이주현
MENU 		*m_filelist;		// 중앙 파일리스트 메뉴
MENU 		*m_titlebar;		// 상단 타이틀 메뉴
MENU 		**m_submenu;		// 서브 메뉴 
// 이태영

// 이재승

	
// 외부 함수 선언
// 이주현
extern 	void 	titlebar_show	(void);
extern 	void 	bottombar_show	(void);
extern	void	insbar_show		(void);
extern 	void 	filelist_show	(void);
extern 	void 	fileinfo_show	(char *);
extern 	void 	filelist_key	(int);
extern 	void 	filelist_free	(void);
extern 	void 	submenu_show	(void);
extern 	void	submenu_free	(void);
extern 	void	read_shortkey	(void);
// 이태영
extern 	void 	fileview_show		(char* filename);
extern 	void 	fileview_show_first	(char* filename);
extern 	void 	fileview_box		();
extern 	void 	fileview_new		();
extern 	void 	print_in_middle_fileview(int starty, int startx, int width, char *string, chtype color);
extern 	void 	fileview_key		(int);
extern 	int 	command_exec		(char* , int );
extern	void	logview_key			();
extern	void	log_free_line();
extern	void	free_line();
extern	int		is_log();
extern  void fileview_mode();
// 이재승
extern void 	dirtree_new	();
extern void 	dirtree_show	();


extern void 	exit_program	(void);
extern void		create_fifo		(void);
extern void		delete_fifo		(void);

void	exit_drive		(void);
void 	main_drive		(void);
void 	check_size		(void);
void 	check_shell		(void);
void 	exitprocess		(void);
void	error_color		(void);
void	error_menu_cfg	(void);

void main_drive(void) {

	// 변수설정
	// 이주현
	int i;			// for문 구동용 변수
	int c;			// 키 코드 입력용 변수
	int n;
	// 이태영
	int exec = 0;	//실행 결과 
	char path[50];
	//테스트 변수
	char ctemp[10];
	int temp;
	int f=0;
	// 이재승


	// ncurses 모드 초기화 
	initscr();						// curses 모드 시작
	
	if (has_colors() == FALSE) {
		error_color();
	}

	start_color();

	cbreak();						// 라인버퍼링 비활성화
	noecho();						// 키 입력 echo 제거
	keypad(stdscr, TRUE);					// stdscr에 키입력 가능
	curs_set(FALSE);					// 커서 오프
	//curs_set(TRUE);
	// COLOR PAIR
	init_pair(0, COLOR_WHITE, 	COLOR_BLACK);   
	init_pair(1, COLOR_YELLOW, 	COLOR_BLACK);   
	init_pair(2, COLOR_BLUE, 	COLOR_BLACK);   
	init_pair(3, COLOR_RED, 	COLOR_BLACK);   
	init_pair(4, COLOR_GREEN, 	COLOR_BLACK);   
	init_pair(5, COLOR_MAGENTA, 	COLOR_BLACK);   
	init_pair(6, COLOR_CYAN, 	COLOR_BLACK);
	init_pair(7, COLOR_BLACK, 	COLOR_YELLOW);
	
	// 프로그램 구동을 위한 세팅
	getmaxyx(stdscr, screen_size_lines, screen_size_cols);	// 터미널 화면의 크기를 구함
	
	// 실행 환경 점검 
	check_size();	// 터미널 크기 한계 에러 출력
	check_shell();	// bash 이외 에러

	// titlebar 세팅모듈 실행
	// 이주현
	titlebar_show();		// 타이틀바를 세팅
	filelist_show();		// 중앙 파일 리스트를 세팅
	bottombar_show();		// 하단 바를 세팅
	fileinfo_show(NULL);
	submenu_show();
	insbar_show();

	//read_shortkey();		// 단축키를 읽음.
	// 이태영
	fileview_new();
	is_vimode = FALSE;
	fileview_show_first("/etc/lls/HELLO");
	// 이재승
	dirtree_new();
	

	//패널을 업데이트
	update_panels();
	doupdate();

	//화면에 출력
	refresh();

	logo_show();			// 로고를 보여줌

	

	//////////////////////////////////////////////////
	// 키보드 제어
	//////////////////////////////////////////////////
	// 키보드 제어의 모드는 
	// mainlib.h 참조하고
	// 모드 추가 역시 mainlib.h에 추가
	//
	// *동작방식*
	// 1. 사용자 키입력
	// 2. flag에 맞는 모드로 세팅
	// 3. flag에 맞는 모드로 각 key함수 실행
	// 4. flag에 맞는 모드로 종굘(보통 리플레쉬)
	
	// FI_MODE	기본패널 모드
	// DI_MODE	디렉토리 체인지 패널 열렸을 때 
	// VI_MODE	파일 내용 보기 패널 열렸을때\
	//
	//
	//
	/*
	// alt 키 사용을 위한 새로운 정의 
	for (n = 0; n < 255; ++n) {
		char temp[10];
		sprintf(temp, "\033%c", n);
		define_key(temp, n + MY_KEYS);
    	}
    	for (n = KEY_MIN; n < KEY_MAX; ++n) {
		char *value;
		if ((value = keybound(n, 0)) != 0) {
	    		char *temp = malloc(strlen(value) + 2);
	    		sprintf(temp, "\033%s", value);
	    		define_key(temp, n + MY_KEYS);
	    		free(temp);
	    		free(value);
		}
    	}
*/
	keypad(w_filelist, TRUE);
	
	while(flag != QU_MODE) {
		
		while(c = getch()) {
			
			// 메인 드라이브 키 조작
			// 절대 키로  모드 변경 이외에 사용
			// 금지
			//
			if (flag == FI_MODE) {
				switch(c) {
				case 'f' :
					keypad(w_bottombar, TRUE);
					logview_key();
					break;
				}
			}

			// 모드 관련 세팅
			switch(flag) {
			case FI_MODE:	// 이주현
				keypad(w_filelist, TRUE);
				post_menu(m_filelist);
				wrefresh(w_filelist);
				/*show_panel(p_fileview);
				update_panels();
				doupdate(); */
				break;
			case DI_MODE:	// 이재승
				dirtree_show();
				break;
			case TT_MODE:	// 이주현
				keypad(w_titlebar, TRUE);
				post_menu(m_titlebar);
				wrefresh(w_titlebar);
				break;
			case TS_MODE:	// 이주현
				keypad(w_submenu[index_menu], TRUE);
				break;
			case VI_MODE:
				fileview_mode();
				wrefresh(w_fileview);
				refresh();
				break;
			}
	
			// 키 콘트롤 함수 실행
			switch(flag) {
			case FI_MODE:	// 이주현
				filelist_key(c);
				break;
			case DI_MODE:	// 이재승
				//wrefresh(w_filelist);
				//wrefresh(w_titlebar);
				//wrefresh(w_bottombar);
				break;
			case TT_MODE:
				titlebar_key(c);
				if (index_menu > -1) {
					temp_submenu = (PANEL_DATA *)panel_userptr(p_submenu[index_menu]);
					if(temp_submenu->hide == FALSE) {
						hide_panel(p_submenu[index_menu]);
						temp_submenu->hide = TRUE;
						show_panel(p_fileview);
					}
					else {
						show_panel(p_submenu[index_menu]);
						temp_submenu = FALSE;
					}
					update_panels();
					doupdate(); 
					flag = TS_MODE;
				}
				break;
			case TS_MODE:
			      	submenu_key(c);	
				if (index_menu == -1) {
					for (i = 0; i < menudata->n_submenu[0]; i++) {
						temp_submenu = (PANEL_DATA *)panel_userptr(p_submenu[i]);
						temp_submenu->hide = TRUE;
						hide_panel(p_submenu[i]);
						show_panel(p_fileview);
					}
					update_panels();
					doupdate(); 
					flag = FI_MODE;
				}
				break;
			case VI_MODE:
				fileview_key(c);
				break;
			}

			// 모드 마무리
			switch(flag) {
			case FI_MODE:	// 이주현
				wrefresh(w_filelist);
				break;
			case DI_MODE:	// 이재승
				flag = FI_MODE;
				//putchar(' ');
				break;
			case TT_MODE:	// 이주현
				wrefresh(w_titlebar);
				break;
			case TS_MODE:
				wrefresh(w_submenu[index_menu]);
				break;
			case VI_MODE:
				wrefresh(w_fileview);
				break;
			}

		}
	}



	// 종료 작업
	// 이주현
	unpost_menu(m_filelist);	// filelist 메뉴 메모리 반환
	unpost_menu(m_titlebar);	// 타이틀 메뉴 메모리 반환
	free_menu(m_filelist);		// filelist 메뉴 메모리 반환
	free_menu(m_titlebar);		// 타이틀 메뉴 메모리 반환
	filelist_free();		// filelist 아이템 메모리 반환
	//submenu_free();
	// 이태영
	log_flag = 0;
	log_free_line();
	free_line();
	// 이재승
	
	endwin();		//curses 모드 끝냄
}
void exit_drive	(void) {

	exit_program();

}

void exitprocess(void) {
	unpost_menu(m_filelist);	// filelist 메뉴 메모리 반환
	unpost_menu(m_titlebar);	// 타이틀 메뉴 메모리 반환
	free_menu(m_filelist);		// filelist 메뉴 메모리 반환
	free_menu(m_titlebar);		// 타이틀 메뉴 메모리 반환
	filelist_free();		// filelist 아이템 메모리 반환
	endwin();			//curses 모드 끝냄
	exit_drive();
}

// 여기부터는 에러 처리 
void check_size(void) {
	if (screen_size_lines < 25 || screen_size_cols < 120) {
		endwin();
		printf("Sorry. your screen size is very small. (Recommend 120+ x 25+)\n");
		printf("your screen size : (%d, %d)\n", screen_size_cols, screen_size_lines);
		exit_drive();
	}
}

void check_shell(void) {
	char *token;
	char *lasts;
	char temp[255];

	strcpy(temp, getenv("SHELL"));

	token = strtok_r(temp, "/", &lasts);
	if (strcmp(token, "bash") == 0)
		return;
	while((token = strtok_r(NULL, "/", &lasts)) != NULL) {
		if (strcmp(token, "bash") == 0)
			return;
	}
	
	endwin();
	printf("Sorry. your shell is not Bash.\n");
	printf("your shell : %s", getenv("SHELL"));
	exit_drive();
}

void error_shortkey(void) {
	endwin();
	printf("Sorry. Failed to read menu.cfg\n");
	printf("Perhaps, this is Shortcut Conflict Error\n");		
	exit_drive();
}

void error_read_menu(void) {
	endwin();
	printf("Sorry. Failed to read menu.cfg\n");
	exit_drive();
}

void error_color(void) {
	endwin();
	printf("Soory. You terminal does not support color\n");
	exit_drive();
}
