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

#include <FL/fl_file_chooser.H>

// Added to extract .deb files:
#include <stdlib.h>

#include "mfmzip_ui.hxx"

#define MAXSIZE 1000

class_mfmzip *ptr_mfmzip;

/**************************************************************************
*
* Function: idle_function
*
* function to call during idle
*
****************************************************************************/

void idle_function(void *) {

  static char *line = NULL;
	
  static size_t dim_line = 0;

  if (getline(&line, &dim_line, ptr_mfmzip->stream)>0) { 						

    ptr_mfmzip->mfmzip_browser->add(line);
		
    if (ptr_mfmzip->mfmzip_browser->size() > MAXSIZE)
		
      ptr_mfmzip->mfmzip_browser->remove(1);		
		
		ptr_mfmzip->mfmzip_browser->bottomline(ptr_mfmzip->mfmzip_browser->size());
		
  }			
		
  else {							
      
    pclose(ptr_mfmzip->stream);
    
    ptr_mfmzip->activate_all();    
		
		Fl::remove_idle(idle_function);
    
    if (ptr_mfmzip->extract) 
  
      ptr_mfmzip->mfmzip_exit_callback();      
						
  }		
	
}


/**************************************************************************
* Metodi di class_mfmzip
****************************************************************************/

/**************************************************************************
* Constructor
****************************************************************************/

class_mfmzip::class_mfmzip(int argc, char **argv) : class_mfmzip_fluid() {

  archive = NULL;
  extract = false;
   
	ptr_mfmzip = this;
  
  for (int i=1; i<argc; i++) {
  
    if (strcmp(argv[i], "-x") == 0) 
          
      extract = true;
          
    else 

      asprintf(&archive, "%s", argv[i]);      
      
  }       
      
  if (archive == NULL) {

    archive = (char *) malloc(1);

    archive[0] = 0;

  }   
  
  mfmzip->label(archive);	      
  
  mfmzip->show();
  
  if (extract)  {
  
    mfmzip_extract_callback();  
    
  }       

} // class_mfmzip


/**************************************************************************
*
* activate_all
*
* Activate all buttons
*
****************************************************************************/

void class_mfmzip::activate_all() {

  mfmzip_open->activate();
  mfmzip_extract->activate();
  mfmzip_exit->activate();
  
  mfmzip->redraw();

} // activate_all


/**************************************************************************
*
* deactivate_all
*
* Deactivate all buttons
*
****************************************************************************/

void class_mfmzip::deactivate_all() {

  mfmzip_open->deactivate();
  mfmzip_extract->deactivate();
  mfmzip_exit->deactivate();
  
  mfmzip->redraw();  

} // deactivate_all


/**************************************************************************
*
* archive_list
*
* List archive's content
*
****************************************************************************/

void class_mfmzip::archive_list() {

  char *command;
  
  int  lun = strlen(archive);

  mfmzip_browser->clear();

  if (!memcmp(archive+lun-7, ".tar.gz",7))

    asprintf(&command, "tar ztf '%s'", archive);

  else if (!memcmp(archive+lun-8, ".tar.bz2",8))

    asprintf(&command, "tar jtf '%s'", archive);

  else if (!memcmp(archive+lun-4, ".zip",4))

// Busybox friendly:
//  asprintf(&command, "zipinfo -1 '%s'", archive);
    asprintf(&command, "unzip -l '%s'", archive);

  else if (!memcmp(archive+lun-4, ".tar",4))

    asprintf(&command, "tar tf '%s'", archive);

  else if (!memcmp(archive+lun-4, ".tgz",4))

    asprintf(&command, "tar ztf '%s'", archive);

// Add ability to list .gz file contents:
  else if (!memcmp(archive+lun-3, ".gz",3))

    asprintf(&command, "tar tf '%s'", archive);

// Add ability to list .xz file contents:
  else if (!memcmp(archive+lun-7, ".tar.xz",7))

    asprintf(&command, "tar tf '%s'", archive);

// Add ability to list .deb file contents:
  else if (!memcmp(archive+lun-4, ".deb",4))

    asprintf(&command, "ar t '%s'", archive);

  else
  
    command = NULL;  
    
  if (command != NULL) { 
  
    deactivate_all();  
  
    stream = popen(command,"r");
  
    free(command);

    Fl::add_idle(idle_function);
  
  } 

} // archive_list


/**************************************************************************
* Callbacks
**************************************************************************/

void class_mfmzip::mfmzip_open_callback() {

  char *string;

// Add ability to extract numerous other file extensions:
//string = fl_file_chooser("Select archive", "{*.tar,*.tar.gz,*.tar.bz2,*.tgz,*.zip}", archive);
  string = fl_file_chooser("SELECT ARCHIVE", "{*.gz,*.tar,*.tar.gz,*.tar.xz,*.tar.bz2,*.tgz,*.zip,*.deb}", archive);

  if (string != NULL) {
    
    asprintf(&archive, "%s", string);
    
    mfmzip_browser->clear();
    
    mfmzip->label(archive);	    

  }  

} // mfmzip_open_callback


