// My File Manager (MFM).
//
// Copyright 2005-2006 by Stefano Gatti.
//
// This program 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 2
// of the License, or (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
//=====================================================================

#include <locale.h>
#include <stdio.h>

#include "mfm_util.hxx"
#include "mfm_main_ui.hxx"
#include "mfm_main_scattered_ui.hxx"
#include "mfm_get_path_ui.hxx"

#define MAX_STIME 20


char *HOMEDIR = NULL;
char *LAUNCHDIR = NULL;
char *TRASHCANDIR = NULL;
char *EDITOR = NULL;
char *TERMINAL = NULL;

FILE *fifo;

int timeout_temp_reload;

struct_ext_data *ext_list = NULL;

int ext_num, prog_num;

Fl_Color exec_color, dir_color;

void *xmalloc (size_t size) {

  register void *value = malloc (size);

  if (value == 0) {

    printf("virtual memory exhausted");

    exit(0);

  }

  return value;

} // xmalloc


void *xrealloc (void *ptr, size_t size) {

  register void *value = realloc (ptr, size);

  if (value == 0) {

    printf("virtual memory exhausted");

    exit(0);

  }

  return value;

} //xrealloc

void  xfree (char **p) {

  if (*p != NULL) {

    free(*p);

    *p = NULL;

  }

  else

    printf("Null pointer\n");

} // xfree


/**************************************************************************
* Funzion: load_config
*
* Load configuration
****************************************************************************/

void load_config() {

  char *cfg_file,
       *prog_str,
       *ext_str,
       *stringa = NULL,
       command[21];

  int num; 

  size_t dim, 
         start = 0;

  Fl_Color color = FL_BLACK;

  FILE *stream;

  struct_ext_data *ext_data,
                  *ext_ptr;

// Changed default exec color:
//  exec_color = FL_BLACK;
  exec_color = FL_RED;

// Changed default directory color:
//dir_color = FL_BLACK;
  dir_color = FL_BLUE;


// Default editor changed to editor:
//asprintf(&EDITOR, "vi");
  asprintf(&EDITOR, "editor");

// Default terminal changed to aterm:
//      asprintf(&TERMINAL, "xterm");
        asprintf(&TERMINAL, "aterm");

// Create trash directory and set as default:
  system("mkdir -p /tmp/trashbin/");

  asprintf(&TRASHCANDIR, "%s", "/tmp/trashbin/");
		
  ext_num = 0;
  prog_num = 0;	

// free file-type list	
	
  ext_ptr = ext_list;
	
	ext_list = NULL;	
	
  while (ext_ptr != NULL) {

    ext_data = ext_ptr->next;
			
		free(ext_ptr);
					
		ext_ptr = ext_data;
			
	}
		
  asprintf(&cfg_file, "%s/.mfm/mfm.cfg", HOMEDIR);
  
  if ((stream = fopen (cfg_file,"r"))!=NULL) {
	
	  int int_col;

    while (getline(&stringa, &dim, stream)>0) {		

      num = sscanf(stringa, "%20s %i", command,  &int_col);
			
			color = (Fl_Color) int_col;

      if (strcmp(command, "exec") == 0)

        exec_color = color;

      else if (strcmp(command, "dir") == 0)

        dir_color = color;

      else if (strcmp(command, "editor") == 0) {

        xfree(&EDITOR);

        for (start=strlen(command) + 1; start<strlen(stringa); start++)

          if (stringa[start] != ' ') break;

        for (size_t i=start+1; i<=strlen(stringa); i++)

          if (stringa[i] <= (char) 32) {

            stringa[i] = (char) 0;

            break;

          }

        asprintf(&EDITOR, "%s", stringa + start);

      }
			
      else if (strcmp(command, "terminal") == 0) {

        xfree(&TERMINAL);

        for (start=strlen(command) + 1; start<strlen(stringa); start++)

          if (stringa[start] != ' ') break;

        for (size_t i=start+1; i<=strlen(stringa); i++)

          if (stringa[i] <= (char) 32) {

            stringa[i] = (char) 0;

            break;

          }

        asprintf(&TERMINAL, "%s", stringa + start);

      }
			

      else if (strcmp(command, "trashcan") == 0) {

        xfree(&TRASHCANDIR);

        for (start=strlen(command) + 1; start<strlen(stringa); start++)

          if (stringa[start] != ' ') break;

        for (size_t i=start+1; i<=strlen(stringa); i++)

          if (stringa[i] <= (char) 32) {

            stringa[i] = (char) 0;

            break;

          }

        asprintf(&TRASHCANDIR, "%s", stringa + strlen(command) + 1);
				
				if (TRASHCANDIR[strlen(TRASHCANDIR)-1] != '/') {

// Compile warning, query below not needed commenting out:
//				  realloc(TRASHCANDIR, strlen(TRASHCANDIR)+2);
					
					TRASHCANDIR[strlen(TRASHCANDIR)-1] = '/';
					
        }					
							

      }

      else if (command[0] == '.' && num > 0) {

        for (int i=strlen(stringa)-1; i>=0; i--)

          if (stringa[i] > (char) 32) {

            stringa[i+1] = (char) 0;

            break;

          }

        for (int i=strlen(stringa)-1; i>0; i--)

          if (stringa[i] == (char) '.' && stringa[i-1] == (char) ' ')

            break;

          else if (stringa[i] == (char) ' ')

            start = i;
						
  	    int int_col;						

        sscanf(stringa+start, "%i", &int_col);
				
  			color = (Fl_Color) int_col;												

        prog_str = NULL;

        for (size_t i=start,flag=0; i<strlen(stringa); i++) {

          switch (flag) {

            case 0:

              if (stringa[i] == (char) ' ') flag=1;

              break;

            case 1:

              if (stringa[i] != (char) ' ') flag=2;

              break;

            case 2:

              if (stringa[i] == (char) ' ') flag=3;

              break;

            case 3:

              if (stringa[i] != (char) ' ') flag=4;

              break;

          }

          if (flag == 4) {

            asprintf(&prog_str, "%s", stringa+i);

            break;

          }

        }

        stringa[start] = (char) 0;

        for (int i=strlen(stringa)-1,flag=0; i>=0; i--)

          switch (flag) {

            case 0:

              if (stringa[i] != (char) ' ') {

                stringa[i+1] = (char) 0;

                flag=1;

              }

              break;

            case 1:

              if (stringa[i] == (char) '.') {

                asprintf(&ext_str, "%s", stringa+i);

                ext_data = new struct_ext_data;

                ext_data->ext = ext_str;
                ext_data->prog = prog_str;
                ext_data->color = color;
                ext_data->next = NULL;

                if (ext_list == NULL)

                  ext_list = ext_data;

                else {

                  ext_ptr = ext_list;

                  while (ext_ptr->next != NULL)

                    ext_ptr = ext_ptr->next;

                  ext_ptr->next = ext_data;

                }

                flag=0;

              }

              break;

          }

      }

    }

    fclose(stream);

    xfree(&stringa);

  }
  
  free(cfg_file);

} /* load_config */



