// 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 <math.h>
#include <locale.h>
#include <string>

#include "mfmrename_ui.hxx"

using namespace std;

/**************************************************************************
* Metodi di class_mfmrename
****************************************************************************/

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

class_mfmrename::class_mfmrename(int argc, char **argv) : class_mfmrename_fluid() {

  int i;  
  
  i = mfmrename_table_group->w()/2 - 8;
  
  mfmrename_table->create_header(2, false);
  
  mfmrename_table->create_table(argc - 1, true);
  
	mfmrename_table->header_label(0, "Old name");
	mfmrename_table->header_label(1, "New name");
	
	mfmrename_table->row_select_mode(SELECT_MODE_OFF);

  mfmrename_table->col_width(0, i);
  mfmrename_table->col_width(1, i);
  
  for (i = 1; i < argc; i++) {
    
    mfmrename_table->cell_label(0, i-1, argv[i]);
    mfmrename_table->cell_label(1, i-1, argv[i]);
	    
  }

  mfmrename_template->value("$F");
  
  mfmrename->show();
  
} // class_mfmrename::class_mfmrename


/**************************************************************************
* Return code parameters
****************************************************************************/

int class_mfmrename::get_param(char *string, char **param1, char **param2) {

  int ret = 0;
  int j = 1;
  
  *param1 = NULL;
  *param2 = NULL;

  if (string[0] == '(') {

    while (string[j] != ')' && string[j] != ',' && string[j] != 0)

      j++;

    if (string[j] == ')' || string[j] == ',') {
                    
      *param1 = (char*) malloc(j);
      
      strncpy(*param1, string+1, j-1);
      
      (*param1)[j-1] = 0;

      ret = ++j;                     						 					
						
    	if (string[j-1] == ',') {              

      	while (string[j] != ')' && string[j] != 0)

        	j++;

      	if (string[j] == ')') {

        	*param2 = (char*) malloc(j-ret+1);

        	strncpy(*param2, string+ret, j-ret);

        	(*param2)[j-ret] = 0;        

        	ret = ++j;

      	}           

    	}   
			
    }       
		
  }  

  return ret;

} // class_mfmrename::get_param


/**************************************************************************
* Rinomina i nomi dei file nel browser
****************************************************************************/

