/* 
 *    Programmed By: Mohammed Isam Mohammed [mohammed_isam1984@yahoo.com]
 *    Copyright 2013, 2014 (c)
 * 
 *    file: main.c
 *    This file is part of Prime.
 *
 *    Prime is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    Prime is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with Prime.  If not, see <http://www.gnu.org/licenses/>.
 */    
#include "../corelib/dialogs.h"
#include "defs.h"
#include "edit.h"
//#include "print.h"
#include "find.h"
#include "cutcopy.h"
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <poll.h>
#include <signal.h>
#include <termios.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <pwd.h>
#include <time.h>

struct passwd *pass;//will be used to find the home dir
time_t tm;

static int one(const struct dirent *unused);

int read_config_file();
int write_config_file();
int NEW_GNU_DOS_LEVEL = 0;

//extern int PRINTING;
//extern void showPrintDialogBox();
//extern void freePrinters();
//extern int findInstalledPrinters();

extern void showFileMenu(int visible);
extern void showHelpMenu(int visible);
extern void showEditMenu(int visible);
//extern int msgBox(char *msg, int Buttons, msgType tmsg);

//extern void setScreenColors(int FG, int BG);
//extern void getScreenSize();
//extern void clearScreen();

extern void cutMarked();
extern void cutOne();
extern void markAll();
extern void unMarkAll();

//static sig_atomic_t end = 0;
/***************************************
 * sighandler(): 
 * Procedure that sets trap to the system
 * signals that are issued when user 
 * presses CTRL-C or CTRL-Z...
 * *************************************/
void sighandler(int signo)
{
    fprintf(log_file, "SIGNAL %d received\n", signo);
    if(signo == 2) 
    {	//CTRL-C pressed
      copyMarked();
      //redraw main window but don't clear the area
      drawBox(1, 1, SCREEN_H, SCREEN_W, " Prime  for GNU/Linux ", NO);
    } 
    else if(signo == SIGTSTP) 
    { //CTRL-Z pressed
      int i = msgBox("Are you sure you want to exit?", YES | NO, CONFIRM);
      if(i == YES) 
      { 	//exit gracefully
	clearScreen(); 
	setScreenColors(WHITE, BGBLACK);
	fprintf(log_file, "Restoring terminal..\n");
	restoreTerminal();
	tm = time(NULL);
	fprintf(log_file, "Closing files and Exiting Prime..\n");
	fprintf(log_file, "System time and date: %s", ctime(&tm));
	fcloseall();
	//freePrinters();
	clearScreen(); 
	exit(0); 
      } 
      else 
      {
	setScreenColors(WHITE, BGBLUE);
	refreshFileView();
	refreshDirView();
      }//end inner if
    } 
    else 
    {
      end = 1;
    }//end outer if
}//end sighandler

struct termios oldtio, curtio;
struct sigaction sa;

/***************************************
 * main(): 
 * Main program loop.
 * *************************************/
