/*
    Xunzip for Linux, handles gzip and zip files via zlib.
    Copyright (C) 1998 Tero Koskinen

    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., 675 Mass Ave, Cambridge, MA 02139, USA.
 
*/

// main.cpp

#include <fstream.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zlib.h>

#ifdef USE_GTK
#include <gtk/gtk.h>
#else

#include <qapp.h>
#include <qpushbt.h>
#include <qfont.h>
#include <qlistbox.h>
#include <qlabel.h>
#include <qfiledlg.h>
#include <qframe.h>
#include <qlabel.h>

#include <kapp.h>

#endif

#include "zipHeader.h"
#include "utils.h"
#include "config.h"
#include "mjono.h"
#include "itoa.h"

char *fstmp; // tiedoston valitsemista varten
ZipPacket zip;

int parseArgs(int argc,char **argv);

// muuttujat, joilla kayttttoliittymaa voi hallita, yhdessa paketissa

#ifdef USE_GTK
class Widgetit
{
public:
  Widgetit() { filesel=0;leveys=230;korkeus=200; }

  GtkWidget *window;
  GtkWidget *lista;
  GtkWidget *taulukko;
  GtkWidget *swindow;
  GtkWidget *quitNappi;
  GtkWidget *unzipNappi;
  GtkWidget *uncompressNappi;
  GtkWidget *openNappi;
  GtkWidget *testiNappi;
  GtkWidget *entry;
  GtkWidget *menubar;
  // GtkWidget *rootmenu;
  GtkWidget *menu;
  GtkWidget *filemenu;
  GtkWidget *actionsmenu;
  GtkWidget *filesel;
  int leveys;
  int korkeus;
} wi;



// funktioiden prototyyppeja (niiden joiden tarvitsee vain :))
void destroy_window (GtkWidget  *,GtkWidget **window);
void delete_event (GtkWidget *, gpointer *);
void delete_unCompress_event(GtkWidget *, GtkWidget *data);
void unCompress_event(GtkWidget *widget,gpointer *data);
void testcrc_event(GtkWidget *widget,gpointer *data);
void filesel_hide(void);
void create_file_selection (int type);

// funktioita

void destroy_window (GtkWidget  *,GtkWidget **window)
{
  *window = NULL;
}

void delete_event (GtkWidget *, gpointer *)
{
    zip.close(wi.lista);
    gtk_main_quit ();
}

void delete_unCompress_event(GtkWidget *, GtkWidget *data)
{
  gtk_widget_hide(data);
  gtk_widget_destroy(data);
}

// luo hakemiston(tiedoston) valintaikkunan
void unCompress_event(GtkWidget *,gpointer *)
{
#if 0
    GtkWidget *window;

    GtkWidget *label;
	GtkWidget *okButton;
	GtkWidget *cancelButton;
	GtkWidget *taulukko;

	window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW (window), "Choose directory");
	gtk_container_border_width(GTK_CONTAINER(window),5);
    gtk_widget_set_usize(window,150,80);

	taulukko=gtk_table_new(3,2,TRUE);
    gtk_table_set_row_spacings (GTK_TABLE (taulukko), 1);
    gtk_table_set_col_spacings (GTK_TABLE (taulukko), 1);
    gtk_container_border_width (GTK_CONTAINER (taulukko), 1); 
    gtk_container_add(GTK_CONTAINER(window),taulukko);
	
	okButton=gtk_button_new_with_label("OK");
	gtk_table_attach_defaults(GTK_TABLE(taulukko),okButton,0,1,2,3);
	cancelButton=gtk_button_new_with_label("Cancel");
	gtk_signal_connect(GTK_OBJECT (cancelButton), "clicked",(GtkSignalFunc) delete_unCompress_event,window);
	gtk_table_attach_defaults(GTK_TABLE(taulukko),cancelButton,1,2,2,3);
	wi.entry=gtk_entry_new();
	gtk_table_attach_defaults(GTK_TABLE(taulukko),wi.entry,0,2,1,2);
	label=gtk_label_new("Where to extract?");
	gtk_table_attach_defaults(GTK_TABLE(taulukko),label,0,2,0,1);
	
	gtk_widget_show(label);
	gtk_widget_show(wi.entry);
	gtk_widget_show(cancelButton);
	gtk_widget_show(okButton);
	gtk_widget_show(taulukko);
	gtk_widget_show(window);
