//
//  MCZlibStreamProcessor.h
//  SyncClient
//
//  Created by Patrick Rogers on 27/03/08.
//  Copyright 2008 Marketcircle, Inc. All rights reserved.
//

#import <Foundation/Foundation.h>

typedef struct z_stream_s z_stream;
@class MCZlibStreamProcessor;

extern NSString *MCZlibErrorDomain;
extern NSString *MCZlibStreamProcessorErrorDomain;
typedef enum {
	MCZlibStreamProcessorInternalError,
} MCZlibStreamProcessorErrors;

extern NSString *MCZlibStreamProcessorOperationBeginNotifcation;
extern NSString *MCZlibStreamProcessorProgressUpdateNotifcation;
extern NSString *MCZlibStreamProcessorOperationCancelledNotifcation;
extern NSString *MCZlibStreamProcessorOperationEndNotifcation;

extern NSString *MCZlibStreamProcessorProgressValueKey;
extern NSString *MCZlibStreamProcessorIsInflateValueKey;
extern NSString *MCZlibStreamProcessorProcessedBytesValueKey;
extern NSString *MCZlibStreamProcessorExpectedBytesValueKey;

@interface NSObject (MCZlibStreamProcessorDelegateEventExtensions)
- (void)willFinishProcessing:(MCZlibStreamProcessor *)processor;
- (void)didFinishProcessing:(MCZlibStreamProcessor *)processor;
- (void)streamProcessingError:(MCZlibStreamProcessor *)processor error:(NSError *)error;
@end

#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
@interface MCZlibStreamProcessor : NSObject
#else
@interface MCZlibStreamProcessor : NSObject <NSStreamDelegate>
#endif
{
	NSInputStream  *inputStream;
	NSOutputStream *outputStream;
	
	BOOL           inflateStream;
	
	NSObject       *delegate;
	
	unsigned int   inputBufferSize;
	unsigned int   bytesInInputBuffer;
	
	unsigned int   outputBufferSize;
	unsigned int   bytesInOutputBuffer;
	unsigned int   outputBufferWriteOffset;
	unsigned int   outputBufferGrowFactor;
	
	unsigned int   outputLimit;
	unsigned int   inputLimit;
	
	unsigned long long expectedInputBytes;
	
	BOOL           outputStreamWaitingForBytes;
	BOOL           inputStreamHasBytes;
	
	BOOL           finishedProcessingPackets;
	BOOL           didSendFinalNotification;
	
	uint8_t        *inputBuffer;
	uint8_t        *outputBuffer;
	
	z_stream       *zStream;
}

#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
- (NSInputStream *)inputStream;
- (void)setInputStream:(NSInputStream *)anInputStream;
- (NSOutputStream *)outputStream;
- (void)setOutputStream:(NSOutputStream *)anOutputStream;
- (BOOL)inflateStream;
- (void)setInflateStream:(BOOL)flag;
- (NSObject *)delegate;
- (void)setDelegate:(NSObject *)aDelegate;

- (unsigned int)outputLimit;
- (void)setOutputLimit:(unsigned int)anOutputLimit;
- (unsigned int)inputLimit;
- (void)setInputLimit:(unsigned int)anInputLimit;
- (unsigned long long)expectedInputBytes;
- (void)setExpectedInputBytes:(unsigned long long)anExpectedInputBytes;
#else
@property (nonatomic, retain) NSObject *delegate;
@property (nonatomic, retain) NSInputStream  *inputStream;
@property (nonatomic, retain) NSOutputStream *outputStream;
@property (nonatomic, readonly) BOOL inflateStream;
@property (nonatomic) unsigned int outputLimit;    // Will stop processing if exceeded
@property (nonatomic) unsigned int inputLimit;     // Will stop processing if exceeded
@property (nonatomic) unsigned long long expectedInputBytes;     // A hint used when sending progress notifications
#endif

+ (MCZlibStreamProcessor *)inflater;
+ (MCZlibStreamProcessor *)deflater;
+ (MCZlibStreamProcessor *)zlibStreamToInflateFile:(NSString *)inputPath toFile:(NSString *)outputPath;
+ (MCZlibStreamProcessor *)zlibStreamToDeflateFile:(NSString *)inputPath toFile:(NSString *)outputPath;

- (id)initForInflationWithInputBufferSize:(unsigned int)inputBufferSizeInit outputBufferSize:(unsigned int)outputBufferSizeInit;
- (id)initForDeflationWithInputBufferSize:(unsigned int)inputBufferSizeInit outputBufferSize:(unsigned int)outputBufferSizeInit;
- (id)initForInflation;
- (id)initForDeflation;
@end
