//
//  BIPObject.h
//  BISubstrate
//
//  Created by Alykhan Jetha on 04/06/08.
//  Copyright 1999-2008 Marketcircle Inc. All rights reserved.
//

#import <MCFoundation/MCPGenericObject.h>
@class BIExtra;
@class MCFormattingAgent;
@class BIQueryHandler;
@class BIUser;
@class BIConnectorMap;

@interface BIPObject : MCPGenericObject {
}

- (void)willDeleteFromObjectContext:(MCPObjectContext *)objCtx;

- (id)createAndInsertRelatedObjectForEntityNamed:(NSString *)aName;
- (BOOL)hasRelationshipForKeyBeenFaulted:(NSString *)key;
- (void)setObject:(BIPObject *)anObject forRelationshipWithKey:(NSString *)key;
- (void)setObject:(BIPObject *)anObject forRelationshipWithKey:(NSString *)key KVONotifying:(BOOL)kvoFlag;


/*!
 Loose associations. Any object can have loosely associated objects. These objects are not retained in array like standard relationships. Instead, a query is made to the database for each call to extraObjects (or one of its variants).
 
 This object/concept was created as a safeguard for our BI/BP touch apps. In the event we need to add a feature to be competitive without having to do schema updates. You should use it sparringly. Use a proper relationship when possible.
 
 It is believe that performance won't be much of an issue since BI and BP run locally on SQLite.
 
 Returns nil if self is not persistent.

 */
- (NSArray *)extraObjects;
- (NSArray *)extraObjectsWithName:(NSString *)aName;
- (NSArray *)extraObjectsForMimeType:(NSString *)mime subtype:(NSString *)subtype name:(NSString *)aName;
- (NSArray *)extraObjectsForInternalType:(int)code name:(NSString *)aName;

/*!
 Special case for deletes
 */
- (NSArray *)extraObjectsUsingObjectContext:(MCPObjectContext *)oc;


/*!
 Sets the parentEntity and parentID on anExtra regardless of whether those values where set before. This makes it easy to move an extra from one parent object to another.
 
 To delete an extra, you delete like any other object using the ObjectContext. You don't have to remove it from a relationship since it a loose association anyways.
 
 Throws an exception if self is not persistent. Self must be persistent.
 
 */
- (void)addExtraObject:(BIExtra *)anExtra;

/*!
 Convenience for BIExtras. Names should be of type: <company>.field. For example: marketcircle.localeIdentifier.
 Reserved word: mc
 */
- (BIExtra *)singleExtraWithName:(NSString *)aName createIfNeeded:(BOOL)create;

- (BIExtra *)setString:(NSString *)aStr onExtraWithName:(NSString *)aUniqueNameForObject;
- (NSString *)stringForExtraWithName:(NSString *)aUniqueNameForObject;


- (BIExtra *)setDouble:(NSNumber *)aDbl onExtraWithName:(NSString *)aUniqueNameForObject;
- (NSNumber *)doubleForExtraWithName:(NSString *)aUniqueNameForObject;




/*!
 Third party integration objects. Any object can have connector maps. These objects are not retained in array like standard relationships. Instead, a query is made to the database for each call to connectorMaps (or one of its variants).
  
 Returns nil if self is not persistent.
 
 */
- (NSArray *)connectorMaps;
- (NSArray *)connectorMapsForForeignAppName:(NSString *)aName;
- (NSArray *)connectorMapsForForeignAppName:(NSString *)aName foreignEntity:(NSString *)aType;
- (NSArray *)connectorMapsForForeignAppName:(NSString *)aName foreignEntity:(NSString *)aType foreignID:(NSString *)aID;

/*!
 Calling this means you expect an object to have exactly zero or one connector map for that given foreign app name. If more are found, an exception is thrown.
 */
- (BIConnectorMap *)singleConnectorMapForForeignAppName:(NSString *)aName;
- (BIConnectorMap *)singleConnectorMapForForeignAppName:(NSString *)aName foreignEntity:(NSString *)aType;
- (BIConnectorMap *)singleConnectorMapForForeignAppName:(NSString *)aName 
										  foreignEntity:(NSString *)aType foreignID:(NSString *)aID;


/*!
 Sets the parentEntity and parentID on anExtra regardless of whether those values where set before.
 
 To delete an connectorMap, you delete like any other object using the ObjectContext. You don't have to remove it from a relationship since it a loose association anyways.
 
 Throws an exception if self is not persistent. Self must be persistent.
 
 */
- (void)addConnectorMap:(BIConnectorMap *)aMap;


/*!
 Special case for deletes
 */
- (NSArray *)connectorMapsUsingObjectContext:(MCPObjectContext *)oc;











- (MCFormattingAgent *)baseCurrencyFormatting;
- (MCFormattingAgent *)clientCurrencyFormatting;

- (NSNumberFormatter *)baseCurrencyFormatter;



/*!
 Convenience. Note: this stuff should just be on the objectContext.
 */
- (BIQueryHandler *)queryHandler;

/*!
 Convenience.
 */
- (BIUser *)currentUser;

#pragma mark - For Subclasses
- (BOOL)shouldIncludeModifyDateForChangedAttribute:(NSString *)attributeName;

@end