#else
    create_file_selection(1);
#endif
}

void delete_testcrc_event(GtkWidget *,GtkWidget *data)
{
    gtk_widget_hide(data);
    gtk_widget_destroy(data);
}

void testcrc_event(GtkWidget *,gpointer *)
{
    GtkWidget *window;
    GtkWidget *label;
    GtkWidget *taulukko;
    GtkWidget *lista;
    GtkWidget *swindow;
    GtkWidget *button;

    if (zip.isOpen())
    {

    // paaikkuna
	    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
	    gtk_window_set_title(GTK_WINDOW(window),"Files with errors");
	    gtk_signal_connect(GTK_OBJECT(window),"destroy",GTK_SIGNAL_FUNC(delete_testcrc_event),window);
	    gtk_container_border_width(GTK_CONTAINER(window),10);
	    gtk_widget_set_usize(window,200,200);
  
    // uusi taulukko
	    taulukko=gtk_table_new(5,3,TRUE);
	    gtk_table_set_row_spacings (GTK_TABLE (taulukko), 1);
	    gtk_table_set_col_spacings (GTK_TABLE (taulukko), 1);
	    gtk_container_border_width (GTK_CONTAINER (taulukko), 1); 
	    gtk_container_add(GTK_CONTAINER(window),taulukko);

    // scrollattava lista (ikkuna, jossa lista)
	    swindow=gtk_scrolled_window_new(NULL,NULL);
	    gtk_widget_set_usize(swindow,100,100);
	    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
								  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 
	    gtk_table_attach_defaults(GTK_TABLE(taulukko),swindow,0,3,1,4);

    // itse lista nyt
	    lista=gtk_list_new();
	    gtk_list_set_selection_mode (GTK_LIST (lista), GTK_SELECTION_MULTIPLE);
	    gtk_list_set_selection_mode (GTK_LIST (lista), GTK_SELECTION_BROWSE);
	    gtk_container_add(GTK_CONTAINER(swindow),lista);

    // kyltti    
	    label=gtk_label_new("Files which have errors");
	    gtk_table_attach_defaults(GTK_TABLE(taulukko),label,0,3,0,1);
    
    // ja ok-nappi
	    button=gtk_button_new_with_label("OK");
	    gtk_signal_connect(GTK_OBJECT (button), "clicked",(GtkSignalFunc) delete_testcrc_event,window);
	    gtk_table_attach_defaults(GTK_TABLE(taulukko),button,1,2,4,5);
    
	    gtk_widget_show(button);
	    gtk_widget_show(label);
	    gtk_widget_show(lista);
	    gtk_widget_show(swindow);
	    gtk_widget_show(taulukko);
	    gtk_widget_show(window);
	
		zip.testcrc(lista);
	}
}

// hakemiston valinta onnistui hyvaksytysti
void dir_selection_ok (GtkWidget *, GtkFileSelection *fs)
{
    char tiedosto[256];
    for (int a=0;a<256;a++)
	    tiedosto[a]='\0';
    fstmp=gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs));
    strncpy(tiedosto,fstmp,strlen(fstmp));
    filesel_hide();
    if (zip.unZip(tiedosto)==-1)
	{
	    showMessage("Can not uncompress the file");
	}
}

// piilotetaan hakemiston/tiedoston valintaikkuna
void filesel_hide(void)
{
  if (GTK_WIDGET_VISIBLE(wi.filesel))
	{
	  gtk_widget_hide(wi.filesel);
	  gtk_widget_destroy(wi.filesel);
	  wi.filesel=NULL;
	}
}

// tiedosto valittu hyvaksytysti
void file_selection_ok (GtkWidget *, GtkFileSelection *fs)
{
    char tiedosto[256];
    for (int a=0;a<256;a++)
	    tiedosto[a]='\0';
    fstmp=gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs));
    strncpy(tiedosto,fstmp,strlen(fstmp));
    filesel_hide();
    if (tiedosto)
	{
	    if (zip.open(tiedosto,wi.lista)==-1)
		{
		    showMessage("Can not open the file");
		}
	}
}


// luodaan/tuhotaan tiedoston valintaikkuna
void open_file_selection(GtkWidget *, gpointer *)
{
    if (wi.filesel==NULL)
	    create_file_selection(0);
    else
	    filesel_hide();
}

