// 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 <fcntl.h>
#include <unistd.h>

#include <FL/fl_draw.H>
#include <FL/fl_show_colormap.H>
#include <FL/Fl_File_Chooser.H>

#include "mfmcfg_ui.hxx"

char *HOMEDIR = NULL;

/**************************************************************************
* Metodi di class_mfmcfg
****************************************************************************/

/**************************************************************************
* Costruttore
****************************************************************************/

class_mfmcfg::class_mfmcfg() : class_mfmcfg_fluid() {

// Set home dir

  asprintf(&HOMEDIR, "%s/", getenv("HOME"));

  load_config();

  mfmcfg_win->show();

} // class_mfmcfg


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

void class_mfmcfg::load_config() {

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

  size_t start = 0,
         dim =  0;

  int num;

  FILE *stream;

  Fl_Color color;

// Changed numerous defaults:
  mfmcfg_exec_button->labelcolor(FL_RED);
  mfmcfg_dir_button->labelcolor(FL_BLUE);
  mfmcfg_mount_button->labelcolor(FL_DARK_GREEN);
  mfmcfg_umount_button->labelcolor(FL_RED);

  mfmcfg_editor_input->value("editor");
  mfmcfg_terminal_input->value("aterm");
  mfmcfg_trash_input->value("/tmp/trashbin/");

  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)

        mfmcfg_exec_button->labelcolor(color);

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

        mfmcfg_dir_button->labelcolor(color);

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

        mfmcfg_mount_button->labelcolor(color);

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

        mfmcfg_umount_button->labelcolor(color);

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

        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;

          }

        mfmcfg_editor_input->value(stringa + start);

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

        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;

          }

        mfmcfg_terminal_input->value(stringa + start);

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

        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;

          }

        mfmcfg_trash_input->value(stringa + start);

      }

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

        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;

          }

        mfmcfg_burn_device_input->value(stringa + start);

      }

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

        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;

          }

        mfmcfg_burn_mount_input->value(stringa + start);

      }

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

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

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

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

            break;

          }

        for (size_t 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);

            stringa[start] = 0;

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

            break;

          }

        }

      asprintf(&ext_data, "@C%i@.%s : %s", color, ext_str, prog_str);

      mfmcfg_type_browser->add(ext_data);

      if (prog_str != NULL) free(prog_str);

      if (ext_str != NULL) free(ext_str);

      free(ext_data);

      }

      free(stringa);

      stringa = NULL;

      dim = (size_t) 0;

    }

    fclose(stream);

  }

  free(cfg_file);

} /* load_config */


/**************************************************************************
* Funzion: save_config
*
* Save configuration
****************************************************************************/

void class_mfmcfg::save_config() {

  char *stringa,
       *ext,
       *prog,
       *cfg_file,
       *fifo_str;  
            
  int fifo_fd;       

  Fl_Color color;

  FILE *stream;
  
  FILE *fifo;  
  
  asprintf(&cfg_file, "%s/.mfm/mfm.cfg", HOMEDIR);
  
  if ((stream = fopen (cfg_file,"w"))!=NULL) {

    fprintf(stream, "exec %i\n", mfmcfg_exec_button->labelcolor());
    fprintf(stream, "dir %i\n", mfmcfg_dir_button->labelcolor());
    fprintf(stream, "mounted %i\n", mfmcfg_mount_button->labelcolor());
    fprintf(stream, "unmounted %i\n", mfmcfg_umount_button->labelcolor());

    fprintf(stream, "editor %s\n", mfmcfg_editor_input->value());
    fprintf(stream, "terminal %s\n", mfmcfg_terminal_input->value());		
    fprintf(stream, "trashcan %s\n", mfmcfg_trash_input->value());
    
    fprintf(stream, "burner_dev %s\n", mfmcfg_burn_device_input->value());
    fprintf(stream, "burner_mount %s\n", mfmcfg_burn_mount_input->value());

    for (int row=1; row<=mfmcfg_type_browser->size(); row++) {

      asprintf(&stringa, "%s", mfmcfg_type_browser->text(row));

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

        if (stringa[i] == ':') {

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

          stringa[i-1] = 0;

          break;

        }

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

        if (stringa[i] == '@') {

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

          stringa[i] = 0;

          break;

        }
			
      int int_col;						
					
      sscanf(stringa+2, "%i", &int_col);
				
  		color = (Fl_Color) int_col;							

      fprintf(stream, "%s %i %s\n", ext, color, prog);

      free(stringa);
      free(ext);
      free(prog);

    }

    fclose(stream);
    
// Load new configuration in all opened windows    
       
    asprintf(&fifo_str, "%s/.mfm/mfm.fifo", HOMEDIR);  

    fifo_fd = open(fifo_str, O_WRONLY + O_NONBLOCK);

    if (fifo_fd > 0) {  
    
      fifo = fdopen(fifo_fd, "w");
      
      fprintf(fifo, "CONF \n");       
        
      fclose(fifo);
    
      close(fifo_fd);
    
    }     
    
  }
  
  free(cfg_file);

  printf("configuration saved to mfm.cfg ...\n");

} // save_config


