//
//  BICreationContext.h
//  BISubstrate
//
//  Created by Eric Hochmeister on 16/08/06.
//  Copyright 2006 __MyCompanyName__. All rights reserved.
//
#import <MCFoundation/MCCreationContext.h>

@class MCPObjectContext, BIClient, BIUser, ABPerson, CNContact;
@class BIProject;
@class BITimeSlip;
@class BIEstimateSlip;
@class BIPayment;
@class BIPaymentMethodType;
@class BITax;
@class BIConsolidatedTax;
@class BITaxConsolidatedTaxEntry;
@class BIEstimateSlip;
@class BITimeSlip;
@class BISlipTemplate;
@class BITimeEntry;
@class BIPayment;
@class BIPaymentInvoiceEntry;
@class BIRetainer;
@class BICategory;
@class BITimeSlipType;
@class BIInvoice;
@class BIProFormaInvoice;
@class BIEstimate;
@class BIRecurringInvoice;
@class BIBEXIgnore;
@class BICurrency;
@class BIExtra;

#ifdef BILLINGS_PRO
@class BIProjectUser;
@class BIIdentity;
@class BIReportTemplate;
@class BIReportTemplatePreference;
@class BIFileStorage;
#endif


/*!
    @class       BICreationContext
    @abstract    Subclass of MCCreationContext which adds Billings specific functoinality, ie. the creation of Billings model objects, etc.
    @discussion  When creating objects of any Billings specific kind, create them by using the BICreationContext.  DO NOT create them on your own, always perform creation through the creation context.
 
                 Creation of objects always stems from one of these methods which are all variants of eachother.
 
 - (id)createObjectForEntityNamed: (NSString*)aName;
 
 - (id)createObjectForEntityNamed: (NSString*)aName addToObjectContext: (BOOL)flag;
 
 - (id)createObjectForEntityNamed: (NSString*)aName 
 addToObjectContext: (BOOL)flag
 postNotification: (BOOL)shouldNotif;
 
                 Ignore all methods found in the "Old Stuff" section of this header.  All of these things should be migrated to the new stuff if they have not been already.
 
                 The reason for not adding a new object to the object context is usually in the case of a create card, where the user may hit cancel.  Otherwise, you normally always want to add to the object context.
 
                 Posting a notification, is done by default, unless you specify otherwise.
 
                 Details on implementation...
 
                 The creation context is very dynamic.  Everything stems from the entity mappings dictionary.  The dictionary is setup in -_entityMappings, so if you are adding a new entity, just add a new entry to the dictionary in this method.  The entries of the dictionary should contain a creation method selector and a notification to fire once the object as been created.  Note, the notification is not required, but the creation selector is.
 
                 The creation selector is usually very basic, take a look at createTimeSlip for instance.  They are set in a way that you can do additional logic, although it is rarely the case that you need to.  The creation selector will call, modelCreateObjForEntityNamed: which will then do everything necessary to create an instance of the object for the Entity, and initialize it using a pattern we use which is the setInitialValuesWithObjectContext: call which should exist on the entity class (and it is only executed if it exists).
*/


@interface BICreationContext : MCCreationContext {
    
	//MCPObjectContext* _context;
    //NSDictionary* _createEntitySelectorMappings;
	NSDictionary* _entityMappings;
}

/*
- (id)initWithObjectContext:(MCPObjectContext*)context;

- (MCPObjectContext*)objectContext;
- (void)setObjectContext:(MCPObjectContext*)context;
*/

- (BIClient*)createClientWithABPerson:(ABPerson*)anABPerson;

/**
 Create a new BIClient by importing data from a CNContact.
 
 This is the modern replacement for -createClientWithABPerson: using the Contacts framework.
 Creates a new client, inserts it into the object context, and imports contact data.
 
 @param contact The CNContact to import data from. Must not be nil.
 @return A newly created BIClient with imported contact data.
 
 @note This is import-only. No link or sync relationship is created.
 */
- (BIClient*)createClientFromContact:(CNContact*)contact;

- (BIProject *)createProjectForClient:(BIClient*)aClient;

- (BITimeSlip*)createTimedTimeSlipWithDefaultValues;

- (BIEstimateSlip*)createEstimateSlipWithDefaultValues;

- (BITimeSlip*)createRealTimeSlipFromTimeSlip:(BIEstimateSlip*)aTimeSlip;

- (BIPayment*)createNewPaymentNotInObjectContext;

- (BIProject*)createProjectForClient:(BIClient*)aClient name:(NSString*)aName;
- (BIProject*)createLooseSlipsProjectForClient:(BIClient*)aClient DEPRECATED_IN_MAC_OS_X_VERSION_10_6_AND_LATER;

- (BIClient*)createClientWithFirstname:(NSString*)fname
                              lastname:(NSString*)lname
                                 email:(NSString*)emailAddr
                               company:(NSString*)company;

- (id)createObjectForEntityNamed: (NSString*)aName;
- (id)createObjectForEntityNamed: (NSString*)aName addToObjectContext: (BOOL)flag;
- (id)createObjectForEntityNamed: (NSString*)aName 
              addToObjectContext: (BOOL)flag
                postNotification: (BOOL)shouldNotif;
- (id)createImportObjectForEntityNamed: (NSString*)aName addToObjectContext:(BOOL)flag;


- (id)modelCreateObjForEntityNamed:(NSString*)entityName setInitialValues:(BOOL)flag;
- (id)modelCreateObjForEntityNamed:(NSString*)entityName;

- (BIClient *)createClient;
- (BIProject*)createProject;
- (BITax*)createTax;
- (BIConsolidatedTax*)createConsolidatedTax;
- (BITaxConsolidatedTaxEntry*)createTaxConsolidatedTaxEntry;

- (BISlipTemplate*)createSlipTemplate;
- (BITimeEntry*)createTimeEntry;
- (BITimeSlip*)createTimeSlip;
- (BIEstimateSlip*)createEstimateSlip;
- (BIPayment*)createPayment;
- (BIPaymentInvoiceEntry*)createPaymentInvoiceEntry;
- (BIRetainer*)createRetainer;
- (BICategory*)createCategory;
- (BITimeSlipType*)createTimeSlipType;

- (BIEstimate*)createEstimate;
- (BIInvoice*)createInvoice;
- (BIRecurringInvoice*)createRecurringInvoice;
- (BIUser*)createUser;

- (BIBEXIgnore*)createBEXIgnore;

- (BIBEXIgnore*)createBEXIgnoreObjectWithForeignAppName:(NSString*)appName
                                   foreignAppEntityName:(NSString*)entityName
                                     foreignAppImportID:(NSString*)importID;

// returns a newly created pro-forma object with all the pertinent details from this invoice. Convenience because when creating a real pro forma invoice, we use an invoice object, caller must insert into object context if intend to save
- (BIProFormaInvoice*)createProFormaInvoiceFromInvoice:(BIInvoice*)anInvoice;

- (BICurrency *)createCurrency;
- (BIExtra *)createExtra;


#ifdef BILLINGS_PRO
- (BIProjectUser *)createProjectUser;
- (BIIdentity *)createIdentity;
- (BIReportTemplate *)createReportTemplateStorage;
- (BIReportTemplatePreference *)createReportTemplatePreference;
- (BIFileStorage *)createFileStorage;
#endif

@end