int main(int argc, char **argv) 
{
  if(argc > 1) 
  {
   int i;
   for(i = 1; i < argc; i++) 
   {
    if(strcmp(argv[i], "--level1") == 0 || strcmp(argv[i], "-l1") == 0)
      NEW_GNU_DOS_LEVEL = 1;
    else if(strcmp(argv[i], "--level2") == 0 || strcmp(argv[i], "-l2") == 0)
      NEW_GNU_DOS_LEVEL = 2;
    else if(strcmp(argv[i], "--level3") == 0 || strcmp(argv[i], "-l3") == 0)
      NEW_GNU_DOS_LEVEL = 3;
    else if(strcmp(argv[i], "--level4") == 0 || strcmp(argv[i], "-l4") == 0)
      NEW_GNU_DOS_LEVEL = 4;
    else if(strcmp(argv[i], "--level5") == 0 || strcmp(argv[i], "-l5") == 0)
      NEW_GNU_DOS_LEVEL = 5;
    else if(strcmp(argv[i], "--no-log") == 0) 
    {
      //******Start Prime with no log information
      log_file = fopen("/dev/null", "w");
    } 
    else if(strcmp(argv[i], "--version" ) == 0
	    || strcmp(argv[i], "-v")) 
    {
      //******Show version
      printf("\nPrime version 1.0.\n");
    } 
    else if(strcmp(argv[i], "--export") == 0
	    || strcmp(argv[i], "-e") == 0) 
    {
      //******Export directory tree
      if(argc < 4) 
      {
	printf("\nMissing arguments: %s -e|--export dirname filename\n"
	"\nWhere: dirname is the name of directory whose tree is to be read\n"
	"       filename is the file to which the dir tree is to be written\n"
	     , argv[0]);
	exit(1);
      }
      exportTreeFromCommandLine(argv[i+1], argv[i+2]);
      i += 2;
      //exit(0);
    } 
    else if(strcmp(argv[i], "--dir") == 0
	    || strcmp(argv[i], "-d") == 0) 
    {
      //******Start with directory dir
      if(argc < 3) 
      {
	printf("\nMissing arguments: %s -d|--dir dirname\n"
	     "\nWhere: dirname is the name of directory to load into Prime\n"
	     , argv[0]);
	exit(1);
      }
      //check for '~'in dir name
      char *tmp = (char *) malloc(MAX_DIR_NAME_LEN);
      strcpy(tmp, argv[i+1]);
      if(strchr(tmp, '~')) 
      {
	char *tmp2 = (char *) malloc(MAX_DIR_NAME_LEN);
	strcpy(tmp2, argv[i+1]+((strchr(tmp, '~')+1)-tmp));
	if((pass = getpwuid(geteuid())))
	  printf("\nError: couldn't open home directory.\n");
	strcpy(tmp, pass->pw_dir);
	strcat(tmp, "/");
	strcat(tmp, tmp2);
	strcat(tmp, "\0");
	free(tmp2);
      }
      struct stat st;
      if(stat(tmp, &st) == -1) 
      {
	printf("Directory '%s' doesn't exist.\n", tmp);
	printf("Starting Prime from current working directory.\n");
	printf("Press any key..");
	char c = getchar();
      } 
      else chdir(tmp);
      //continue to the rest of program startup....
      free(tmp);
      //Open log file
      if((pass = getpwuid(geteuid())))
	printf("\nError: couldn't open home directory.\n");
      log_file_name = (char *) malloc(strlen(pass->pw_dir)+8);
      strcpy(log_file_name, pass->pw_dir);
      strcat(log_file_name, "/");
      strcat(log_file_name, "Prime.log");
      if(!(log_file = fopen(log_file_name, "w"))) 
      {
	printf("\nFatal error: couldn't open logfile 'Prime.log'.\n"
	  "If you want to start Prime with no log, type './Prime --no-log'\n"
	  "Aborting.\n");
	exit(1);
      }
      i++;
    } 
    else if(strcmp(argv[i], "--help") == 0 
	    || strcmp(argv[i], "-h") == 0) 
    {
      //******Show command line help
      printf("Prime for GNU/Linux, Version 1.0\n"
	     "By Mohammed Isam, 2013, 2014\n"
	     "Prime is a GNU software, as part of the GnuDOS package\n\n"
	     "Prime is a file manager for the GNU/Linux console/xterm.\n"
	     "It was developed with ease of use and simplicity in mind.\n"
	     "\nUsage: %s [options] [log-file-name]\n"
	     "\nOptions:\n  --no-log:\tstart Prime with no log information\n"
	     "  [-e, --export] dirname filename:\n"
	     "	\texport directory tree of 'dirname' into 'filename'\n"
	     "  [-d,--dir] dirname:\n"
	     "  \tdirname is the name of directory to load into Prime\n"
	     "  --help, -h:\tshow this help\n\nlog-file-name:\tthe name"
	     " of a file to be used as log instead of default 'Prime.log'\n",
	     argv[0]);
      exit(0);
    } 
    else 
    {
      //******Open specified file as log file
      log_file_name = (char *) malloc(strlen(argv[i]));
      strcpy(log_file_name, argv[i]);
      if(!(log_file = fopen(log_file_name, "w"))) 
      {
	printf("Error: couldn't open logfile '%s'.\n", log_file_name);
	printf("Would you like to use default file 'Prime.log'? [Y/n]:");
	char c = getchar();
	if(c == 'Y' || c == 'y' || c == '\n') 
	{
	  if((pass = getpwuid(geteuid())))
	    printf("\nError: couldn't open home directory.\n");
	  log_file_name = (char *) malloc(strlen(pass->pw_dir)+8);
	  strcpy(log_file_name, pass->pw_dir);
	  strcat(log_file_name, "/");
	  strcat(log_file_name, "Prime.log");
	  if(!(log_file = fopen(log_file_name, "w"))) 
	  {
	    printf("\nFatal error: couldn't open logfile 'Prime.log'. Aborting.\n");
	    exit(1);
	  }
	} 
	else 
	{
	    printf("Couldn't open logfile. If you want to start Prime with no \
log, type './Prime --no-log'\n");
	    exit(1);
	}
      }
    }
   }
  } 
  else 
  {
    OpenLog:
    if((pass = getpwuid(geteuid())))
      printf("\nError: couldn't open home directory.\n");
    log_file_name = (char *) malloc(strlen(pass->pw_dir)+8);
    strcpy(log_file_name, pass->pw_dir);
    strcat(log_file_name, "/");
    strcat(log_file_name, "Prime.log");
    if(!(log_file = fopen(log_file_name, "w"))) {
      printf("\nFatal error: couldn't open logfile 'Prime.log'.\n"
	  "If you want to start Prime with no log, type './Prime --no-log'\n"
	  "Aborting.\n");
      exit(1);
    }
  }
 //}
 read_config_file();
 
 cwd = getcwd(NULL, 0);
 tm = time(NULL);
 fprintf(log_file, "Starting Prime in: %s\n", cwd);
 fprintf(log_file, "System time and date: %s", ctime(&tm));
 fprintf(log_file, "Log_file: %s\n", log_file_name);
 fprintf(log_file, "Program started: in the main function..\n");
 init();			//some initialization code
 fprintf(log_file, "Initializing variables [ OK ]..\n");
 
 clearScreen();			//clear the screen
 setScreenColors(WHITE, BGBLUE);
 //draw main window
 drawBox(1, 1, SCREEN_H, SCREEN_W, " Prime for GNU/Linux ", YES);
 drawMenuBar(2, 2, SCREEN_W-2); //draw main menu bar

 //draw right sub-window
 drawBox(3, (int)(SCREEN_W/2), SCREEN_H-5, SCREEN_W-1, " File view ", YES);
 //draw bottom sub-window
 drawBox(SCREEN_H-4, 2, SCREEN_H-1, SCREEN_W-1, " Quick functions ", YES);
 //draw left sub-window
 drawBox(3, 2, SCREEN_H-5, (int)(SCREEN_W/2)-1, " Directory view ", YES);

 //redraw main window but don't clear the area
 drawBox(1, 1, SCREEN_H, SCREEN_W, " Prime for GNU/Linux ", NO);
 fprintf(log_file, "Setting windows and main menu [ OK ]..\n");

 //CHECK FOR PRINTERS ON SYSTEM
 /*fprintf(log_file, "Checking for installed printers");
 if(findInstalledPrinters() != 0) {
  fprintf(log_file, " [ERROR]: Couldn't find printers..\n");
 } else fprintf(log_file, " [ OK ]..\n");
 */
 refreshBottomView();
 fprintf(log_file, "Scanning current working directory [ OK ]..\n");
 scanDir(".");

 int ch;
 while(!end) 
 {	//infinite program loop//
  fprintf(log_file, "Waiting for user input..\n");
  ch = getKey();
  switch(ch) 
  {
   case(DEL_KEY):
     if(GNU_DOS_LEVEL > 3) break;
do_del:
     if(numStarred == 0) 
     {
       if(activeWindow == DIR_WIN) 
       {
	 int k = msgBox("Are you sure you want to delete\nthis directory and \
all its subdirectories?", YES|NO, CONFIRM);
	 if(k == YES) 
	 {
	   deleteThisDir(dirs[firstVisDir+selectedDir], 0);
	 }
       } 
       else 
       { 
	 int j = msgBox("Are you sure you want to delete this file?", 
			YES|NO, CONFIRM);
	 if(j == YES) remove(files[firstVisFile+selectedFile]);
       }//end inner if/else
     } 
     else 
     {//end outer if
       deleteMarked();
     }//end outer else
     setScreenColors(WHITE, BGBLUE);
     scanDir(cwd);
     break;
   case(UP_KEY):
     if(GNU_DOS_LEVEL > 1) break;
do_up:
     if(activeWindow == DIR_WIN) 
     {
       selectedDir--; 
       if(selectedDir < 0) 
       {
	 selectedDir = 0;
	 if(firstVisDir > 0) { firstVisDir--; refreshDirView(); }
       } 
       else 
       {
	int j;
	setScreenColors(GREEN, BGBLUE);
	fprintf(stdout, "\x1b[%d;%dH%s", selectedDir+5, 3, dirHighLight);
	//fprintf(stdout, "\x1b[%d;%dH%c%s", selectedDir+5, 3, 
	//	dirStar[firstVisDir+selectedDir+1], dirs[firstVisDir+selectedDir+1]);
	if(strlen(dirs[firstVisDir+selectedDir+1]) >= MAX_DIR_NAME_LEN) 
	{
	  fprintf(stdout, "\x1b[%d;%dH%c", selectedDir+5, 3, 
		  dirStar[firstVisDir+selectedDir+1]);
	for(j = 0; j < MAX_DIR_NAME_LEN-3; j++) 
	  fprintf(stdout, "%c", dirs[firstVisDir+selectedDir+1][j]);
	fprintf(stdout, "..");
	} 
	else 
	{ 
	  fprintf(stdout, "\x1b[%d;%dH%c%s", selectedDir+5, 3, 
		    dirStar[firstVisDir+selectedDir+1], 
		    dirs[firstVisDir+selectedDir+1]);
	}//end if
	setScreenColors(BLUE, BGWHITE);
	fprintf(stdout, "\x1b[%d;%dH%s", selectedDir+4, 3, dirHighLight);
	//fprintf(stdout, "\x1b[%d;%dH%c%s", selectedDir+4, 3, 
	//	dirStar[firstVisDir+selectedDir], dirs[firstVisDir+selectedDir]);
	if(strlen(dirs[firstVisDir+selectedDir]) >= MAX_DIR_NAME_LEN) 
	{
	  fprintf(stdout, "\x1b[%d;%dH%c", selectedDir+4, 3, 
		  dirStar[firstVisDir+selectedDir]);
	for(j = 0; j < MAX_DIR_NAME_LEN-3; j++) 
	  fprintf(stdout, "%c", dirs[firstVisDir+selectedDir][j]);
	fprintf(stdout, "..");
	} 
	else 
	{ fprintf(stdout, "\x1b[%d;%dH%c%s", selectedDir+4, 3, 
		    dirStar[firstVisDir+selectedDir], 
		    dirs[firstVisDir+selectedDir]);
	}//end if
       }//end if
       fprintf(stdout, "\e[3;3H");	//move cursor to point to window
     } 
     else 
     {
       int j;
       if(strcmp(files[0], "(Empty folder)") == 0) break;//this dir is empty!!
       selectedFile--;
       if(selectedFile < 0) 
       {
	 selectedFile = 0;
	 if(firstVisFile > 0) { firstVisFile--; refreshFileView(); }
       } 
       else 
       {
	setScreenColors(GREEN, BGBLUE);
	fprintf(stdout, "\x1b[%d;%dH%s", selectedFile+5, 
		(SCREEN_W/2)+1, fileHighLight);
	//fprintf(stdout, "\x1b[%d;%dH%c%s", selectedFile+5, (SCREEN_W/2)+1, 
	//	      fileStar[firstVisFile+selectedFile+1], files[firstVisFile+selectedFile+1]);
	if(strlen(files[firstVisFile+selectedFile+1]) >= MAX_DIR_NAME_LEN) 
	{
	  fprintf(stdout, "\x1b[%d;%dH%c", selectedFile+5, (SCREEN_W/2)+1, 
		  fileStar[firstVisFile+selectedFile+1]);
	for(j = 0; j < MAX_DIR_NAME_LEN-3; j++) 
	  fprintf(stdout, "%c", files[firstVisFile+selectedFile+1][j]);
	fprintf(stdout, "..");
	} 
	else 
	{ 
	  fprintf(stdout, "\x1b[%d;%dH%c%s", selectedFile+5, (SCREEN_W/2)+1, 
		    fileStar[firstVisFile+selectedFile+1], 
		    files[firstVisFile+selectedFile+1]);
	}//end if
	setScreenColors(BLUE, BGWHITE);
	fprintf(stdout, "\x1b[%d;%dH%s", selectedFile+4, 
		(SCREEN_W/2)+1, fileHighLight);
	//fprintf(stdout, "\x1b[%d;%dH%c%s", selectedFile+4, (SCREEN_W/2)+1, 
	//	      fileStar[firstVisFile+selectedFile], files[firstVisFile+selectedFile]);
	if(strlen(files[firstVisFile+selectedFile]) >= MAX_DIR_NAME_LEN) 
	{
	  fprintf(stdout, "\x1b[%d;%dH%c", selectedFile+4, (SCREEN_W/2)+1, 
		  fileStar[firstVisFile+selectedFile]);
	for(j = 0; j < MAX_DIR_NAME_LEN-3; j++) 
	  fprintf(stdout, "%c", files[firstVisFile+selectedFile][j]);
	fprintf(stdout, "..");
	} 
	else 
	{ 
	  fprintf(stdout, "\x1b[%d;%dH%c%s", selectedFile+4, (SCREEN_W/2)+1, 
		    fileStar[firstVisFile+selectedFile], 
		    files[firstVisFile+selectedFile]);
	}//end if
       }//end if
       fprintf(stdout, "\e[3;%dH",(SCREEN_W/2)+2);//cursor to point to window
     } 
     break;
   case(DOWN_KEY):
     if(GNU_DOS_LEVEL > 1) break;
do_down:
     if(activeWindow == DIR_WIN) 
     {
       selectedDir++;
       //if totalDirs is less than numVisDirs
       if(selectedDir >= totalDirs) selectedDir--;
       if(selectedDir >= numVisDirs) 
       {
	 selectedDir = numVisDirs-1;
	 if((firstVisDir+numVisDirs) < totalDirs) 
	 { 
	   firstVisDir++; refreshDirView(); 
	}
       } 
       else 
       {
	 int j;
	setScreenColors(GREEN, BGBLUE);
	fprintf(stdout, "\x1b[%d;%dH%s", selectedDir+3, 3, dirHighLight);
	//fprintf(stdout, "\x1b[%d;%dH%c%s", selectedDir+3, 3, 
	//	dirStar[firstVisDir+selectedDir-1], dirs[firstVisDir+selectedDir-1]);
	if(strlen(dirs[firstVisDir+selectedDir-1]) >= MAX_DIR_NAME_LEN) 
	{
	  fprintf(stdout, "\x1b[%d;%dH%c", selectedDir+3, 3, 
		  dirStar[firstVisDir+selectedDir-1]);
	for(j = 0; j < MAX_DIR_NAME_LEN-3; j++) 
	  fprintf(stdout, "%c", dirs[firstVisDir+selectedDir-1][j]);
	fprintf(stdout, "..");
	} 
	else 
	{ 
	  fprintf(stdout, "\x1b[%d;%dH%c%s", selectedDir+3, 3, 
		    dirStar[firstVisDir+selectedDir-1], 
		    dirs[firstVisDir+selectedDir-1]);
	}//end if
	setScreenColors(BLUE, BGWHITE);
	fprintf(stdout, "\x1b[%d;%dH%s", selectedDir+4, 3, dirHighLight);
	//fprintf(stdout, "\x1b[%d;%dH%c%s", selectedDir+4, 3, 
	//	dirStar[firstVisDir+selectedDir], dirs[firstVisDir+selectedDir]);
	if(strlen(dirs[firstVisDir+selectedDir]) >= MAX_DIR_NAME_LEN) 
	{
	  fprintf(stdout, "\x1b[%d;%dH%c", selectedDir+4, 3, 
		  dirStar[firstVisDir+selectedDir]);
	for(j = 0; j < MAX_DIR_NAME_LEN-3; j++) 
	  fprintf(stdout, "%c", dirs[firstVisDir+selectedDir][j]);
	fprintf(stdout, "..");
	} 
	else 
	{ 
	  fprintf(stdout, "\x1b[%d;%dH%c%s", selectedDir+4, 3, 
		    dirStar[firstVisDir+selectedDir], 
		    dirs[firstVisDir+selectedDir]);
	}//end if
       }//end if
       fprintf(stdout, "\e[3;3H");	//move cursor to point to window
     } 
     else 
     {
       if(strcmp(files[0], "(Empty folder)") == 0) break;//this dir is empty!!
       selectedFile++;
       //if totalFiles is less than numVisFiles
       if(selectedFile >= totalFiles) selectedFile--;
       if(selectedFile >= numVisFiles) {
	 selectedFile = numVisFiles-1;
	 if((firstVisFile+numVisFiles) < totalFiles) 
	 { 
	   firstVisFile++; refreshFileView(); 
	}
       } 
       else 
       {
	 int j;
	setScreenColors(GREEN, BGBLUE);
	fprintf(stdout, "\x1b[%d;%dH%s", selectedFile+3, 
		(SCREEN_W/2)+1, fileHighLight);
	//fprintf(stdout, "\x1b[%d;%dH%c%s", selectedFile+3, (SCREEN_W/2)+1, 
	//	      fileStar[firstVisFile+selectedFile-1], files[firstVisFile+selectedFile-1]);
	if(strlen(files[firstVisFile+selectedFile-1]) >= MAX_DIR_NAME_LEN) 
	{
	  fprintf(stdout, "\x1b[%d;%dH%c", selectedFile+3, 
		  (SCREEN_W/2)+1, fileStar[firstVisFile+selectedFile-1]);
	for(j = 0; j < MAX_DIR_NAME_LEN-3; j++) 
	  fprintf(stdout, "%c", files[firstVisFile+selectedFile-1][j]);
	fprintf(stdout, "..");
	} 
	else 
	{ 
	  fprintf(stdout, "\x1b[%d;%dH%c%s", selectedFile+3, (SCREEN_W/2)+1, 
		    fileStar[firstVisFile+selectedFile-1], 
	   files[firstVisFile+selectedFile-1]);
	}//end if
	setScreenColors(BLUE, BGWHITE);
	fprintf(stdout, "\x1b[%d;%dH%s", selectedFile+4, 
		(SCREEN_W/2)+1, fileHighLight);
	//fprintf(stdout, "\x1b[%d;%dH%c%s", selectedFile+4, (SCREEN_W/2)+1, 
	//	      fileStar[firstVisFile+selectedFile], files[firstVisFile+selectedFile]);
	if(strlen(files[firstVisFile+selectedFile]) >= MAX_DIR_NAME_LEN) 
	{
	  fprintf(stdout, "\x1b[%d;%dH%c", selectedFile+4, 
		  (SCREEN_W/2)+1, fileStar[firstVisFile+selectedFile]);
	for(j = 0; j < MAX_DIR_NAME_LEN-3; j++) 
	  fprintf(stdout, "%c", files[firstVisFile+selectedFile][j]);
	fprintf(stdout, "..");
	} 
	else 
	{ 
	  fprintf(stdout, "\x1b[%d;%dH%c%s", selectedFile+4, (SCREEN_W/2)+1, 
		    fileStar[firstVisFile+selectedFile], 
		    files[firstVisFile+selectedFile]);
	}//end if
       }//end if
       fprintf(stdout, "\e[3;%dH",(SCREEN_W/2)+2);//cursor to point to window
     } 
     break;
   case(TAB_KEY):	//toggle active window with TAB press
     if(activeWindow == DIR_WIN) 
	activeWindow = FILE_WIN;
     else 
	activeWindow = DIR_WIN;
     refreshFileView();
     refreshDirView();
     break;
   case(ENTER_KEY):
     if(ALT) 
     {
       showPropertiesDialog();
       setScreenColors(WHITE, BGBLUE);
       scanDir(cwd);
       break;
     }
     else
     {
      if(activeWindow == DIR_WIN) 
      {	//navigate to the selected directory
        scanDir(dirs[firstVisDir+selectedDir]);
      } break;
     }
   case(SPACE_KEY):			//toggle select/unselect file or directory
     toggleSelected();
     break;
   case('s'):
     if(CTRL) 
     {
      if(GNU_DOS_LEVEL <= 4) break;
      findFile();
      setScreenColors(WHITE, BGBLUE);
      scanDir(cwd);
     } 
     else goto insert_char;
     break;
   case('f'):
     if(ALT) 
     {
      if(GNU_DOS_LEVEL > 1) break;
      fprintf(log_file, "Opening file menu..\n");
      showFileMenu(YES);
      fprintf(log_file, "Waiting for user input..\n");
      break;
     } 
     else if(CTRL) 
     {
   //case(CTRL_F_KEY):			//open the find file dialog box
      if(GNU_DOS_LEVEL > 4) break;
      findFile();
      setScreenColors(WHITE, BGBLUE);
      scanDir(cwd);
     } 
     else goto insert_char;
     break;
   //case(ALT_E_KEY):			//showup the edit menu
   case('e'):
     if(CTRL) 
     {
       if(GNU_DOS_LEVEL > 2) goto do_end;
     }
     else if(ALT) 
     {
      if(GNU_DOS_LEVEL > 1) break;
      fprintf(log_file, "Opening edit menu..\n");
      showEditMenu(YES);
      fprintf(log_file, "Waiting for user input..\n");
      break;
     } 
     else if(CTRL) 
     {
   //case(CTRL_E_KEY):
      exportTree(YES);
      setScreenColors(WHITE, BGBLUE);
      scanDir(cwd);
     } 
     else goto insert_char;
     break;
   //case(ALT_H_KEY):			//showup the help menu
   case('h'):
     if(ALT) 
     {
      if(GNU_DOS_LEVEL > 1) break;
      fprintf(log_file, "Opening help menu..\n");
      showHelpMenu(YES);
      fprintf(log_file, "Waiting for user input..\n");
     } 
     else goto insert_char;
     break;
   //case(CTRL_X_KEY):			//CTRL-X --> cut starred items
   case('x'):
     if(CTRL) 
     {
      if(GNU_DOS_LEVEL >= 4) break;
      cutMarked();			//found in edit.c
     } 
     else goto insert_char;
     break;
   //case(CTRL_V_KEY):			//call paste marked function
   case('v'):
     if(CTRL) 
     {
       if(GNU_DOS_LEVEL > 2) break;
       pasteMarked();
     } 
     else goto insert_char;
     break;
   //case(CTRL_P_KEY):			//call paste marked function
   case('p'):
     if(CTRL) 
     {
      if(GNU_DOS_LEVEL > 1) goto do_down;
      msgBox("Oops! This function is currently not implemented.", OK, INFO);
      //fprintf(log_file, "Showing Print dialog box..\n");
      //showPrintDialogBox();
      setScreenColors(WHITE, BGBLUE);
	refreshFileView();
	refreshDirView();
     }
     else goto insert_char;
     break;
   //case(CTRL_A_KEY):			//mark all
   case('a'):
     if(CTRL) 
     {
      if(GNU_DOS_LEVEL > 2) goto do_home;//GNU key binding
      markAll();
      if(activeWindow == DIR_WIN)
	fprintf(log_file, "Selecting All directories..\n");
      else fprintf(log_file, "Selecting All files..\n");
      setScreenColors(WHITE, BGBLUE);
      refreshFileView();
      refreshDirView();
      refreshBottomView();
     } 
     else goto insert_char;
     break;
   //case(CTRL_O_KEY):			//open location..
   case('w'):
     if(CTRL) 
     {
      if(GNU_DOS_LEVEL < 4)
      {
	clearSelection();
	fprintf(log_file, "Clearing all selections..\n");
      }
      else
      {
        cutMarked();			//found in edit.c
      }
     } 
     else goto insert_char;
     break;
   case('o'):
    if(CTRL) 
    {
     if(1) ;
     char *res = inputBox("Enter directory path to open:", "Open Location");
     if(res != NULL) 
     {
      //************** check for '~'
      char *tmp = (char *) malloc(MAX_DIR_NAME_LEN);
      strcpy(tmp, res);
      if(strchr(tmp, '~')) 
      {
	char *tmp2 = (char *) malloc(MAX_DIR_NAME_LEN);
	strcpy(tmp2, res+((strchr(res, '~')+1)-res));
	struct passwd *pass;//will be used to find the home dir
	if((pass = getpwuid(geteuid())))
	  ;//printf("\nError: couldn't open home directory.\n");
	strcpy(tmp, pass->pw_dir);
	strcat(tmp, "/");
	strcat(tmp, tmp2);
	strcat(tmp, "\0");
	free(tmp2);
      }//***************
      scanDir(tmp);
      free(tmp);
	//scanDir(res);
	refreshFileView();
	refreshDirView();
     }
     fprintf(log_file, "Opening '%s'..\n", res);
     //free(res);
    } 
    else goto insert_char;
    break;
   case(HOME_KEY):
     if(GNU_DOS_LEVEL > 1) break;
do_home:
     if(activeWindow == DIR_WIN) 
     {
       firstVisDir = 0;
       selectedDir = 0;
       refreshDirView();
     } 
     else if(activeWindow == FILE_WIN) 
     {
       firstVisFile = 0;
       selectedFile = 0;
       refreshFileView();
     } break;
   case(END_KEY):
     if(GNU_DOS_LEVEL > 1) break;
do_end:
     if(activeWindow == DIR_WIN) 
     {
       if(totalDirs <= numVisDirs) 
       {
	 selectedDir = totalDirs-1;
       }
       else 
       {
	 firstVisDir = totalDirs-numVisDirs;
	 selectedDir = numVisDirs-1;
       }//end inner if
       refreshDirView();
     } 
     else 
     {//end outer if
       if(totalFiles <= numVisFiles) 
       {
	 selectedFile = totalFiles-1;
       }
       else 
       {
	 firstVisFile = totalFiles-numVisFiles;
	 selectedFile = numVisFiles-1;
       }//end inner if
       refreshFileView();
     }//end outer else
     break;
   //case(CTRL_Q_KEY):
   case('g'):
    if(CTRL) 
    {
     if(GNU_DOS_LEVEL < 3) break;
     goto do_exit;
    } 
    else goto insert_char;
    break;
   case('d'):
    if(CTRL) 
    {
       if(GNU_DOS_LEVEL > 3) goto do_del;
    } 
    else goto insert_char;
    break;
   case('q'):
    if(CTRL) 
    {
     if(GNU_DOS_LEVEL > 4) break;
do_exit:
     if(1) ;
      int i = msgBox("Are you sure you want to exit?", YES | NO, CONFIRM);
      if(i == YES) 
      { 	//exit gracefully
	setScreenColors(WHITE, BGBLACK);
	clearScreen(); 
	fprintf(log_file, "Restoring terminal..\n");
	restoreTerminal();
	tm = time(NULL);
	fprintf(log_file, "Closing files and Exiting Prime..\n");
	fprintf(log_file, "System time and date: %s", ctime(&tm));
	fcloseall();
	setScreenColors(WHITE, BGBLACK);
	clearScreen(); 
	exit(0); 
      } 
      else 
      {
	setScreenColors(WHITE, BGBLUE);
	refreshFileView();
	refreshDirView();
      }//end inner if
    } 
    else goto insert_char;
    break;
   //case(CTRL_C_KEY):
   case('c'):
     if(CTRL) 
     {
      copyMarked();
     } 
     else goto insert_char;
     break;
   //case(CTRL_Z_KEY):
   case('z'):
     if(CTRL) 
     {
      unMarkAll();
      if(activeWindow == DIR_WIN)
	fprintf(log_file, "Deselecting All directories..\n");
      else fprintf(log_file, "Deselecting All files..\n");
     } 
     else goto insert_char;
     break;
   //case(CTRL_N_KEY):
   case('n'):
   if(CTRL) 
   {
    if(GNU_DOS_LEVEL > 1) goto do_down;
    inputBox("Enter directory name to create:", "New Directory");
    char *res2 = (char *) malloc(MAX_DIR_NAME_LEN);
    strcpy(res2, input);
    if(res2 != NULL) {
      struct stat st;
      if(stat(res2, &st) == -1) 
      {
	mkdir(res2, 0700);//check if it doesn't exist, create it
	fprintf(log_file, "Creating directory %s..\n", res2);
      }
      else 
      {
	msgBox("Directory already exists!", OK, ERROR);
	fprintf(log_file, "Directory %s already exists..\n", res2);
      }
      scanDir(cwd);
      refreshFileView();
      refreshDirView();
    } 
    free(res2);
   } 
   else goto insert_char;
   break;
   ////////////////////////////////////////////////////
   default:
     //browse to the first entry starting with the entered character
insert_char:
     if(ch >= 33 && ch <= 126) 
     {//if1
       int i, x = -1;
	  if(activeWindow == DIR_WIN) 
       {//if2
	 //search from this point to the end
	 for(i = firstVisDir+selectedDir+1; i < totalDirs; i++)
	   if(dirs[i][0] == ch || dirs[i][0] == ch-32) { x=i; break; }
	 //if the previous loop didn't find anything, try again
	 //starting from the top to the current point
	 if(i >= totalDirs)
	   for(i = 0; i <= firstVisDir+selectedDir; i++)
	      if(dirs[i][0] == ch || dirs[i][0] == ch-32) { x=i; break; }
	 //check to see if we found any result
	 if(x >= 0) 
	 {
	   selectedDir = x-firstVisDir;
	   if(totalDirs <= numVisDirs) { refreshDirView(); continue; }
	   if(selectedDir < 0) {firstVisDir += selectedDir; selectedDir = 0;}
	   if(selectedDir >= numVisDirs) 
	   { 
	     firstVisDir += selectedDir-numVisDirs+1;
	     selectedDir = numVisDirs-1;
	   }
	   if(totalDirs-firstVisDir < numVisDirs) 
	   { 
	     selectedDir = firstVisDir;
	     firstVisDir = totalDirs-numVisDirs; 
	     selectedDir -= firstVisDir; 
	  } 
	   refreshDirView();
	 }
	//////////////////////////////////////////////////
       } 
       else if(activeWindow == FILE_WIN) 
       {//if2
	 //search from this point to the end
	 for(i = firstVisFile+selectedFile+1; i < totalFiles; i++)
	   if(files[i][0] == ch || files[i][0] == ch-32) { x=i; break; }
	 //if the previous loop didn't find anything, try again
	 //starting from the top to the current point
	 if(i >= totalFiles)
	   for(i = 0; i <= firstVisFile+selectedFile; i++)
	      if(files[i][0] == ch || files[i][0] == ch-32) { x=i; break; }
	 //check to see if we found any result
	 if(x >= 0) 
	 {
	   selectedFile = x-firstVisFile;
	   if(totalFiles <= numVisFiles) { refreshFileView(); continue; }
	   if(selectedFile < 0) {firstVisFile+=selectedFile; selectedFile = 0;}
	   if(selectedFile >= numVisFiles) 
	   { 
	     firstVisFile += selectedFile-numVisFiles+1;
	     selectedFile = numVisFiles-1;
	   } 
	   if(totalFiles-firstVisFile < numVisFiles) 
	   { 
	     selectedFile = firstVisFile;
	     firstVisFile = totalFiles-numVisFiles; 
	     selectedFile -= firstVisFile;
	  } 
	   refreshFileView();
	 }
       }//end if2
     }//end if1
     break;
  }//end switch
  setScreenColors(WHITE, BGBLUE);
 }//end while
 
 fprintf(log_file, "Restoring terminal..\n");
 restoreTerminal();
 fprintf(log_file, "Closing files and Exiting Prime..\n");
 time_t tm = time(NULL);
 fprintf(log_file, "System time and date: %s", ctime(&tm));
 fcloseall();
 //freePrinters();
 exit(0);
}

