// 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 <string.h>
#include <FL/fl_draw.H>
#include <time.h>
#include <locale.h>

#include "file_info.hxx"
#include "mfm_util.hxx"
#include "mfm_attrib_ui.hxx"
#include "mfm_main_ui.hxx"

#define MAX_STIME 20

/**************************************************************************
* Metodi di class_mfm_attrib
****************************************************************************/

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

class_mfm_attrib::class_mfm_attrib(void *mfm_window) : class_mfm_attrib_fluid() {

  char sdate[MAX_STIME],
       stime[MAX_STIME],
       *line = NULL,
       *user,
       *group;

  size_t dim_line = 0;
  
  bool first = true;
  
  struct tm *ltime = NULL;
  
  int nr;

  time_t time;

  class_mfm_window *ptr_window;
  
  file_info file_stat;
  
  FILE *stream;

  ptr_mfm_window = mfm_window;

  ptr_window = (class_mfm_window *) ptr_mfm_window;

// Ricerca degli utenti in /etc/passwd

  if ((stream = popen ("sort < /etc/passwd","r"))!=NULL) {

    while (getline(&line, &dim_line, stream)>0) {

      for (size_t i=0; i<dim_line; i++)
      
        if (line[i] == ':') {

          line[i] = (char) 0;
          
          break;
          
        }

      mfm_attrib_user_choice->add(line);

    }
    
    pclose(stream);
    
  }
  
// Ricerca dei gruppo in /etc/group

  if ((stream = popen ("sort < /etc/group","r"))!=NULL) {

    while (getline(&line, &dim_line, stream)>0) {

      for (size_t i=0; i<dim_line; i++)

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

          line[i] = (char) 0;

          break;

        }

      mfm_attrib_group_choice->add(line);

    }

    pclose(stream);

  }
  
  for (int i=0; i< ptr_window->mfm_window_table->get_rows(); i++)
  
    if (ptr_window->mfm_window_table->table[i].selected) {
    
      char *name = convert_names(ptr_window->mfm_window_table->cell_label(ptr_window->col_name, i), false);
  
      file_stat.set_file(ptr_window->path, name);
      
      free(name);
      
// get user and group

      asprintf(&user, "%s", file_stat.get_user());
      asprintf(&group, "%s", file_stat.get_group());

// get date status

      time = file_stat.get_time();

      ltime = localtime(&time);
      
      if (ptr_window->localized_date)

        strftime(sdate, MAX_STIME, "%x", ltime);
            
      else
      
        strftime(sdate, MAX_STIME, "%F", ltime);          
      
      strftime(stime, MAX_STIME, "%X", ltime);
      
// set values according first file

      if (first) {
	  
        if ((S_IRUSR & file_stat.stat_buffer.st_mode) != 0) mfm_attrib_owner_read_button->set();
        if ((S_IWUSR & file_stat.stat_buffer.st_mode) != 0) mfm_attrib_owner_write_button->set();
        if ((S_IXUSR & file_stat.stat_buffer.st_mode) != 0) mfm_attrib_owner_execute_button->set();
        if ((S_IRGRP & file_stat.stat_buffer.st_mode) != 0) mfm_attrib_group_read_button->set();
        if ((S_IWGRP & file_stat.stat_buffer.st_mode) != 0) mfm_attrib_group_write_button->set();
        if ((S_IXGRP & file_stat.stat_buffer.st_mode) != 0) mfm_attrib_group_execute_button->set();
        if ((S_IROTH & file_stat.stat_buffer.st_mode) != 0) mfm_attrib_others_read_button->set();
        if ((S_IWOTH & file_stat.stat_buffer.st_mode) != 0) mfm_attrib_others_write_button->set();
        if ((S_IXOTH & file_stat.stat_buffer.st_mode) != 0) mfm_attrib_others_execute_button->set();
        if ((S_ISUID & file_stat.stat_buffer.st_mode) != 0) mfm_attrib_uid_button->set();
        if ((S_ISGID & file_stat.stat_buffer.st_mode) != 0) mfm_attrib_gid_button->set();
        if ((S_ISVTX & file_stat.stat_buffer.st_mode) != 0) mfm_attrib_sticky_button->set();		 		 				

// user

        nr = mfm_attrib_user_choice->size();
       
        for (int i=0; i<nr; i++){
        
          if (mfm_attrib_user_choice->text(i) != NULL && strcmp(user, mfm_attrib_user_choice->text(i)) == 0) {
          
            mfm_attrib_user_choice->value(i);
            
            break;
            
          }
 }
// group

        nr = mfm_attrib_group_choice->size();

        for (int i=0; i<nr; i++)

          if (mfm_attrib_group_choice->text(i) != NULL && strcmp(group, mfm_attrib_group_choice->text(i)) == 0) {

            mfm_attrib_group_choice->value(i);

            break;

          }
   
// date

        mfm_attrib_date->value(sdate);
        mfm_attrib_time->value(stime);
        
        first = false;
        
      }
      
// check values according next files

      else {
      
// permissions

        if (((S_IRUSR & file_stat.stat_buffer.st_mode) != 0) != (mfm_attrib_owner_read_button->value() == 1)) {

          mfm_attrib_owner_read_button->set();

          mfm_attrib_owner_read_button->selection_color(FL_GRAY);
          
        }
          
        if (((S_IWUSR & file_stat.stat_buffer.st_mode) != 0) != (mfm_attrib_owner_write_button->value() == 1)) {

          mfm_attrib_owner_write_button->set();

          mfm_attrib_owner_write_button->selection_color(FL_GRAY);

        }
        
        if (((S_IXUSR & file_stat.stat_buffer.st_mode) != 0) != (mfm_attrib_owner_execute_button->value() == 1)) {

          mfm_attrib_owner_execute_button->set();

          mfm_attrib_owner_execute_button->selection_color(FL_GRAY);

        }
        
        if (((S_IRGRP & file_stat.stat_buffer.st_mode) != 0) != (mfm_attrib_group_read_button->value() == 1)) {

          mfm_attrib_group_read_button->set();

          mfm_attrib_group_read_button->selection_color(FL_GRAY);

        }

        if (((S_IWGRP & file_stat.stat_buffer.st_mode) != 0) != (mfm_attrib_group_write_button->value() == 1)) {

          mfm_attrib_group_write_button->set();

          mfm_attrib_group_write_button->selection_color(FL_GRAY);

        }

        if (((S_IXGRP & file_stat.stat_buffer.st_mode) != 0) != (mfm_attrib_group_execute_button->value() == 1)) {

          mfm_attrib_group_execute_button->set();

          mfm_attrib_group_execute_button->selection_color(FL_GRAY);

        }
        
        if (((S_IROTH & file_stat.stat_buffer.st_mode) != 0) != (mfm_attrib_others_read_button->value() == 1)) {

          mfm_attrib_others_read_button->set();

          mfm_attrib_others_read_button->selection_color(FL_GRAY);

        }

        if (((S_IWOTH & file_stat.stat_buffer.st_mode) != 0) != (mfm_attrib_others_write_button->value() == 1)) {

          mfm_attrib_others_write_button->set();

          mfm_attrib_others_write_button->selection_color(FL_GRAY);

        }

        if (((S_IXOTH & file_stat.stat_buffer.st_mode) != 0) != (mfm_attrib_others_execute_button->value() == 1)) {

          mfm_attrib_others_execute_button->set();

          mfm_attrib_others_execute_button->selection_color(FL_GRAY);

        }
				
        if (((S_ISUID & file_stat.stat_buffer.st_mode) != 0) != (mfm_attrib_uid_button->value() == 1)) {

          mfm_attrib_uid_button->set();

          mfm_attrib_uid_button->selection_color(FL_GRAY);

        }
				
        if (((S_ISGID & file_stat.stat_buffer.st_mode) != 0) != (mfm_attrib_gid_button->value() == 1)) {

          mfm_attrib_gid_button->set();

          mfm_attrib_gid_button->selection_color(FL_GRAY);

        }
				
        if (((S_ISVTX & file_stat.stat_buffer.st_mode) != 0) != (mfm_attrib_sticky_button->value() == 1)) {

          mfm_attrib_sticky_button->set();

          mfm_attrib_sticky_button->selection_color(FL_GRAY);

        }				
        
// user

        nr = mfm_attrib_user_choice->value();

        if (strcmp(user, mfm_attrib_user_choice->text(nr)) != 0) {

          user_item = (Fl_Menu_Item *) mfm_attrib_user_choice->mvalue();
          
          user_item->labelcolor(FL_GRAY);
          
          
        }
          

// group

        nr = mfm_attrib_group_choice->value();

        if (strcmp(group, mfm_attrib_group_choice->text(nr)) != 0) {

          group_item = (Fl_Menu_Item *) mfm_attrib_group_choice->mvalue();

          group_item->labelcolor(FL_GRAY);

        }

// date

        if (strcmp(mfm_attrib_date->value(), sdate) != 0) {
        
          mfm_attrib_date->textcolor(FL_GRAY);
          mfm_attrib_time->textcolor(FL_GRAY);
          
        }
        
        else if (strcmp(mfm_attrib_time->value(), stime) != 0)
          
          mfm_attrib_time->textcolor(FL_GRAY);
        
      }

    }

  mfm_attrib->show();
  
  xfree(&line);
  
} // class_mfm_attrib


