//
//  MCStageSyncUpdate.h
//  MCStageSync
//
//  Created by Mark Onyschuk on 28/04/08.
//  Copyright 2008 Marketcircle, Inc.. All rights reserved.
//


#import "MCStageSyncOperation.h"
#import "MCExportRule.h"

//#import <GWSubstrate/GWPObject.h>

#import <MCFoundation/MCPEntity.h>
#import <MCFoundation/MCPObject.h>


@class MCStageSyncDaemon, MCStageChangeManager, MCClientStage, MCChangeSet;
@class MCPDatabaseObjectContext;
@class MCSQLiteContext;
@class MCPDatabaseConnection;
@class MCChangeRecord;

@interface MCStageSyncUpdate : MCStageSyncOperation {
	
	// Weakly referenced collaborative objects
	MCPDatabaseConnection         *mainConn;
	MCPDatabaseObjectContext      *mainContext;
	MCPModel                      *mainModel;
	MCSQLiteContext               *touchContext;
	MCPModel                      *touchModel;
	MCStageChangeManager          *changeManager;
	
	NSMutableDictionary *initialCandidates;
	NSMutableDictionary *relatedCandidates;
	NSMutableDictionary *relatedRemovals;
	
	NSMutableDictionary *primaryAccepts;
	NSMutableDictionary *rejectedObjects;
	NSMutableDictionary *deletedObjects;
	NSMutableDictionary *changedHistories;

	BOOL processInitialCandidates;
	BOOL supportsPlayingDead;
}

- (id)run;

// Subclass methods
- (BOOL)userIsInterestedInObject:(MCPObject *)object;
- (BOOL)treatObjectAsDeleted:(MCPObject *)object;

@end

@interface MCStageSyncUpdate (Private)
- (BOOL)exportServerChangesIntoChangeSet:(MCChangeSet *)changeSet error:(NSError **)error;
- (BOOL)exportServerChangeSet:(NSError **)error;


- (void)addInitialCandidate:(MCPObject *)object timeStamp:(NSDate *)timeStamp;
- (void)addInitialCandidates:(NSArray *)objects timeStamp:(NSDate *)timeStamp;
- (void)addRelatedCandidate:(MCPObject *)object timeStamp:(NSDate *)timeStamp;
- (void)addRelatedCandidates:(NSArray *)objects timeStamp:(NSDate *)timeStamp;

- (void)markRelatedObjectsForRemoval:(NSArray *)objects;
- (void)markRelatedObjectForRemoval:(MCPObject *)object;
- (void)markObjectsHistoryAsChanged:(NSArray *)objects;
- (void)markObjectHistoryAsChanged:(MCPObject *)object;

- (void)acceptObject:(MCPObject *)object;
- (void)rejectObject:(MCPObject *)object;
- (void)addDeletedPrimaryKey:(id)pKey forEntityNamed:(NSString *)entityName timeStamp:(NSDate *)timeStamp;

- (BOOL)previouslyConsideredObject:(MCPObject *)object;
- (BOOL)previouslyAcceptedObject:(MCPObject *)object;
- (BOOL)previouslyRejectedObject:(MCPObject *)object;
- (BOOL)objectIsMarkedForRemoval:(MCPObject *)object;

- (void)removeCandidate:(MCPObject *)object;

- (void)filterRelatedCandidatesForEntity:(MCPEntity *)entity;

- (NSArray *)changeLogsForTableID:(NSNumber *)tableID;
- (MCChangeRecord *)changeRecordForObjectWithOldState:(NSDictionary *)old
											 newState:(NSDictionary *)new
entityName:(NSString *)entityName
timeStamp:(NSDate *)timestamp;

- (BOOL)doesObject:(MCPGenericObject *)object satisfyRule:(MCExportRule *)rule;
- (NSArray *)changesForRule:(MCExportRule *)rule;
- (NSMutableArray *)changesForRules;

- (BOOL)shouldExportJoinObject:(MCPGenericObject *)join shouldDelete:(BOOL *)doDelete;
- (NSArray *)changesForJoinEntityName:(NSString *)joinName;
- (NSArray *)changesForJoins;

- (void)addRelatedTrashRecordsToChangeSet:(MCChangeSet *)changeSet;

- (void)findInitialCandidates;
- (void)findRelatedCandidatesForRule:(MCExportRule *)rule;
- (void)findRelatedCandidates;
- (void)findJoinCandidates;

@end


@interface MCPEntity (MCRelationshipTraveling)

- (NSString *)inversePathForRelationshipKeyPath:(NSString *)keyPath;

@end

@interface MCPObject (MCRelationshipTraveling)

- (NSString *)inversePathForRelationshipKeyPath:(NSString *)keyPath;

@end