void toggleSelected() 
{
  setScreenColors(BLUE, BGWHITE);
  switch(activeWindow) 
  {
    case(DIR_WIN):
      if((strcmp(dirs[firstVisDir+selectedDir], ".") == 0)//ignore '.' and '..'
	 || (strcmp(dirs[firstVisDir+selectedDir], "..") == 0)) break;

      if(dirStar[firstVisDir+selectedDir] == '*') 
      {	//if selected, un-select
	dirStar[firstVisDir+selectedDir] = ' '; numStarred--;
      } 
      else 
      {						//otherwise, select it
	if(dirStar[firstVisDir+selectedDir] == '^') 
	{
	  numCut--;	//if marked for cut, remove cut
	  removeCutDir(firstVisDir+selectedDir);
	} 
	else if (dirStar[firstVisDir+selectedDir] == '#') 
	{
	  numCopy--;	//if marked for copy, remove copy
	  removeCopyDir(firstVisDir+selectedDir);
	} //end inner if
	dirStar[firstVisDir+selectedDir] = '*'; numStarred++;
      }//end outer if				//and then print it!!
      fprintf(stdout, "\e[%d;%dH", selectedDir+4, 3);
      fprintf(stdout, "%c", dirStar[firstVisDir+selectedDir]);
      setScreenColors(WHITE, BGBLUE);
      refreshBottomView();
      fprintf(stdout, "\e[3;3H");	//move cursor to point to window
      break;
    case(FILE_WIN):
      if(strcmp(files[firstVisFile+selectedFile], 
		"(Empty folder)") == 0) break;//this means folder is empty!!
      if(fileStar[firstVisFile+selectedFile] == '*') 
      {//if selected, unselect
	fileStar[firstVisFile+selectedFile] = ' '; numStarred--;
      } 
      else 
      {			//otherwise, select it
	if(fileStar[firstVisFile+selectedFile] == '^') 
	{
	  numCut--; //if marked for cut, remove cut
	  removeCutFile(firstVisFile+selectedFile);
	} 
	else if(fileStar[firstVisFile+selectedFile] == '#') 
	{
	  numCopy--; //if marked for cut, remove cut
	  removeCopyFile(firstVisFile+selectedFile);
	} //end inner if
	fileStar[firstVisFile+selectedFile] = '*'; numStarred++;
      }//end outer if				//and then print it!!
      fprintf(stdout, "\e[%d;%dH", selectedFile+4, (SCREEN_W/2)+1);
      fprintf(stdout, "%c", fileStar[firstVisFile+selectedFile]);
      setScreenColors(WHITE, BGBLUE);
      refreshBottomView();
      fprintf(stdout, "\e[3;%dH",(SCREEN_W/2)+2);//cursor to point to window
      break;
  }
}