void class_mfmzip::mfmzip_list_callback() {

  if (archive != NULL)
  
    archive_list();  

} // mfmzip_list_callback


void class_mfmzip::mfmzip_extract_callback() {

  char *dest,
       *command;

  int  lun = strlen(archive);

  mfmzip_browser->clear();

  asprintf(&command, "%s", archive);  

  for (int i = lun; i >= 0; i--)  {
  
    if (command[i] == '/')
    
      break;
      
    command[i] = 0;      
    
  }  
  
  if (strlen(command) == 0) {
  
    free(command);
    
    asprintf(&command, ".");  
  
  }    

  if (extract)
  
    dest = command;
    
  else {

    dest = fl_dir_chooser("SELECT DESTINATION PATHWAY", command);

    free(command);  

  }   

  if (dest != NULL) {


// Reference: *.gz,*.tar,*.tar.gz,*.tar.xz,*.tar.bz2,*.tgz,*.zip,*.deb

// Add ability to extract .deb file:
    if (!memcmp(archive+lun-4, ".deb",4))

      asprintf(&command, "ar p '%s' data.tar.gz | tar zxvC '%s'", archive, dest);

//{

// This if/else works for .xz but not .gz :(

//    if (asprintf(&command, "ar t '%s' | grep data.tar.gz", archive) == true)
    
//      asprintf(&command, "ar p '%s' data.tar.* | tar zxvC '%s'", archive, dest);

//    else

        // This works for data.tar.xz, just can't get both to work :(
//      asprintf(&command, "ar p '%s' data.tar.* | tar JxvC '%s'", archive, dest);

// Only worked for first, not second:
//      asprintf(&command, "ar p '%s' data.tar.* | tar zxvC '%s'", archive, dest) || asprintf(&command, "ar p '%s' data.tar.* | tar JxvC '%s'", archive, dest);


// Didn't work, query why?
//    if (asprintf(&command, "ar t '%s' | grep data.tar.gz", archive))

//      asprintf(&command, "ar p '%s' data.tar.* | tar zxvC '%s'", archive, dest);

//    else

//      asprintf(&command, "ar p '%s' data.tar.* | tar JxvC '%s'", archive, dest);

// Works standalone, only for data.tar.gz though:
//    asprintf(&command, "ar p '%s' data.tar.gz | tar zxvC '%s'", archive, dest);

// Works only for data.tar.gz:
//  {
//  if (asprintf(&command, "ar t '%s' | grep data.tar.gz", archive) != NULL)
//    asprintf(&command, "ar p '%s' data.tar.gz | tar zxvC '%s'", archive, dest);
//  else
//    asprintf(&command, "ar p '%s' data.tar.xz | tar JxvC '%s'", archive, dest);
//  }

// Trying special grep if statement:

 // if (asprintf(&command, "ar t '%s' | grep data.tar.gz", archive) == 1)
//  if (asprintf(&command, "ar t '%s' | grep data.tar.gz", archive)) {

//  free(command);

//  char *command;

//  asprintf(&command, "ar p '%s' data.tar.gz | tar zxvC '%s'", archive, dest);

//  }

//  else

//    asprintf(&command, "ar p '%s' data.tar.xz | tar JxvC '%s'", archive, dest);

//  }

// Add ability to extract .tar.xz file:
    else if (!memcmp(archive+lun-7, ".tar.xz",7))

      asprintf(&command, "tar xvf '%s' -C '%s'", archive, dest);

// Add ability to extract .gz file:
    else if (!memcmp(archive+lun-3, ".gz",3))

      asprintf(&command, "tar zxvf '%s' -C '%s'", archive, dest);

    else if (!memcmp(archive+lun-7, ".tar.gz",7))

      asprintf(&command, "tar zxvf '%s' -C '%s'", archive, dest);

    else if (!memcmp(archive+lun-8, ".tar.bz2",8))

      asprintf(&command, "tar jxvf '%s' -C '%s'", archive, dest);

    else if (!memcmp(archive+lun-4, ".zip",4))

// Modified for busybox:
//    asprintf(&command, "unzip -u -o '%s' -d '%s' ", archive, dest);
      asprintf(&command, "unzip -o '%s' -d '%s' ", archive, dest);
      
    else if (!memcmp(archive+lun-4, ".tar",4))

      asprintf(&command, "tar xvf '%s' -C '%s'", archive, dest);

    else if (!memcmp(archive+lun-4, ".tgz",4))

      asprintf(&command, "tar zxvf '%s' -C '%s'", archive, dest);

    else
  
      command = NULL;       

    if (command != NULL) { 

      deactivate_all();            

      stream = popen(command,"r");     
  
      free(command);

      Fl::add_idle(idle_function);
  
    }     
    
  }  
  
} // mfmzip_extract_callback


void class_mfmzip::mfmzip_exit_callback() {

  delete this->mfmzip;
  delete this;

} // mfmzip_exit_callback

void class_mfmzip::mfmzip_help_callback() {

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

} // mfmzip_help_callback