/**************************************************************************
* Change permission
****************************************************************************/

void class_mfm_attrib::mfm_attrib_ch_mode(char *mode) {

  char *command,
       *list_file;
       
  class_mfm_window *ptr_window;
         
  ptr_window = (class_mfm_window *) ptr_mfm_window;
  
  list_file = ptr_window->get_list_file(false);
	
	chdir(ptr_window->path);
	
	if (mfm_attrib_recursive_button->value())

// Changed to sudo to make Tiny Core friendly
//  asprintf(&command, "chmod -R %s %s", mode, list_file);
    asprintf(&command, "sudo chmod -R %s %s", mode, list_file);	
	
	else
    
// Changed to sudo to make Tiny Core friendly
//  asprintf(&command, "chmod %s %s", mode, list_file);
    asprintf(&command, "sudo chmod %s %s", mode, list_file);

  system(command);

  xfree(&command);

  xfree(&list_file);

} // mfm_attrib_ch_mode


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


void class_mfm_attrib::mfm_attrib_owner_read_callback(){

  mfm_attrib_owner_read_button->selection_color(FL_BLACK);
  
  if (mfm_attrib_owner_read_button->value())
  
    mfm_attrib_ch_mode("u+r");
    
  else
  
    mfm_attrib_ch_mode("u-r");

}