void scanDir(char *dir) 
{
  int dcount, fcount;
  //int nf = 0;
  int n, j;
  struct dirent **eps;
  struct stat statbuf;

  n = scandir(dir, &eps, one, alphasort);
  chdir(dir);
  cwd = getcwd(NULL, 0);
  dcount = fcount = 0;
  
  if(n >= 0) 
  {
    int cnt;
    fprintf(log_file, "Scanning directory '%s'\n", dir);
    for(cnt = 0; cnt < n; ++cnt) 
    {
      lstat(eps[cnt]->d_name,&statbuf);
      if(S_ISDIR(statbuf.st_mode)) 
      {
	if(dcount >= MAXDIRS) break;
	dirs[dcount++] = eps[cnt]->d_name;
	if(strcmp(eps[cnt]->d_name, "..") == 0
	   || strcmp(eps[cnt]->d_name, ".") == 0) j = 0;
	else j = checkCutOrCopyDir(dcount-1);
	if(j == 1) dirStar[dcount-1] = '^';
	else if(j == 2) dirStar[dcount-1] = '#';
	else dirStar[dcount-1] = ' ';
      } 
      else 
      {
	if(fcount >= MAXFILES) break;
	files[fcount++] = eps[cnt]->d_name;
	if(strcmp(dir, "..") == 0) j = 0;
	else j = checkCutOrCopyFile(fcount-1);
	if(j == 1) fileStar[fcount-1] = '^';
	else if(j == 2) fileStar[fcount-1] = '#';
	else fileStar[fcount-1] = ' ';
      }
    }
  } 
  else 
  {
    fprintf(log_file, "Error opening dir: %s\n", dir);
    dcount = msgBox("Cannot open directory.\nProbably bad path specified or \
access denied.", OK, ERROR);
    setScreenColors(WHITE, BGBLUE);
    refreshFileView();
    refreshDirView();
    return;
  }

    totalFiles = fcount;
    if(totalFiles < numVisFiles) 
      files[totalFiles] = NULL;	//so the refreshFileView() will work properly
    firstVisFile = 0;
    selectedFile = 0;
    
    totalDirs = dcount;
    if(totalDirs < numVisDirs) 
      dirs[totalDirs] = NULL;	//so the refreshDirView() will work properly
    firstVisDir = 0;
    selectedDir = 0;
    
    numStarred = 0;
    refreshFileView();
    refreshDirView();
    refreshBottomView();
    fprintf(log_file, "Finished scanning directory '%s'..\n", dir);
}

