//
//  MCSyncManager.h
//  GWSyncServices
//
//  Created by Michael Clark on 20/12/06.
//  Copyright 2006 Marketcircle Inc. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "MCSyncWorker.h"
#import "MCSyncWorkerProtocol.h"
#import "MCSyncManagerProtocol.h"

@class MCSyncConfig;
@class ISyncClient;
@class MCPObjectContext;
@class MCFileLogger;
@class MCSyncAbstractObjectProcessor;


@interface MCSyncManager : NSObject <MCSyncManagerProtocol> {

	@private
	
	NSString*                     __documentIdentifier;
	NSDictionary*                 __userSyncConfig;
	
	MCPObjectContext*             __objectContext; // Not retained!
	
	MCSyncConfig*                 __syncConfig;
	
	id <MCSyncWorkerProtocol>     __syncWorkerProxy;
	BOOL                          __isSetup;
	ISyncClient*                  __syncClient;
	
	MCFileLogger*                 __logger; // Only valid once a sync operation begins and invalid when it ends
	NSMutableDictionary*          __queuedChangeCache; // Only valid once a sync operation begins and invalid when it ends
	BOOL                          __syncPending;
	BOOL                          __isSyncing;
	BOOL                          __isTrickleDisabled;
	BOOL                          __isBlocking;
	
	NSString*                     __clientSyncIdentifier;
	
	NSMutableDictionary*          __objectProcessors;
	NSMutableDictionary*          __newObjectCache;  // passed into the object processors so they can try to find newly created objects
	NSMutableDictionary*          __deletedObjectCache; // passed into the object processors so they can try to find newly created objects

	id                            __syncUIDelegate;
	id                            __syncFailureDelegate;
}

+ (void)setSyncWorkerClass: (Class)aClass;
	// Can be used to override the default class for the sync worker which is MCSyncWorker - if you subclass MCSyncWorker then you must tell the SyncManager this by calling this method

+ (BOOL)syncingEnabledForLocalMachine; // this is set by the user in the iSync preferences

+ (void)markActiveSyncThreadState;
+ (void)markInactiveSyncThreadState;
+ (BOOL)hasActiveSyncThread;

- (id)initWithObjectContext: (MCPObjectContext*)context documentIdentifier: (NSString*)identifier;

- (void)setupSyncEnvironment;
- (void)shutdownSyncEnvironment;
- (BOOL)isSyncEnvironmentSetup;

- (void)toggleTrickleSyncingEnabled;
- (void)disableTrickleSyncing;
- (void)enableTrickleSyncing;

- (BOOL)isSyncing;
- (void)performSyncForEntityGroups: (NSArray*)entityGroupIdentifiers modalDelegate: (id)delegate isBlockingSync: (BOOL)isBlocking;
	// Used to start a sync process.  
	//   entityGroupIdentifiers can be nil, in which case the engine will determine which groups to sync
	//   delegate can be nil, in which case no one will be called directly to be told that the sync has finished
	//   if isBlocking is YES then the entire sync will happen on the sync thread and it will be up to the caller to make sure the UI gets updated after the sync
	//     if isBlocking is NO then part of the sync processing will happen on the main thread in order to update the UI
- (void)timedPerformSync; // calls the above method with nil, nil and NO as arguments

#pragma mark SyncClient Key/Values
- (NSString*)clientSyncIdentifier;
- (NSCalendarDate*)clientLastSyncDate;
- (void)recordClientLastSyncDate;

#pragma mark Object Processors
- (MCSyncAbstractObjectProcessor*)objectProcessorForClassName: (NSString*)className;


#pragma mark Accessors
- (NSString *)documentIdentifier;
- (void)setDocumentIdentifier:(NSString *)aDocumentIdentifier;
- (NSDictionary *)userSyncConfig;
- (void)setUserSyncConfig:(NSDictionary *)anUserSyncConfig;
- (MCSyncConfig*)syncConfig;

- (void)setSyncFailureDelegate:(id)anObject; // anObject must respond to -syncFailed
- (id)syncFailureDelegate;

#pragma mark Debug Logic
- (void)testDOConnection;


#pragma mark Subclassers
- (NSString*)clientIdentifier;
	// This method should return the unique iSync client identifier for this instance - i.e. take the document identifier into account

- (NSString*)clientDescriptionFilename;
	// Returns the name of the client description plist without the .plist extension

- (NSString*)applicationSyncConfigPath;
    // Returns the path to the application sync configuration file

// END -  For subclassers

@end


@interface NSObject (MCSyncUIDelegate)

- (void)syncCompleted: (BOOL)flag;

@end

@interface NSObject (MCSyncFailureDelegate)
//- (void)syncFailedWithException:(id)exception;
- (void)syncFailedWithExceptionReason: (NSString*)exceptionReason;
@end