void class_mfm_attrib::mfm_attrib_owner_write_callback(){

  mfm_attrib_owner_write_button->selection_color(FL_BLACK);
  
  if (mfm_attrib_owner_write_button->value())

    mfm_attrib_ch_mode("u+w");

  else

    mfm_attrib_ch_mode("u-w");

}


void class_mfm_attrib::mfm_attrib_owner_execute_callback(){

  mfm_attrib_owner_execute_button->selection_color(FL_BLACK);
  
  if (mfm_attrib_owner_execute_button->value())

    mfm_attrib_ch_mode("u+x");

  else

    mfm_attrib_ch_mode("u-x");

}


void class_mfm_attrib::mfm_attrib_group_read_callback(){

  mfm_attrib_group_read_button->selection_color(FL_BLACK);
  
  if (mfm_attrib_group_read_button->value())

    mfm_attrib_ch_mode("g+r");

  else

    mfm_attrib_ch_mode("g-r");

}


void class_mfm_attrib::mfm_attrib_group_write_callback(){

  mfm_attrib_group_write_button->selection_color(FL_BLACK);
  
  if (mfm_attrib_group_write_button->value())

    mfm_attrib_ch_mode("g+w");

  else

    mfm_attrib_ch_mode("g-w");

}


void class_mfm_attrib::mfm_attrib_group_execute_callback(){

  mfm_attrib_group_execute_button->selection_color(FL_BLACK);
  
  if (mfm_attrib_group_execute_button->value())

    mfm_attrib_ch_mode("g+x");

  else

    mfm_attrib_ch_mode("g-x");

}


void class_mfm_attrib::mfm_attrib_others_read_callback(){

  mfm_attrib_others_read_button->selection_color(FL_BLACK);
  
  if (mfm_attrib_others_read_button->value())

    mfm_attrib_ch_mode("o+r");

  else

    mfm_attrib_ch_mode("o-r");

}


void class_mfm_attrib::mfm_attrib_others_write_callback(){

  mfm_attrib_others_write_button->selection_color(FL_BLACK);
  
  if (mfm_attrib_others_write_button->value())

    mfm_attrib_ch_mode("o+w");

  else

    mfm_attrib_ch_mode("o-w");

}

