//
//  MCAlertManager.h
//  MCFoundation
//
//  Created by Michael Clark on 07/09/2005.
//  Copyright 2005 Marketcircle Inc. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "MCAlertDefines.h"

// The alert mechanism is a way to send user centric alerts around a multi user system
//  In DayLite we use this mechanism to implement the Notification Center
// The AlertManager is the gateway into this mechanism.  He is responsible for
//  quering the data store for pending, unseen alerts, and sending out an NSNotification
//  to interested parties to alert the user.
//  The AlertManager is also responsible for creating new alerts and saving them to the data store.
//    He uses an Entity name to instantiate an instance of the proper class for the application
//    using this mechanism.  By default the entity is called AlertObject.


// Posted when MCAlertManager finds unseen alerts
extern NSString*       MCNewAlertsNotification;
extern NSString*       MCRemoveAlertsNotification;

// Keys in the MCNewAlertsNotification userInfo dictionary
extern NSString*       MCAlertsKey;
extern NSString*       MCObjectContextKey; // Used for document uniquing

// Alert General Settings (all alerts adhere to these settings)
extern NSString*       MCAlertSettingsShouldOpenNotificationWindow;
extern NSString*       MCAlertSettingsShouldBounceDockIcon;
extern NSString*       MCAlertSettingsBounceDockType;

// Alert Specific Settings Keys (on a per alert basis)
extern NSString*       MCAlertSettingsShouldPlaySound;    // Should we play a sound?
extern NSString*       MCAlertSettingsPlaySoundName;      // If above is true, play the sound with this name
extern NSString*       MCAlertSettingsShouldSendEmail;    // Should we send an email?
extern NSString*       MCAlertSettingsSendEmailToAddress; // If above is true, send to this address
extern NSString*       MCAlertSettingsShouldShowNote;     // Should we show a note?
extern NSString*       MCAlertSettingsShowNoteContent;    // If above is true, display a note with this content
extern NSString*       MCAlertSettingsShouldSpeakText;    // Should we speak some text?
extern NSString*       MCAlertSettingsSpeakTextContent;   // If above is true, speak this text
extern NSString*       MCAlertSettingsShouldOpenFile;     // Should we open a file?
extern NSString*       MCAlertSettingsOpenFileName;       // If above true, open file at this path
extern NSString*       MCAlertSettingsShouldRunScript;    // Should we run a script?
extern NSString*       MCAlertSettingsRunScriptName;      // If above true, run script at this path

extern NSString*       MCAlertSettingsProxyObject;

@class MCPDatabaseObjectContext;
@class BDQualifier;
@protocol MCAlertObjectProtocol, MCPUserProtocol, MCAlertableObjectProtocol;


@interface MCAlertManager : NSObject {
	@private
	MCPDatabaseObjectContext*     __objectContext;
	
	NSTimer*                      __queryTimer;
	BDQualifier*                  __unseenAlertQualifier;
	BDQualifier*                  __allAlertQualifier;
}

+ (void)setDefaultAlertObjectEntityName: (NSString*)anEntityName;

- (id)initWithObjectContext: (MCPDatabaseObjectContext*)anObjectContext;

// Creates an alert with the relevant information passed in
//  If this alert is for the user hanging off of the object context it will be sent out right away
// Main method - the other two are wrappers
- (NSArray*)alertUser: (id <MCPUserProtocol>)receivingUser 
		 aboutObjects: (NSArray*)objects
			 fromUser: (id <MCPUserProtocol>)sendingUser 
		  withMessage: (NSString*)aMessage 
			  forType: (MCAlertType)type 
			 userInfo: (NSDictionary*)aUserInfo
		recycleAlerts: (BOOL)recycleFlag;

- (NSArray*)alertUser: (id <MCPUserProtocol>)receivingUser 
		 aboutObjects: (NSArray*)objects 
			 fromUser: (id <MCPUserProtocol>)sendingUser 
		  withMessage: (NSString*)aMessage 
			  forType: (MCAlertType)type 
			 userInfo: (NSDictionary*)aUserInfo
		recycleAlerts: (BOOL)recycleFlag;


- (id <MCAlertObjectProtocol>)alertForUser: (id <MCPUserProtocol>)user aboutObject: (id <MCAlertableObjectProtocol>)object ofAlertType: (MCAlertType)type;

- (id <MCAlertObjectProtocol>)alertUser: (id <MCPUserProtocol>)receivingUser 
							aboutObject: (id <MCAlertableObjectProtocol>)anObject 
							   fromUser: (id <MCPUserProtocol>)sendingUser 
							withMessage: (NSString*)aMessage 
								forType: (MCAlertType)type;
- (id <MCAlertObjectProtocol>)alertUser: (id <MCPUserProtocol>)receivingUser 
							aboutObject: (id <MCAlertableObjectProtocol>)anObject 
							   fromUser: (id <MCPUserProtocol>)sendingUser 
							withMessage: (NSString*)aMessage 
								forType: (MCAlertType)type 
							   userInfo: (NSDictionary*)aUserInfo;

- (id <MCAlertObjectProtocol>)alertUser: (id <MCPUserProtocol>)receivingUser
						   aboutChanges: (NSDictionary*)changes
							   toObject: (id <MCAlertableObjectProtocol>)anObject
								 byUser: (id <MCPUserProtocol>)changingUser
							withMessage: (NSString*)aMessage
								forType: (MCAlertType)type;

- (id <MCAlertObjectProtocol>)alertUser: (id <MCPUserProtocol>)receivingUser
						   aboutChanges: (NSDictionary*)changes
							   toObject: (id <MCAlertableObjectProtocol>)anObject
								 byUser: (id <MCPUserProtocol>)changingUser
							withMessage: (NSString*)aMessage
								forType: (MCAlertType)type
							   userInfo: (NSDictionary*)aUserInfo;

- (void)dismissAlerts: (NSArray*)alerts;

- (MCPDatabaseObjectContext*)objectContext;

// The qualifier used for fetching unseen alerts for the user hanging off the object context
//  Created by default to be receivingUser = objectContext.user && isShown = 0
//  But it can be tweaked.  It will fetch against the Entity named as the defaultAlertObjectEntityName
- (BDQualifier *)unseenAlertQualifier;
- (void)setUnseenAlertQualifier:(BDQualifier *)anUnseenAlertQualifier;
- (BDQualifier *)allAlertQualifier;
- (void)setAllAlertQualifier:(BDQualifier *)anAllAlertQualifier;

- (void)_stopQueryTimer;
- (void)_startQueryTimer;
- (NSArray *)_fetchUnseenAlerts;
- (void)_fetchAllAndNotify;
@end
