/*
 * Copyright (c) 2005-2006 Tom N Harris.
 *
 *     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.
 *
 *     A copy of the GNU General Public License can be found at
 *     http://www.gnu.org/
 *
 * Written by Tom N Harris <telliamed@whoopdedo.org>.
 *
 */

#ifndef ZLIB_ZIPARCHIVE_H
#define ZLIB_ZIPARCHIVE_H

#include "zlib.h"
#include "zip.h"
#include "unzip.h"

namespace zLib
{

typedef struct _zip_extrafield_tag_s
{
	unsigned short tag;
	unsigned short blksz;
} zip_extrafield_tag;


class ZipArchive
{
public:
	~ZipArchive();
	ZipArchive();

	int Close(void);
	int Open(const char* fname, int append = APPEND_STATUS_CREATE);
	int Open(const wchar_t* fname, int append = APPEND_STATUS_CREATE);

	int SetComment(const char* comment);

	int CloseFile(void);
	int AddFile(const char* fname, unsigned long ftime, unsigned long attr);
	int SetFileComment(const char* comment);
	int AddExtraField(unsigned short tag, const char* ldata, unsigned long lsize, const char* gdata, unsigned long gsize);

	int Write(const char* data, unsigned long nbytes);

protected:
	zipFile m_zf;

	char* m_globalcomment;

	int m_method;
	int m_level;

	zip_fileinfo m_currfile;
	char* m_filename;
	char* m_eflocal;
	unsigned long m_eflocalsize;
	char* m_efglobal;
	unsigned long m_efglobalsize;
	char* m_comment;

	enum _zip_status
	{
		zip_archive_error = -1,
		zip_archive_closed = 0,
		zip_archive_open,
		zip_archive_fileopen,
		zip_archive_filewrite
	};

	_zip_status m_status;

	int openfile(void);
	int closefile(void);
};

class UnzipArchive
{
public:
	~UnzipArchive();
	UnzipArchive();

	int Close(void);
	int Open(const char* fname);
	int Open(const wchar_t* fname);

	unsigned long GetCommentLength(void);
	int GetComment(char* comment, unsigned long bufsize);

	int FirstFile(void);
	int NextFile(void);

	enum CaseCompareType
	{
		DefaultCaseCompare = 0,
		CaseCompare = 1,
		NoCaseCompare = 2
	};

	int LocateFile(const char* fname, int casecmp);

	int OpenFile(void);
	int CloseFile(void);

	unsigned long GetFileNameLength(void);
	int GetFileName(char* fname, unsigned long bufsize);
	unsigned long GetFileTime(void);
	unsigned long GetFileAttributes(void);
	unsigned long GetFileCommentLength(void);
	int GetFileComment(char* comment, unsigned long bufsize);
	int GetExtraField(unsigned short tag, char* ldata, unsigned int lsize, char* gdata, unsigned int gsize);
	int GetExtraFieldLength(unsigned short tag, unsigned int *lsize, unsigned int *gsize);

	unsigned long GetCompressedSize(void);
	unsigned long GetUncompressedSize(void);

	int Read(char* data, unsigned long nbytes);

protected:
	unzFile m_zf;

	unz_global_info m_info;
	unz_file_info m_currfile;

	enum _unzip_status
	{
		unzip_archive_error = -1,
		unzip_archive_closed = 0,
		unzip_archive_open,
		unzip_archive_fileopen,
		unzip_archive_fileread
	};

	_unzip_status m_status;

	int loadfileinfo(void);
};

};

#endif