void class_mfmrename::rename_files(class_table *mfmrename_table, Fl_Input *rename_template) {

  int i;
  
  size_t j, k, template_count;

  char *name = NULL;
  char *ext = NULL;
  char *str_counter = NULL;
  char *new_name = NULL;
  char *str_template = NULL;
  char *param1 = NULL;
  char *param2 = NULL;
  
  char *name_ptr = NULL;

  char fmt_counter[10], flag;

  bool flag_counter = true;
  int width_counter = 0;
  int counter = 1;
  int counter_inc = 1;  
  int name_start;
  int name_len;
  int chr_count = 0;

  int str_len;
  
  string name_str;

  asprintf(&str_template, rename_template->value());

  for (i = 0; i < mfmrename_table->get_rows(); i++) {
  
    name_str = "";

    asprintf(&name, "%s", mfmrename_table->cell_label(0, i));
    
    int dot_pos = 0;

    for (j = 1; j < strlen(name); j++)

      if (name[j] == '.') 
      
        dot_pos = j;
     
    if (dot_pos > 0) {
          
      asprintf(&ext, "%s", name+dot_pos+1);

      name[dot_pos] = (char) 0;
      
    } 

    else {

      ext = (char *) malloc(1);

      ext[0] = 0;

    }

    for (template_count = 0; template_count < strlen(str_template); template_count++) {

      if (str_template[template_count] != '$') 
      
        name_str = name_str + str_template[template_count];
        
      else {

        template_count++;

        flag = str_template[template_count];

        switch (flag) {

          case 'F':

            name_ptr = mfmrename_table->cell_label(0, i);         

          case 'N':
          
            if (flag == 'N')

              name_ptr = name;
          
            str_len = strlen(name_ptr);
          
            template_count += get_param(str_template+template_count+1, &param1, &param2);

            if (param2 == NULL) {
            
              name_start = 0;
               
              if (param1 == NULL) {
            
                name_len = 0;
                
              } 
              
              else {

                if (sscanf(param1, "%i", &name_len) != 1)
                
                  name_len = 0;                

                free(param1);                

              }               
                
            }                              
            
            else {
            
              if (sscanf(param1, "%i", &name_start) != 1)
              
                name_start = 0;
              
              if (sscanf(param2, "%i", &name_len) != 1 )
              
                name_len = 0;

              free(param1);                

              free(param2);                

            }                        
                       
            if (name_len == 0) 
            
              name_len = str_len;
              
            if (abs(name_start) < str_len) {
            
              char *string;

              if (name_len > 0 && name_start >= 0)

                asprintf(&string, "%s", name_ptr+name_start);

              else if (name_len > 0 && name_start < 0) 

                asprintf(&string, "%s", name_ptr+str_len+name_start);

              else if (name_len < 0 && name_start == 0) 

                asprintf(&string, "%s", name_ptr+str_len+name_len);
                
              else if (name_len < 0 && name_start < 0)

                asprintf(&string, "%s", name_ptr+str_len+name_start+name_len);                

              else if (name_len < 0 && name_start > 0) {
              
                if (name_start < -name_len)
                
                  name_len = -name_start;

                asprintf(&string, "%s", name_ptr+name_start+name_len);
                
              }               

              if (abs(name_len) < (int) strlen(string))  

                string[abs(name_len)] = 0;                

              name_str = name_str + string;                            

              free(string);            
            
            }                 
              
            break;
            
          case 'E':

            name_str = name_str + ext;     

            break;

          case 'C':
          
            if (flag_counter) {
            
              chr_count = get_param(str_template+template_count+1, &param1, &param2);            
              
              if (param1 != NULL) { 
              
                sscanf(param1, "%i", &counter);
                
                free(param1);

              }
              
              if (param2 != NULL) { 
              
                sscanf(param2, "%i", &counter_inc);
                
                free(param2);

              }
                           
              if (counter < 0) counter = -counter;
              if (counter_inc < 0) counter_inc = -counter_inc;              
              
              width_counter = ((int) log10(counter + mfmrename_table->get_rows()*counter_inc)) + 1;
                           
              flag_counter = false;
       
            }                
            
            template_count += chr_count;
            
            sprintf(fmt_counter, "%%%ii", width_counter);

            asprintf(&str_counter, fmt_counter, counter);

            for (k = 0; k < width_counter - (size_t) log10(counter) - 1; k++)

              str_counter[k] = '0';

            str_counter[width_counter] = (char) 0;

            name_str = name_str + str_counter;     
              
            free(str_counter);

            counter += counter_inc;

            break;
            
          case 'I':
          
            template_count += get_param(str_template+template_count+1, &param1, &param2);

            if (param1 != NULL && param2 != NULL) {
            
              sscanf(param1, "%i", &name_start); 
              
              if (name_start < 0)
              
                name_start = name_str.length() + name_start;                             
                
              if (name_start >= 0 && name_start <= (int) name_str.length())           
              
                name_str.insert(name_start, param2);
        
            }        
            
            if (param1 != NULL) free(param1);
            
            if (param2 != NULL) free(param2);
          
            break;
                      
          case 'O':
          
            template_count += get_param(str_template+template_count+1, &param1, &param2);

            if (param1 != NULL && param2 != NULL) {
            
              sscanf(param1, "%i", &name_start);                            
              
              if (name_start < 0)
              
                name_start = name_str.length() + name_start;                                           
                
              if (name_start >= 0 && name_start <= (int) name_str.length())           
              
                name_str.replace(name_start, strlen(param2), param2);
        
            }        
            
            if (param1 != NULL) free(param1);
            
            if (param2 != NULL) free(param2);
                    
            break;
            
          case 'D':
          
            template_count += get_param(str_template+template_count+1, &param1, &param2);

            if (param1 != NULL) {
            
              sscanf(param1, "%i", &name_start);     
              
              free(param1);
              
              if (param2 != NULL) {
              
                sscanf(param2, "%i", &name_len);
                
                free(param2);
                
              }  
              
              else
              
                name_len = 1;
                
              if (name_len == 0)
              
                name_len = name_str.length();

              if (name_start < 0)
              
                name_start = name_str.length() + name_start;                             
                
              if (name_start >= 0 && name_start <= (int) name_str.length())
              
                name_str.replace(name_start, name_len, "");
        
            }        
                      
            break;            
            
          case 'R':
          
            template_count += get_param(str_template+template_count+1, &param1, &param2);

            if (param1 != NULL) {
            
              int len1 = strlen(param1);
                        
              name_start = 0;
                            
              if (param2 == NULL) {

                param2 = (char *) malloc(1);

                param2[0] = 0;

              }
                
              int len2 = strlen(param2);  
                      
              while (name_start != (int) name_str.npos) {
              
                name_start = name_str.find(param1, name_start);
                
                if (name_start != (int) name_str.npos) {
                
                  name_str.replace(name_start, len1, param2);
                  
                  name_start += len2+1;
            
                } 
  
              }  
        
              free(param1);
            
              free(param2);
              
            }  
          
            break;

          case '$':

            name_str = name_str + "$";  

            break;

        }

      }

    }

    new_name = (char*) malloc(name_str.length()+1);

    name_str.copy(new_name, name_str.length());

    new_name[name_str.length()] = 0;

    mfmrename_table->cell_label(1, i, new_name);

    free(name);

    free(ext);

    free(new_name);

  }
  
  free(str_template);

} // class_mfmrename::rename_files


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

