/*
  Cloned Xunzip
  Copyright (C) 1999 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.
 
*/

#include <stdio.h>
#include <string.h>
#include <config.h>

#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>

#include <gnome.h>

/* #include <list>
#include <string> */

#include "app.hh"
#include "callbacks.hh"
#include "prepareapp.hh"
#include "misc.h"

#include "zip_utils.h"

#ifndef DIRMODE
#define DIRMODE 0700
#endif

App::App(int read_config_file)
{
	pid_t pid=0;
	dialog=0;
	readConfig=read_config_file;
	filesel=0;
	selectedFile=-1;
	app=0;
	bar=0;
	list=0;
	saveSize=0;
	saveSizeTmp=0;
	width=400;
	height=400;
	zip=zip_file_new();

	gchar *msg;
	pid=getpid();

	msg=g_strdup_printf("/tmp/%d.cxunzip.XXXXXX",(int)pid);
	tmpdir=mkdtemp(msg);
        if (tmpdir.size() > 0)
                mkdir(tmpdir.c_str(),DIRMODE);
	g_free(msg);
}

App::~App()
{
	if (zip)
		zip_file_close(zip);
	zip=NULL;

	if (tmpdir.size() > 0) {
		delete_dir(tmpdir.c_str());
	} else {
		fprintf(stderr,"no tmpdir?\n");
	}
	
	// free(tmpdir);
}

void App::read_config(void)
{
	saveSize=gnome_config_get_int("/cxunzip/Options/RememberWindowSize");
  
	if (saveSize!=0)
	{
		width=gnome_config_get_int("/cxunzip/Geometry/w");
		height=gnome_config_get_int("/cxunzip/Geometry/h");
	}
}

void App::write_config(void)
{
	gint x,y,w,h;

	gdk_window_get_geometry (app->window, &x, &y, &w, &h, NULL);

	if (saveSize!=0)
	{
		gnome_config_set_int("/cxunzip/Options/RememberWindowSize",saveSize);
		gnome_config_set_int("/cxunzip/Geometry/w",w);
		gnome_config_set_int("/cxunzip/Geometry/h",h);
		gnome_config_set_int("/cxunzip/Geometry/x",x);
		gnome_config_set_int("/cxunzip/Geometry/y",y);
	}
	gnome_config_sync();
}

void clear_list(App *app)
{
	gtk_clist_clear(GTK_CLIST(app->list));
}

#ifndef CLEAR_BUFFER_2
#define CLEAR_BUFFER_2(x,y) for (int a=0;a<y;a++) x[a]='\0';
#endif

void add_to_list_current(gpointer data,gpointer user_data)
{
	const char *ctmp[5];
	
	int yr=0,mo=0,dy=0;
	char date[256];
	char ratio[256];
	char size[256];
	char packed[256];
	
	ZipCDR *r;
	App *app;
	
	if (data==NULL)
		return;
	g_return_if_fail(user_data!=NULL);

	r=(ZipCDR*)data;
	app=(App*)user_data;

	convert_date(r->moddate,&yr,&mo,&dy);
	CLEAR_BUFFER_2(date,256);
	sprintf(date,"%d-%d-%d",dy,mo,yr);
	CLEAR_BUFFER_2(ratio,256);
	if (r->size > 0) {
		sprintf(ratio,"%ld%%",100-(unsigned long)(((r->csize*100)/
						   (r->size))+0.5));
	} else {
		sprintf(ratio,"0%%");
	}
		
	CLEAR_BUFFER_2(size,256);
	sprintf(size,"%ld",r->size);
	CLEAR_BUFFER_2(packed,256);
	sprintf(packed,"%ld",r->csize);
	
	ctmp[0]=(const char*)r->filename;
	ctmp[1]=(const char*)date;
	ctmp[2]=(const char*)ratio;
	ctmp[3]=(const char*)size;
	ctmp[4]=(const char*)packed;
	gtk_clist_append(GTK_CLIST(app->list),(char**)ctmp);
}

void add_to_list(App *app)
{
	if (app->zip) {
		g_slist_foreach(app->zip->records,add_to_list_current,
				(gpointer)app);
	}
}