// luodaan ikkuna ja sihen tarvittavat widgetit
void alustaGTK(void)
{
    char eMessage[100];
	GtkWidget *menuitem;

    tyhjennaTaulukko(eMessage,100);
    strcpy(eMessage,"Xunzip ");
    strcat(eMessage,VERSION);

    // paaikkuna
    wi.window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(wi.window),eMessage);
    gtk_signal_connect(GTK_OBJECT(wi.window),"delete_event",GTK_SIGNAL_FUNC(delete_event),NULL);
    gtk_container_border_width(GTK_CONTAINER(wi.window),1);
    gtk_widget_set_usize(wi.window,wi.leveys,wi.korkeus);
  
    // uusi taulukko
    wi.taulukko=gtk_table_new(6,4,TRUE);
    gtk_table_set_row_spacings (GTK_TABLE (wi.taulukko), 1);
    gtk_table_set_col_spacings (GTK_TABLE (wi.taulukko), 1);
    gtk_container_border_width (GTK_CONTAINER (wi.taulukko), 1); 
    gtk_container_add(GTK_CONTAINER(wi.window),wi.taulukko);

    // scrollattava lista (ikkuna, jossa lista)
    wi.swindow=gtk_scrolled_window_new(NULL,NULL);
    gtk_widget_set_usize(wi.swindow,wi.leveys>>1,wi.korkeus>>1);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wi.swindow),
								  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 
    gtk_table_attach_defaults(GTK_TABLE(wi.taulukko),wi.swindow,0,4,2,6);

    // itse lista nyt
    wi.lista=gtk_list_new();
    gtk_list_set_selection_mode (GTK_LIST (wi.lista), GTK_SELECTION_MULTIPLE);
    gtk_list_set_selection_mode (GTK_LIST (wi.lista), GTK_SELECTION_BROWSE);
    gtk_container_add(GTK_CONTAINER(wi.swindow),wi.lista);
    
    // open-nappi
    wi.openNappi=gtk_button_new_with_label("Open");
    gtk_signal_connect (GTK_OBJECT (wi.openNappi), "clicked",GTK_SIGNAL_FUNC (open_file_selection), NULL);
    gtk_table_attach_defaults(GTK_TABLE(wi.taulukko),wi.openNappi,0,1,1,2);

    // quit-nappi
    wi.quitNappi=gtk_button_new_with_label("Quit");
    gtk_signal_connect(GTK_OBJECT(wi.quitNappi),"clicked",GTK_SIGNAL_FUNC(delete_event),NULL);
    gtk_table_attach_defaults(GTK_TABLE(wi.taulukko),wi.quitNappi,3,4,1,2);

    // unzip-nappi
	wi.unzipNappi=gtk_button_new_with_label("Extract");
	gtk_signal_connect(GTK_OBJECT(wi.unzipNappi),"clicked",GTK_SIGNAL_FUNC(unCompress_event),NULL);
	gtk_table_attach_defaults(GTK_TABLE(wi.taulukko),wi.unzipNappi,1,2,1,2);

    // test-nappi
    wi.testiNappi=gtk_button_new_with_label("Test");
    gtk_signal_connect(GTK_OBJECT(wi.testiNappi),"clicked",GTK_SIGNAL_FUNC(testcrc_event),NULL);
    gtk_table_attach_defaults(GTK_TABLE(wi.taulukko),wi.testiNappi,2,3,1,2);
    
    // menujen luonti
   	wi.menubar=gtk_menu_bar_new();
    gtk_table_attach_defaults(GTK_TABLE(wi.taulukko),wi.menubar,0,4,0,1);
        
    // uusi menu, valikkoja varten, tata ei tarvitse nayttaa (ohjeiden mukaan...)
    wi.menu=gtk_menu_new();
    
    // File-valikko
    wi.filemenu=gtk_menu_item_new_with_label("File");
    gtk_widget_show(wi.filemenu);
	gtk_menu_item_set_submenu(GTK_MENU_ITEM(wi.filemenu),wi.menu);
        
    // open
    menuitem=gtk_menu_item_new_with_label("Open");
    gtk_menu_append(GTK_MENU(wi.menu),menuitem);
    gtk_signal_connect(GTK_OBJECT(menuitem),"activate",GTK_SIGNAL_FUNC (open_file_selection), NULL);
    gtk_widget_show(menuitem);
    
    // viiva valiin
    menuitem=gtk_menu_item_new();
    gtk_menu_append(GTK_MENU(wi.menu),menuitem);
    gtk_widget_show(menuitem);
    
    // quit
    menuitem=gtk_menu_item_new_with_label("Quit");
    gtk_menu_append(GTK_MENU(wi.menu),menuitem);
    gtk_signal_connect(GTK_OBJECT(menuitem),"activate",GTK_SIGNAL_FUNC (delete_event), NULL);
    gtk_widget_show(menuitem);

    // liitetaan menu menubaariin
    gtk_menu_bar_append(GTK_MENU_BAR(wi.menubar),wi.filemenu);

    wi.menu=gtk_menu_new();

    // Actions-valikko
    wi.actionsmenu=gtk_menu_item_new_with_label("Actions");
    gtk_widget_show(wi.actionsmenu);
    gtk_menu_item_set_submenu(GTK_MENU_ITEM(wi.actionsmenu),wi.menu);

    // Extract
    menuitem=gtk_menu_item_new_with_label("Extract");
    gtk_menu_append(GTK_MENU(wi.menu),menuitem);
    gtk_signal_connect(GTK_OBJECT(menuitem),"activate",GTK_SIGNAL_FUNC (unCompress_event), NULL);
    gtk_widget_show(menuitem);

    // Test
    menuitem=gtk_menu_item_new_with_label("Test");
    gtk_menu_append(GTK_MENU(wi.menu),menuitem);
    gtk_signal_connect(GTK_OBJECT(menuitem),"activate",GTK_SIGNAL_FUNC (testcrc_event), NULL);
    gtk_widget_show(menuitem);
    
    // liitetaan menu menubaariin
	gtk_menu_bar_append(GTK_MENU_BAR(wi.menubar),wi.actionsmenu);
		            
	// lopuksi naytetaan kaikki
	gtk_widget_show(wi.menubar);
    gtk_widget_show(wi.testiNappi);
    gtk_widget_show(wi.unzipNappi);
    gtk_widget_show(wi.quitNappi);
    gtk_widget_show(wi.openNappi);
    gtk_widget_show(wi.lista);
    gtk_widget_show(wi.swindow);
    gtk_widget_show(wi.taulukko);
    gtk_widget_show(wi.window);
}