void class_mfm_attrib::mfm_attrib_uid_callback(){

  mfm_attrib_uid_button->selection_color(FL_BLACK);
  
  if (mfm_attrib_uid_button->value())

    mfm_attrib_ch_mode("u+s");

  else

    mfm_attrib_ch_mode("u-s");

}


void class_mfm_attrib::mfm_attrib_gid_callback(){

  mfm_attrib_gid_button->selection_color(FL_BLACK);
  
  if (mfm_attrib_gid_button->value())

    mfm_attrib_ch_mode("g+s");

  else

    mfm_attrib_ch_mode("g-s");

}


void class_mfm_attrib::mfm_attrib_sticky_callback(){

  mfm_attrib_sticky_button->selection_color(FL_BLACK);
  
  if (mfm_attrib_sticky_button->value())

// Fix sticky bit function:
//  mfm_attrib_ch_mode("o+t");
    mfm_attrib_ch_mode(" +t");

  else

//  mfm_attrib_ch_mode("o-t");
    mfm_attrib_ch_mode(" -t");

}


void class_mfm_attrib::mfm_attrib_others_execute_callback(){

  mfm_attrib_others_execute_button->selection_color(FL_BLACK);
  
  if (mfm_attrib_others_execute_button->value())

    mfm_attrib_ch_mode("o+x");

  else

    mfm_attrib_ch_mode("o-x");

}


void class_mfm_attrib::mfm_attrib_user_callback() {

  char *command,
       *list_file;
       
  class_mfm_window *ptr_window;

  ptr_window = (class_mfm_window *) ptr_mfm_window;

  list_file = ptr_window->get_list_file(false);
	
	chdir(ptr_window->path);

// Recursive button does not work with chown command, added 3 lines:
  if (mfm_attrib_recursive_button->value())
  asprintf(&command, "sudo chown -R %s %s", mfm_attrib_user_choice->text(), list_file);
  else

// Changed to sudo to be more Tiny Core friendly
//asprintf(&command, "chown %s %s", mfm_attrib_user_choice->text(), list_file);
  asprintf(&command, "sudo chown %s %s", mfm_attrib_user_choice->text(), list_file);

  system(command);

  xfree(&command);

  xfree(&list_file);

}


void class_mfm_attrib::mfm_attrib_group_callback() {

  char *command,
       *list_file;

  class_mfm_window *ptr_window;

  ptr_window = (class_mfm_window *) ptr_mfm_window;

  list_file = ptr_window->get_list_file(false);
	
	chdir(ptr_window->path);

// Recursive button does not work with chgrp command, added 3 lines:
  if (mfm_attrib_recursive_button->value())
  asprintf(&command, "sudo chgrp -R %s %s", mfm_attrib_group_choice->text(), list_file);
  else

// Changed to sudo to be more Tiny Core friendly
//asprintf(&command, "chgrp %s %s", mfm_attrib_group_choice->text(), list_file);
  asprintf(&command, "sudo chgrp %s %s", mfm_attrib_group_choice->text(), list_file);

  system(command);

  xfree(&command);

  xfree(&list_file);

}


void class_mfm_attrib::mfm_attrib_touch_callback() {

  char *command,
       *list_file,
       sdate[MAX_STIME],
       stime[MAX_STIME];

  struct tm *ltime = NULL;

  time_t time_act;

  class_mfm_window *ptr_window;

  ptr_window = (class_mfm_window *) ptr_mfm_window;
  
  list_file = ptr_window->get_list_file(false);
  
  time_act = time(NULL);

  ltime = localtime(&time_act);
	
	chdir(ptr_window->path);

// Changed to sudo to be more Tiny Core friendly
//asprintf(&command, "touch %s", list_file);
  asprintf(&command, "sudo touch %s", list_file);

  system(command);

  xfree(&command);

  xfree(&list_file);
  
  strftime(sdate, MAX_STIME, "%x", ltime);
  strftime(stime, MAX_STIME, "%X", ltime);
  
  mfm_attrib_date->textcolor(FL_BLACK);
  mfm_attrib_time->textcolor(FL_BLACK);
  
  mfm_attrib_date->value(sdate);
  mfm_attrib_time->value(stime);
  
} // mfm_attrib_touch_callback


void class_mfm_attrib::mfm_attrib_exit_callback() {

  delete mfm_attrib;
	
	mfm_attrib = NULL;

} // mfm_attrib_exit_callback


void class_mfm_attrib::mfm_attrib_help_callback() {

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

} // mfm_attrib_help_callback