/**************************************************************************
* Funzion: clear_type_input
*
* Clear values of selected file type
****************************************************************************/

void class_mfmcfg::clear_type_input() {

  mfmcfg_type_color_button->labelcolor(FL_BLACK);

  mfmcfg_type_color_button->redraw();

  mfmcfg_ext_input->value(NULL);

  mfmcfg_prog_input->value(NULL);

} //  clear_type_input


/**************************************************************************
* Callback dei widget dell'interfaccia
****************************************************************************/

void class_mfmcfg::mfmcfg_editor_button_callback() {

  char *name = NULL;
  int start = 0;

  name = fl_file_chooser("Select editor ...", "", HOMEDIR);

  if (name != NULL) {

    for (size_t i=0; i<strlen(name); i++)

      if (name[i] == '/')

        start = i;

    mfmcfg_editor_input->value(name+start+1);

  }

}


void class_mfmcfg::mfmcfg_terminal_button_callback() {

  char *name = NULL;
  int start = 0;

  name = fl_file_chooser("Select terminal ...", "", HOMEDIR);

  if (name != NULL) {

    for (size_t i=0; i<strlen(name); i++)

      if (name[i] == '/')

        start = i;

    mfmcfg_terminal_input->value(name+start+1);

  }

}


void class_mfmcfg::mfmcfg_trash_button_callback() {;

 char *name = NULL;

 name = fl_dir_chooser("Select trash bin ...", mfmcfg_trash_input->value());

  if (name != NULL) {

    mfmcfg_trash_input->value(name);

  }

}


void class_mfmcfg::mfmcfg_exec_button_callback() {

  fl_show_colormap(mfmcfg_exec_button->labelcolor());

  Fl_Color color = fl_color();

  if (color < 255)

    mfmcfg_exec_button->labelcolor(color);

}


void class_mfmcfg::mfmcfg_dir_button_callback() {

  fl_show_colormap(mfmcfg_dir_button->labelcolor());

  Fl_Color color = fl_color();

  if (color < 255)

    mfmcfg_dir_button->labelcolor(color);

}


void class_mfmcfg::mfmcfg_mount_button_callback() {

  fl_show_colormap(mfmcfg_mount_button->labelcolor());

  Fl_Color color = fl_color();

  if (color < 255)

    mfmcfg_mount_button->labelcolor(color);

}


void class_mfmcfg::mfmcfg_umount_button_callback() {

  fl_show_colormap(mfmcfg_umount_button->labelcolor());

  Fl_Color color = fl_color();

  if (color < 255)

    mfmcfg_umount_button->labelcolor(color);

}


void class_mfmcfg::mfmcfg_type_browser_callback() {

  char *stringa;

  int sel;

  Fl_Color color;

  sel = mfmcfg_type_browser->value();

  if (sel > 0) {

    asprintf(&stringa, "%s", mfmcfg_type_browser->text(sel));

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

      if (stringa[i] == ':') {

        mfmcfg_prog_input->value(stringa+i+2);

        stringa[i-1] = 0;

        break;

      }

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

      if (stringa[i] == '@') {

        mfmcfg_ext_input->value(stringa+i+2);

        stringa[i] = 0;

        break;

      }
		
    int int_col;						
		
    sscanf(stringa+2, "%i", &int_col);
				
		color = (Fl_Color) int_col;				

    mfmcfg_type_color_button->labelcolor(color);

    mfmcfg_type_color_button->redraw();

  }

  else

    clear_type_input();

}