void class_mfmrename::mfmrename_menu_fullname_callback() {

  mfmrename_template->insert("$F(0,0)");

}


void class_mfmrename::mfmrename_menu_name_callback() {

  mfmrename_template->insert("$N(0,0)");

}


void class_mfmrename::mfmrename_menu_ext_callback() {

  mfmrename_template->insert("$E");

}


void class_mfmrename::mfmrename_menu_counter_callback() {

  mfmrename_template->insert("$C(1)");

}


void class_mfmrename::mfmrename_menu_insert_callback() {

  mfmrename_template->insert("$I(,)");

}


void class_mfmrename::mfmrename_menu_overwrite_callback() {

  mfmrename_template->insert("$O(,)");

}


void class_mfmrename::mfmrename_menu_delete_callback() {

  mfmrename_template->insert("$D(,)");

}


void class_mfmrename::mfmrename_menu_replace_callback() {

  mfmrename_template->insert("$R(,)");

}


void class_mfmrename::mfmrename_menu_rename_callback() {

  char *command;
  char tempdir[13] = "mfmrenXXXXXX";
  
// create a temporary directory

  mkdtemp(tempdir);
  
  for (int i = 0; i < mfmrename_table->get_rows(); i++) {
                                        
    asprintf(&command, "mv  '%s' '%s/%s'", mfmrename_table->cell_label(0, i),
                       tempdir, mfmrename_table->cell_label(1, i));


    mfmrename_table->cell_label(0, i, mfmrename_table->cell_label(1, i));

    system(command);

    free(command);

  }
  
  asprintf(&command, "mv -b %s/* .", tempdir);

  system(command);

  free(command);
  
  rmdir(tempdir);  
  
}


void class_mfmrename::mfmrename_menu_reset_callback() {

  mfmrename_template->value("$F");
  
  for (int i = 0; i < mfmrename_table->get_rows(); i++)
  
    mfmrename_table->cell_label(1, i, mfmrename_table->cell_label(0, i));

}


void class_mfmrename::mfmrename_menu_exit_callback() {

    delete mfmrename;
    delete this;

}


void class_mfmrename::mfmrename_menu_help_callback() {

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

}


void class_mfmrename::mfmrename_template_callback() {
               
  rename_files(mfmrename_table, mfmrename_template);

}