static int one(const struct dirent *unused) 
{
  return 1;
}


/***************************************
 * refreshDirView(): 
 * Procedure to refresh the left window
 * showing directory tree.
 * **************************************/
void refreshDirView() 
{
 if(activeWindow == DIR_WIN) setScreenColors(GREEN, BGBLUE);
 //draw left sub-window
 drawBox(3, 2, SCREEN_H-5, (int)(SCREEN_W/2)-1, " Directory view ", YES);
 int i, j;
 if(totalDirs == 0) 
 {
   i = msgBox("No directory entries found!.", OK, ERROR);
   refreshFileView();
   refreshDirView();//this will make an infinite loop.. solution??
   return;
 }
 setScreenColors(GREEN, BGBLUE);
 for(i = 0; i < numVisDirs; i++) 
 {
   if(dirs[firstVisDir+i] == NULL) break; 
   if(i == selectedDir) 
   {
      setScreenColors(BLUE, BGWHITE);
      fprintf(stdout, "\x1b[%d;%dH%s", i+4, 3, dirHighLight);
      if(strlen(dirs[firstVisDir+i]) >= MAX_DIR_NAME_LEN) {
	fprintf(stdout, "\x1b[%d;%dH%c", i+4, 3, dirStar[firstVisDir+i]);
	for(j = 0; j < MAX_DIR_NAME_LEN-3; j++) 
	  fprintf(stdout, "%c", dirs[firstVisDir+i][j]);
	fprintf(stdout, "..");
      } 
      else 
      {
	fprintf(stdout, "\x1b[%d;%dH%c%s", i+4, 3, 
		dirStar[firstVisDir+i], dirs[firstVisDir+i]);
      }//end if
      setScreenColors(GREEN, BGBLUE);
    } 
    else 
    {
      if(strlen(dirs[firstVisDir+i]) >= MAX_DIR_NAME_LEN) 
      {
	fprintf(stdout, "\x1b[%d;%dH%c", i+4, 3, dirStar[firstVisDir+i]);
	for(j = 0; j < MAX_DIR_NAME_LEN-3; j++) 
	  fprintf(stdout, "%c", dirs[firstVisDir+i][j]);
	fprintf(stdout, "..");
      } 
      else 
      {
	fprintf(stdout, "\x1b[%d;%dH%c%s", i+4, 3, 
		dirStar[firstVisDir+i], dirs[firstVisDir+i]);
      }//end if
    }//end if
 }//end for
 setScreenColors(WHITE, BGBLUE);
 //redraw main window but don't clear the area
 drawBox(1, 1, SCREEN_H, SCREEN_W, " Prime  for GNU/Linux ", NO);
 
 //move cursor to point to window
 if(activeWindow == DIR_WIN) fprintf(stdout, "\e[3;3H");
 //move cursor to point to window
 if(activeWindow == FILE_WIN) fprintf(stdout, "\e[3;%dH",(SCREEN_W/2)+2);
}