void create_file_selection (int type)
{
    if (type==0)
	    wi.filesel = gtk_file_selection_new ("File selection");
	else
	    wi.filesel = gtk_file_selection_new ("Directory selection");

    gtk_window_position (GTK_WINDOW (wi.filesel), GTK_WIN_POS_MOUSE);
    gtk_signal_connect (GTK_OBJECT (wi.filesel), "destroy",
					  (GtkSignalFunc) destroy_window,
					  &wi.filesel);
      
    if (type==0)
	    gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (wi.filesel)->ok_button),
					  "clicked", (GtkSignalFunc) file_selection_ok,wi.filesel);
    else
	    gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(wi.filesel)->ok_button),
				      "clicked",(GtkSignalFunc)dir_selection_ok,wi.filesel);
    gtk_signal_connect_object (GTK_OBJECT (GTK_FILE_SELECTION (wi.filesel)->cancel_button),
							 "clicked", (GtkSignalFunc) gtk_widget_destroy,
							 GTK_OBJECT (wi.filesel));
    gtk_widget_show(wi.filesel);
}
#else // !USE_GTK

#include "xunzip.qt.h"

MyWidget *w;

// #include "xunzip.moc"

#endif

// ----------- Main -----------
int main(int argc,char **argv)
{
    int status;
#ifdef USE_GTK
    gtk_init(&argc,&argv);
    fstmp=NULL;
    alustaGTK();
#else
    KApplication k(argc,argv);
    w=new MyWidget();
    k.setMainWidget(w);
    w->show();
#endif
    parseArgs(argc,argv);
#ifdef USE_GTK
    gtk_main();
    status=0;
    zip.close(wi.lista);
#else
    status=k.exec();
	zip.close(w->lista);
#endif
    return status;
}

int parseArgs(int argc,char **argv)
{
    if (argc<2)
	    return 0;
	    
	for (int a=1;a<argc;a++)
	{
	    if (argv[a][0]!='-')
	    {
#ifdef USE_GTK
		    if (zip.open(argv[a],wi.lista)==-1)
#else
		    if (zip.open(argv[a],w->lista)==-1)
#endif
				showMessage("Can not open the file");
		    return 0;
		}
	}
	return 0;
}