void list_errors(GSList *errors)
{
	GtkWidget *dialog;
	gchar *tmp1;
	gchar *tmp2;
	GSList *e;

	tmp1 = g_strdup("Following files had errors:\n");
	for (e = errors; e != NULL; e=e->next) {
		if (!e->next) {
			tmp2 = g_strconcat(tmp1,(const char*)e->data,NULL);
		} else {
			tmp2 = g_strconcat(tmp1,(const char*)e->data,
					",\n",NULL);
		}
		g_free(tmp1);
		tmp1 = tmp2;
	}
	dialog = gnome_ok_dialog(tmp1);
	gtk_widget_show(dialog);
	g_free(tmp1);
}

void create_view_dialog(App *app)
{
	GtkWidget *dialog;
	const char *mtype;
	char *filename;
	GSList *node;
	ZipCDR *cdr;
	char *program;

	node=g_slist_nth(app->zip->records,app->selectedFile+1);
	cdr=(ZipCDR*)node->data;
	filename=cdr->filename;

	mtype=gnome_mime_type(filename);
	if (mtype!=NULL)
		program=parse_program(gnome_mime_program((char*)mtype));
	else
		program=NULL;

	dialog=gnome_request_dialog(FALSE,_("View file with program"),
				    program,1024,
				    (void (*)(gchar*, gpointer))
                                    view_dialog_clicked_callback,app,
				    NULL);
	g_free(program);
	gtk_widget_show(dialog);
}

int open_file(const char *file,App *app)
{
	char *filename;
	
	int status=0;
	
	if (!file) {
		show_error(_("Filepointer lost "),NULL);
		return 1;
	}
	
	if (strncmp(file,"file:",5)==0) {
		filename=new char[strlen(file)-4];
		
		strcpy(filename,file+5);
		for (unsigned int a=0;a<strlen(filename);a++) {
			if (filename[a]=='\n' || filename[a]=='\r')
				filename[a]='\0';
		}
		filename[strlen(file)-5]='\0';
	} else  {
		filename=new char[strlen(file)+1];
		strcpy(filename,file);
		filename[strlen(file)]='\0';
	}

	if (app->zip) {
		gchar *msg=g_strdup_printf(_("Cloned Xunzip %s"),VERSION);
		zip_file_close(app->zip);
		clear_list(app);
		gtk_window_set_title(GTK_WINDOW(app->app),msg);
		if (msg)
			g_free(msg);
	}

	status=zip_file_open(filename,app->zip);
	if (status==0) {
		gchar *mesg;
		mesg=g_strdup_printf(_("Unable open file %s"),
				       filename);
		show_error(mesg);
		delete filename;
		g_free(mesg);
		return 1;
	}

	app->selectedFile=-1;
	
	gtk_window_set_title(GTK_WINDOW(app->app),filename);
	clear_list(app);
	add_to_list(app);
	
	delete filename;
	
	return 0;
}

void show_message(const char *msg)
{
	GtkWidget *w;
	w=gnome_message_box_new(msg,GNOME_MESSAGE_BOX_INFO,
				GNOME_STOCK_BUTTON_OK,NULL);
	gtk_widget_show(w);
}


void show_error(const char *msg,const char *file)
{
	gchar *total_msg;
	GtkWidget *w;
	total_msg=g_copy_strings(msg,file,NULL);
	w=gnome_message_box_new(total_msg,GNOME_MESSAGE_BOX_ERROR,
				GNOME_STOCK_BUTTON_OK,NULL);
	gtk_widget_show(w);
	g_free(total_msg);
}

void show_error(const char *msg)
{
	GtkWidget *w;
	w=gnome_message_box_new(msg,GNOME_MESSAGE_BOX_ERROR,
				GNOME_STOCK_BUTTON_OK,NULL);
	gtk_widget_show(w);
}

void destroy_file_selection(App *app)
{
	if (app->filesel) {
		gtk_widget_hide(app->filesel);
		gtk_widget_destroy(app->filesel);
		app->filesel=NULL;
	}
}
