#include <config.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <strings.h>
#include <kapp.h>

#include "zipprot.h"

ZipProtocol::ZipProtocol(const char *localFile, const char *file)
	:ArchiveProtocol(localFile,file)
{
	Type = Protocol::Zip;
	Code = 4;
	Prefix += "#zip:";
	ReadOnly = TRUE;
}

ZipProtocol::~ZipProtocol()
{}

void ZipProtocol::initCommand(QStrList& cmd)
{ cmd.append("unzip");}

bool ZipProtocol::thread_updateEntries()
{
	rawEntries->clear();
	DirDict->clear();
	TreeItem	*root = new TreeItem("/");
	DirDict->insert("/",root);
	QStrList	cmd;
	QString		str;
	int		status;
	initCommand(cmd);
	cmd.append("-qq");
	cmd.append("-l");
	cmd.append(LocalFile.data());
	if (!executeCommand("unzip",cmd)) return FALSE;
	char	buf[2048], *last;
	while (1) {
		if (!fgets(buf,2048,fout)) break;
		strtok_r(buf,"\r\n",&last);
		FileInfo	*fi = new FileInfo(buf,Code);
		str = Prefix.data();
		str += fi->fileName();
		if (fi->isDir() && str[str.length()-1] != '/') str += '/';
		fi->setPath(str.data());
		processEntry(fi);
		rawEntries->append(fi);
	}
	finishCommand();
	if (WIFEXITED(status)) {
		updateFlag = FALSE;
		return TRUE;
	}
	updateFlag = TRUE;
	return FALSE;
}

void ZipProtocol::createParentStr(QString& Str, FileInfo *fi)
{
	Str.truncate(0);
#define Date	fi->lastModified().date()
#define Time	fi->lastModified().time()
	int	y = (Date.year() < 2000 ? div(Date.year(),1900).rem : div(Date.year(),2000).rem);
	Str.sprintf("%d %.2d-%.2d-%.2d %.2d:%.2d ",0,Date.month(),Date.day(),y,Time.hour(),Time.minute());
#undef 	Date
#undef	Time
}

bool ZipProtocol::extract(const char *src, const char *dest, ProgressDlg *dlg)
{
	QStrList	cmd;
	initCommand(cmd);
	cmd.append("-o");
	cmd.append(LocalFile.data());
	cmd.append(src);
	cmd.append("-d");
	cmd.append(dest);
	if (!executeCommand("unzip",cmd)) return FALSE;
	char	buf[2048], *last;
	while (1) {
		if (!fgets(buf,2048,fout)) break;
		strtok_r(buf,"\r\n",&last);
		if (dlg) {
			dlg->setLabelText(buf);
			dlg->setProgress(100);
		}
	}
	finishCommand();
	int	status;
	waitpid(ProcID,&status,0);
	if (WIFEXITED(status)) {
		updateFlag = FALSE;
		return TRUE;
	}
	return FALSE;
}