void class_mfmcfg::mfmcfg_type_color_button_callback() {

  fl_show_colormap(mfmcfg_type_color_button->labelcolor());

  Fl_Color color = fl_color();

  if (color < 255)

    mfmcfg_type_color_button->labelcolor(color);

}


void class_mfmcfg::mfmcfg_type_add_button_callback() {

  char *ext_data;

  asprintf(&ext_data, "@C%i@. : ", FL_BLACK);

  mfmcfg_type_browser->add(ext_data);

  mfmcfg_type_browser->value(mfmcfg_type_browser->size());

  free(ext_data);

}


void class_mfmcfg::mfmcfg_type_del_button_callback() {

  mfmcfg_type_browser->remove(mfmcfg_type_browser->value());

  clear_type_input();

}


void class_mfmcfg::mfmcfg_type_modify_button_callback() {

  char *ext_data,
       *ext_str,
       *ext_input;

  int sel,
// Compile warning start set but not used:
// Query compiler wrong, problems saving config
      start = 0,
      lun = 0,
      pos = 0;

  asprintf(&ext_input, "%s", mfmcfg_ext_input->value());
	
	if (strlen(ext_input) > 0) {

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

    	if (ext_input[i] != ' ') {

      	ext_input[i+1] = 0;

      	break;

    	}

  	for (size_t i=0; i<strlen(ext_input); i++)

    	if (ext_input[i] != ' ') {

// Compile warning start set but not used:
        start = i;

      	break;

    	}

  	if (ext_input[0] != '.') lun++;

  	for (size_t i=1; i<strlen(ext_input); i++) {

    	if (ext_input[i-1] != ' ' || ext_input[i] != ' ') lun++;

    	if (ext_input[i-1] == ' ' && ext_input[i] != ' ' && ext_input[i] != '.') lun++;

  	}

  	ext_str = (char*) malloc(lun + 10);

  	if (ext_input[0] != '.') {

    	ext_str[pos] = '.';

    	pos++;

  	}

  	for (size_t i=0; i<strlen(ext_input); i++) {

    	if (ext_input[i] != ' ' || ext_input[i+1] != ' ') {

      	ext_str[pos] = ext_input[i];

      	pos++;

    	}

    	if (ext_input[i] == ' ' && ext_input[i+1] != ' ' && ext_input[i+1] != '.') {

      	ext_str[pos] = '.';

      	pos++;

    	}

  	}

  	ext_str[pos] = 0;

  	mfmcfg_ext_input->value(ext_str);

  	asprintf(&ext_data, "@C%i@.%s : %s", mfmcfg_type_color_button->labelcolor(),
                                      	 ext_str,
                                      	 mfmcfg_prog_input->value());

  	sel = mfmcfg_type_browser->value();

  	mfmcfg_type_browser->text(sel, ext_data);

    free(ext_data);
    free(ext_str);

  }

  free(ext_input);
	
}


void class_mfmcfg::mfmcfg_burn_device_button_callback() {

  char *name = NULL;
  int start = 0;

  name = fl_file_chooser("Select burner device ...", "", "/dev/");

  if (name != NULL) {

    for (size_t i=0; i<strlen(name); i++)

      if (name[i] == '/')

        start = i;

    mfmcfg_burn_device_input->value(name+start+1);

  }

}


void class_mfmcfg::mfmcfg_burn_mount_button_callback() {

  char *name = NULL;
  int start = 0;

  name = fl_dir_chooser("Select burner mount point ...", "/");

  if (name != NULL) {

    for (size_t i=0; i<strlen(name); i++)

      if (name[i] == '/')

        start = i;

    mfmcfg_burn_mount_input->value(name+start+1);

  }

}


void class_mfmcfg::mfmcfg_save_callback() {

  save_config();

}


void class_mfmcfg::mfmcfg_exit_callback() {

  delete this->mfmcfg_win;

}


void class_mfmcfg::mfmcfg_help_callback() {

  system("mfmhelp /usr/local/share/doc/mfm.html#menu_conf &");

}