void init() {

/**************************************************************************
* Funzion: init
*
* Init procedures
*
****************************************************************************/


// reworked LAUNCHDIR to open to TCE
//char *dir_ptr;

// Set locales

  setlocale(LC_ALL, "");

// Set launch dir

//  dir_ptr = getcwd(NULL, 0);

//  asprintf(&LAUNCHDIR, "%s", dir_ptr);
  asprintf(&LAUNCHDIR, "%s", "/etc/sysconfig/tcedir/");

//  xfree(&dir_ptr);

// Set home dir

  asprintf(&HOMEDIR, "%s", getenv("HOME"));
	
// Verify if config dir exist

  if (system("ls ~/.mfm > /dev/null") != 0)

    system("mkdir ~/.mfm");

} /* init */


/**************************************************************************
*
* Function: idle_function
*
* function to call every TIMEOUT_RELOAD seconds during idle
*  - refresh all directories
*
****************************************************************************/

void idle_function (void *) {

  static char *stringa = NULL;
  
  static size_t size = 0;
  
  refresh_dir(NULL, false);

  while (getline(&stringa, &size, fifo)>0) { 

    stringa[strlen(stringa)-1] = 0;
  
    if (strncmp(stringa, "OPEN ", 5) == 0)
  
      new class_mfm_window(stringa+5);       
      
    else if (strncmp(stringa, "OPENS ", 6) == 0) {   

      int argc;
      
      char **argv;
    
      sscanf(stringa+6, "%i", &argc);
      
      argv = (char **) malloc(sizeof(char *)*(argc+1));

      for (int i = 0; i < argc; i++) {
                
        getline(&stringa, &size, fifo);
        
        stringa[strlen(stringa)-1] = 0;
        
        asprintf(&argv[i], "%s", stringa);        
        
      } 

      new class_mfm_window_scattered(argc, argv);      
      
      for (int i = 0; i < argc; i++) 
                
        free(argv[i]);
        
      free(argv);
      
    }  
    
    else if (strncmp(stringa, "CONF ", 5) == 0) {     
    
      load_config();

      for (int i = 0; i< mfm_window_index.num_window_index; i++) 
 
        mfm_window_index.ptr_window_index[i]->load_dir(false);

    } 
       
  }    

  Fl::repeat_timeout(timeout_temp_reload, idle_function);

  if (timeout_temp_reload < TIMEOUT_RELOAD)
  
    timeout_temp_reload++;  

}


/**************************************************************************
*
* Function: start_timeout()
*
* Install timeout function
*
****************************************************************************/

void start_timeout() {

  timeout_temp_reload = 1;                            
  
  Fl::remove_timeout(idle_function);    
 
  Fl::add_timeout(timeout_temp_reload, idle_function);
  
}	// start_timeout
  

/**************************************************************************
*
* Function: convert_names
*
* Convert table's string in real filenames
*
* Optionally add \ character before each space and others special characters 
*
****************************************************************************/

char* convert_names (char *string, bool slash_flag) {

  int lun, count;
	
	char* mod_string;
	
  lun = strlen(string);	
  
  for (int j=0; j<lun-3; j++)
					
    if (string[j] == ' ' && string[j+1] == '-' && string[j+2] == '>'  && string[j+3] == ' ') {
						
      lun = j;		
					
	    break;
					
    } 
  	
  count = lun;
				
  for (int j=0; j<lun; j++) {
			
    if ((string[j] < 42 || string[j] == 96)  && slash_flag)
				
	    count++;
      
    else if (j > 0 && string[j] == '@' && string[j-1] == '@')
    
      count--; 
      
  }						
  
	mod_string = (char *) xmalloc(count+1);
			
	mod_string[count--] = 0;

	for (int j=lun-1; j>=0; j--) {

    mod_string[count--] = string[j];
				
    if ((string[j] < 42 || string[j] == 96) && slash_flag)
				
      mod_string[count--] = '\\' ;
      
    else if (j > 0 && string[j] == '@' && string[j-1] == '@')
    
      j--;
					
  }	

	return mod_string;

}
