
#include "common.h"
#include "unzip.h"

#define MAX_FILE_HANDLES    64
#define MAX_ZPATH           256

typedef union qfile_gus {
	FILE*       o;
	unzFile z;
} qfile_gut;

typedef struct qfile_us {
	qfile_gut file;
	qboolean unique;
} qfile_ut;

typedef struct {
	qfile_ut handleFiles;
	qboolean handleSync;
	int baseOffset;
	int fileSize;
	int zipFilePos;
	qboolean zipFile;
	qboolean streamed;
	char name[MAX_ZPATH];
} fileHandleData_t;

static int fs_readCount;                    // total bytes read
static fileHandleData_t fsh[MAX_FILE_HANDLES];

int FS_Read( void *buffer, int len, fileHandle_t f ) {
	int block, remaining;
	int read;
	byte    *buf;
	int tries;

	//if ( !fs_searchpaths ) {
	//	Com_Error( ERR_FATAL, "Filesystem call made without initialization\n" );
	//}

	if ( !f ) {
		return 0;
	}

	buf = (byte *)buffer;
	fs_readCount += len;

	if ( fsh[f].zipFile == qfalse ) {
		remaining = len;
		tries = 0;
		while ( remaining ) {
			block = remaining;
			read = fread( buf, 1, block, fsh[f].handleFiles.file.o );
			if ( read == 0 ) {
				// we might have been trying to read from a CD, which
				// sometimes returns a 0 read on windows
				if ( !tries ) {
					tries = 1;
				} else {
					return len - remaining;   //Com_Error (ERR_FATAL, "FS_Read: 0 bytes read");
				}
			}

			if ( read == -1 ) {
				Com_Error( ERR_FATAL, "FS_Read: -1 bytes read" );
			}

			remaining -= read;
			buf += read;
		}
		return len;
	} else {
		return unzReadCurrentFile( fsh[f].handleFiles.file.z, buffer, len );
	}
}