/***************************************
 * refreshFileView(): 
 * Procedure to refresh the right window
 * showing file entries.
 * **************************************/
void refreshFileView() 
{
 if(activeWindow == FILE_WIN) setScreenColors(GREEN, BGBLUE);
 //draw right sub-window
 drawBox(3, (int)(SCREEN_W/2), SCREEN_H-5, SCREEN_W-1, " File view ", YES);
 int i, j;
 if(totalFiles == 0) 
 {
   files[0] = "(Empty folder)";
   files[1] = NULL;
   totalFiles = 1;
 }
 setScreenColors(GREEN, BGBLUE);
 for(i = 0; i < numVisFiles; i++) 
 {
    if(files[firstVisFile+i] == NULL) break; 
    if(i == selectedFile) 
    {
      setScreenColors(BLUE, BGWHITE);
      fprintf(stdout, "\x1b[%d;%dH%s", i+4, (SCREEN_W/2)+1, fileHighLight);
      if(strlen(files[firstVisFile+i]) >= MAX_FILE_NAME_LEN) {
	fprintf(stdout, "\x1b[%d;%dH%c", i+4, (SCREEN_W/2)+1, 
		fileStar[firstVisFile+i]);
	for(j = 0; j < MAX_FILE_NAME_LEN-3; j++) 
	  fprintf(stdout, "%c", files[firstVisFile+i][j]);
	fprintf(stdout, "..");
      } 
      else 
      {
	fprintf(stdout, "\x1b[%d;%dH%c%s", i+4, (SCREEN_W/2)+1, 
		      fileStar[firstVisFile+i], files[firstVisFile+i]);
      }//end if
      setScreenColors(GREEN, BGBLUE);
    } 
    else 
    {
	if(strlen(files[firstVisFile+i]) >= MAX_FILE_NAME_LEN) 
	{
	  fprintf(stdout, "\x1b[%d;%dH%c", i+4, (SCREEN_W/2)+1, 
		  fileStar[firstVisFile+i]);
	  for(j = 0; j < MAX_FILE_NAME_LEN-3; j++) 
	    fprintf(stdout, "%c", files[firstVisFile+i][j]);
	  fprintf(stdout, "..");
	} 
	else 
	{
          fprintf(stdout, "\x1b[%d;%dH%c%s", i+4, (SCREEN_W/2)+1, 
		      fileStar[firstVisFile+i], files[firstVisFile+i]);
	}//end if
    }//end if
 }//end for
 setScreenColors(WHITE, BGBLUE);
  
 if(activeWindow == DIR_WIN) 
   fprintf(stdout, "\e[3;3H");	//move cursor to point to window
 if(activeWindow == FILE_WIN) 
   fprintf(stdout, "\e[3;%dH",(SCREEN_W/2)+2);//move cursor to point to window
}

