namespace Core::Zip

namespace Zip {

// enums

enum CompressionMethod;
enum ExtraFieldIdentifiers;
enum GeneralPurposeFlags;

// structs

struct CentralDirEndRecord;
struct CentralDirEndRecord64;
struct CentralDirEndRecordLocator64;
struct CentralDirFileHeader;
struct ExtraField;
struct ExtraFieldZip64;
struct LocalFileHeader;

// global variables

static const int kZipByteOrder = CORE_LITTLE_ENDIAN;
static const uint32 kCentralDirEndRecordSize = 22;
static const uint32 kCentralDirEndSignature = 0x06054b50;
static const uint32 kCentralDirEnd64Size = 56;
static const uint32 kCentralDirEnd64Signature = 0x06064b50;
static const uint32 CentralDirEndRecordLocator64Size = 20;
static const uint32 CentralDirEndRecordLocator64Signature = 0x07064b50;
static const uint32 kCentralDirFileHeaderSize = 46;
static const uint32 kCentralDirFileHeaderSignature = 0x02014b50;
static const uint32 kExtraFieldPrologSize = 4;
static const uint32 kExtraFieldZip64DataSize = 28;
static const uint32 kLocalFileHeaderSize = 30;
static const uint32 kLocalFileHeaderSignature = 0x04034b50;

// global functions

bool findCentralDirectoryEnd(CentralDirEndRecord& result, IO::Stream& stream);
bool findZip64Locator(CentralDirEndRecordLocator64& result, IO::Stream& stream);
bool isCompressionSupported(uint16 method);
void getDate(Date& date, uint16 zipDate);
void setDate(uint16& zipDate, const Date& date);
void getTime(Time& time, uint16 zipTime);
void setTime(uint16& zipTime, const Time& time);
void getDateTime(DateTime& dateTime, uint16 zipDate, uint16 zipTime);
void adjustDateTime(DateTime& dateTime);

template <class Record, const uint32 kSignature, const uint32 kChunkSize>
bool findRecord(
    Record& result,
    IO::Stream& stream
);

} // namespace Zip