/***************************************
 * refreshBottomView(): 
 * Procedure to refresh the bottom window
 * showing CWD and statistics.
 * *************************************/
void refreshBottomView() 
{
  //draw bottom sub-window
  drawBox(SCREEN_H-4, 2, SCREEN_H-1, SCREEN_W-1, " Quick reference ", YES);
  fprintf(stdout, "\e[%d;%dH", SCREEN_H-2, 4);
  if(cwd != NULL) 
  {	//check the current working directory var is not NULL pointer
    if(strlen(cwd) > SCREEN_W-7) 
    {	//check if cwd length is more than display width
      int i;
      fprintf(stdout, "CWD: ");
      for(i = 0; i < SCREEN_W-12; i++) 
	putchar(cwd[i]);	//show just enought chars of the string
      fprintf(stdout, "..");			//and seal it with '..'
    } 
    else 
    { 				//the length is less than display width
      fprintf(stdout, "CWD: %s", cwd); 	//so spit it all out
    }
  }
  fprintf(stdout, "\e[%d;%dH", SCREEN_H-3, 4);
  if(numStarred > 0) fprintf(stdout, "Marked (%d) ", numStarred);
  if(numCut > 0) fprintf(stdout, "Cut (%d) ", numCut);
  if(numCopy > 0) fprintf(stdout, "Copy (%d) ", numCopy);
  //redraw main window but don't clear the area
  drawBox(1, 1, SCREEN_H, SCREEN_W, " Prime  for GNU/Linux ", NO);

  if(activeWindow == DIR_WIN) 
    fprintf(stdout, "\e[3;3H");	//move cursor to point to window
  if(activeWindow == FILE_WIN) 
    fprintf(stdout, "\e[3;%dH",(SCREEN_W/2)+2);//cursor to point to window
}

/***************************************
 * drawMenuBar(): 
 * Procedure to draw the main menu bar.
 * **************************************/
void drawMenuBar(int x, int y, int w) 
{
  setScreenColors(BLUE, BGWHITE);
  fprintf(stdout, "\x1b[%d;%dH", x, y);		//reposition the cursor
  int i,j, lastChar=y;
  for(i = 0; i < w; i++) fputc(' ', stdout);	//Draw empty menu bar
  fprintf(stdout, "\x1b[%d;%dH", x, y);		//reposition the cursor

  for(i = 0; i < totalMainMenus; i++) 
  {
    j=0; lastChar++;
    fprintf(stdout, " ");
    while(menu[i][j] != '\0') 
    {
      if(menu[i][j] == '&') 
      {	//turn on underline feature to print the shortcut key
	fprintf(stdout, "\x1b[4m%c\x1b[24m", menu[i][j+1]);//then turn it off
      }
      else
	fprintf(stdout, "%c", menu[i][j+1]);	//print normal chars (other than the
      lastChar++; j++;					//shortcut key)
    }
    fprintf(stdout, " ");
  }
  setScreenColors(WHITE, BGBLUE);
}

/***************************************
 * init(): 
 * Procedure containing code that init-
 * ializes various data structures.
 * **************************************/
void init() 
{
 getScreenSize();
  //1. Main Menu//
  menu[0] = "&File";
  menu[1] = "&Edit";
  menu[2] = "&Help";
  //2. File Menu//
  fileMenu[0] = "New directory ^N";
  fileMenu[1] = "Open location ^O";
  fileMenu[2] = "Export tree   ^E";
  fileMenu[3] = "Print         ^P";
  fileMenu[4] = "Exit          ^Q";
  //3. Edit Menu//
  editMenu[0] = "Cut        ^X";
  editMenu[1] = "Copy       ^C";
  editMenu[2] = "Paste      ^V";
  editMenu[3] = "Mark all   ^A";
  editMenu[4] = "Unmark all ^Z";
  editMenu[5] = "Clear sel. ^W";
  editMenu[6] = "Find..     ^F";
  //4. Help Menu//
  helpMenu[0] = "View README    ";
  helpMenu[1] = "Quick reference";
  helpMenu[2] = "About Prime..    ";

 int i;
  //set defaults for Dir view//
 numVisDirs = SCREEN_H-9;
 firstVisDir = 0;
 selectedDir = -1;
 totalDirs = 0;
 //reserve enough space in memory for highlight bar
 dirHighLight = malloc(SCREEN_W/2);
 memset(dirHighLight, ' ', (SCREEN_W/2)-4);	//fill the bar with spaces
 dirHighLight[(SCREEN_W/2)-4] = '\0';
  //set defaults for File view//
 numVisFiles = SCREEN_H-9;
 firstVisFile = 0;
 selectedFile = -1;
 totalFiles = 0;
 fileHighLight = malloc(SCREEN_W/2);
 memset(fileHighLight, ' ', (SCREEN_W/2)-2);
 fileHighLight[(SCREEN_W/2)-2] = '\0';
 //strcat(fileHighLight, "\0");
 
 activeWindow = DIR_WIN;
 MAX_DIR_NAME_LEN = (SCREEN_W/2)-4;
 MAX_FILE_NAME_LEN = (SCREEN_W/2)-2; 
 MAX_MSG_BOX_W = SCREEN_W - 4;
 MAX_MSG_BOX_H = SCREEN_H - 4;
 for(i = 0; i < MAXDIRS; i++) 
 {
   dirStar[i] = ' ';
   dirs[i] = (char *) malloc(MAX_DIR_NAME_LEN);
 }
 for(i = 0; i < MAXFILES; i++) 
 {
   fileStar[i] = ' ';
   files[i] = (char *) malloc(MAX_FILE_NAME_LEN);
 }
  
 numStarred = 0;
 numCut = 0;
 numCopy = 0;
 numCutFiles = 0;
 numCopyFiles = 0;
 numCutDirs = 0;
 numCopyDirs = 0;
 for(i = 0; i < MAX_CUT_COPY; i++) 
 {
   //cutFiles[i] = malloc(1);
   //copyFiles[i] = malloc(1);
   //cutDirs[i] = malloc(1);
   //copyDirs[i] = malloc(1);
   cutFiles[i] = malloc(MAX_FILE_NAME_LEN);
   copyFiles[i] = malloc(MAX_FILE_NAME_LEN);
   cutDirs[i] = malloc(MAX_DIR_NAME_LEN);
   copyDirs[i] = malloc(MAX_DIR_NAME_LEN);
 }

 //numPrinters = -1;
 //selectedPrinter = -1;
 //PRINTING = 0;

 startStr = (char *) malloc(MAX_DIR_NAME_LEN); 
 middleStr = (char *) malloc(MAX_DIR_NAME_LEN); 
 endStr = (char *) malloc(MAX_DIR_NAME_LEN); 

  FG_COLOR[COLOR_WINDOW] = 37;
  FG_COLOR[COLOR_HIGHLIGHT_TEXT] = 34;
  FG_COLOR[COLOR_MENU_BAR] = 34;
  FG_COLOR[COLOR_STATUS_BAR] = 34;
  FG_COLOR[COLOR_BUTTONS] = 37;
  FG_COLOR[COLOR_HBUTTONS] = 32;
  BG_COLOR[COLOR_WINDOW] = 44;
  BG_COLOR[COLOR_HIGHLIGHT_TEXT] = 47;
  BG_COLOR[COLOR_MENU_BAR] = 47;
  BG_COLOR[COLOR_STATUS_BAR] = 47;
  BG_COLOR[COLOR_BUTTONS] = 41;
  BG_COLOR[COLOR_HBUTTONS] = 41;

 initTerminal();
}


int read_config_file()
{
      GNU_DOS_LEVEL = 1;
      if(!(pass = getpwuid(geteuid()))) 
      {
	printf("Error: couldn't open home directory to read configuration file.\n");
	printf("Aborting.\n");
	exit(1);
      }
      config_file_name = (char *) malloc(strlen(pass->pw_dir)+12);
      strcpy(config_file_name, pass->pw_dir);
      strcat(config_file_name, "/");
      strcat(config_file_name, ".prime.conf");
      if(!(config_file = fopen(config_file_name, "r"))) 
      {
	printf("Error: couldn't read configuration file in home directory.\n");
	printf("Resetting configuration file.\n");
	//exit(1);
	write_config_file();
      }

      char buf[100];
      //read configuration file
      while(fgets(buf, sizeof(buf), config_file)) 
      {
	if(buf[0] == '#' || buf[0] == '\n') continue;
	else if (strstr(buf, "GNU_DOS_LEVEL")) 
	{
	  GNU_DOS_LEVEL = atoi((strchr(buf, '=')+2));
	}
      }//end while
      fclose(config_file);
      if(NEW_GNU_DOS_LEVEL)
	GNU_DOS_LEVEL = NEW_GNU_DOS_LEVEL;
      if(GNU_DOS_LEVEL > 5 || GNU_DOS_LEVEL < 1) GNU_DOS_LEVEL = 1;
      return 1;
}

int write_config_file()
{
      if(!(pass = getpwuid(geteuid()))) 
      {
	//printf("Error: couldn't open home directory to write configuration file.\n");
	//printf("Aborting.\n");
	//exit(1);
	return 0;
      }
      config_file_name = (char *) malloc(strlen(pass->pw_dir)+12);
      strcpy(config_file_name, pass->pw_dir);
      strcat(config_file_name, "/");
      strcat(config_file_name, ".prime.conf");
      if(!(config_file = fopen(config_file_name, "w"))) 
      {
	//printf("Error: couldn't write to configuration file in home directory.\n");
	//printf("Aborting.\n");
	//exit(1);
	return 0;
      }
      //printf("Resetting program configuration..\n");
      //write default values to the configuration file
      fprintf(config_file, "#Configuration file for the prime program\n");
      fprintf(config_file, "#Please do not modify this file by hand\n\n");
      fprintf(config_file, "#GnuDOS Level\n");
      fprintf(config_file, "GNU_DOS_LEVEL = %d\n", GNU_DOS_LEVEL);
      fclose(config_file);
      return 1;
}
