//
//  MSCommandsManager.h
//  MSCommandsManager
//
//  Created by Paul Herzog on 19-Jul-2007.
//  Copyright 2007 MacSpeech, Inc. All rights reserved.
//

#import <Cocoa/Cocoa.h>

#import "ActionMO.h"
#import "CommandMO.h"
#import "LocationMO.h"
#import "TriggerMO.h"
#import "MSCommandContext.h"
#import "MSCommandGroup.h"
#import "MSLocale.h"
#import "BookmarkAlias.h"
#import "BDAliasStringTransformer.h"
#import "GeneralTermMO.h"
#import "SpecificTermMO.h"
#import "EnhancedTrigger.h"
#import "TriggerPhrase.h"
//#import "MSCommandsManager+DynamicTrigger.h"
//#import "MSCommandsManager+Groups.h"


@class MSSystemMonitor;
@class MSStoreLoader;
@class WebContext;
@class PFApplicationUIElement;
@class PFUIElement;
@class PFObserver;

// Types of generated commands
typedef enum {
   kMSGeneratedCommandTypeApplication, 
   kMSGeneratedCommandTypeBookmark, 
   kMSGeneratedCommandTypeWorkflow
} MSGeneratedCommandType;


#pragma mark

@interface MSCommandsManager : NSObject {
   NSManagedObjectContext *workMoc;
   NSManagedObjectContext *workMoc2;
   NSManagedObjectContext *originalMoc;
   NSManagedObjectContext *dynamicTriggerMoc;
   NSManagedObjectContext *infoDataMoc;
   NSPersistentStore *dynamicDataUserStore;
	
   id inMemoryStore;
   
   NSMutableDictionary *roStoreLoaders;
   MSStoreLoader *userStoreLoader;
   MSSystemMonitor *storeMonitor;
   NSSet *vendors;
   NSSet *appBundles;
   
   NSManagedObjectContext *bookmarkContext;
   NSDictionary *commandGroupTemplates;
   
   NSString *currentSpokenLanguage;
   NSString *currentOsLanguage;
   NSString *altLanguage;
   
   NSMutableDictionary *commandTrackerDictionary;

   NSString *activeAppBundleID;
   NSString *activeAppName;
   NSString *activeAppShortVersion;
   NSInteger activeAppMajorVersion;
   MSLocale *currentLocale;

   NSArray *currentGroups;
   NSUInteger groupCount;
   MSCommandContext *currentContext;
	NSArray *availableCommands;
	NSUInteger availableCommandsCount;
	
	NSMutableDictionary *usageNotes;
  NSMetadataQuery *bookmarkQuery;
    
	NSString *synImagePath;
	NSString *altImagePath;
	NSString *dctImagePath;
	
    NSFont *triggerTextFont;
    NSFont *triggerAlternativeFont;
    NSFont *triggerSynonymFont;
    NSFont *triggerOptionalSynonymFont;
    NSFont *triggerSpeechFont;
 
    WebContext *webContext;
    
    PFApplicationUIElement *observedApp;
    PFUIElement *observedElement;
    PFObserver *observer;
    
    NSLock *notifyCallbackLock;
    //NSMutableArray *callbacks;
}
@property(retain) NSString *synImagePath;
@property(retain) NSString *altImagePath;
@property(retain) NSString *dctImagePath;
@property(retain) NSFont *triggerTextFont;
@property(retain) NSFont *triggerAlternativeFont;
@property(retain) NSFont *triggerSynonymFont;
@property(retain) NSFont *triggerOptionalSynonymFont;
@property(retain) NSFont *triggerSpeechFont;
@property(retain) NSPersistentStore *dynamicDataUserStore;

#pragma mark Initialization
+ (MSCommandsManager *)sharedManager;
+ (MSCommandsManager *)sharedManagerWithoutInit;
- (void)setupDynamicTriggerMoc;
- (void)setupInfoDataMoc;
- (void)reset;
- (BOOL)isUsingModel2;
- (void)migrateROStoresToModel2;
- (NSArray *)migrateCommands:(NSArray *)commands fromPath:(NSString *)path intoContext:(NSManagedObjectContext *)moc;
- (void)setupWebContext;

#pragma mark -
#pragma mark Action Methods
- (void)refreshVendorAndBundleLists;
- (void)refreshAllCommands;
- (void)refreshCurrentCommandActions;
- (void)refreshCurrentCommandTriggers;
- (void)refreshCurrentGroups;
- (void)refreshCurrentContext;
- (CommandMO *)addUserCommand:(NSDictionary *)commandInfo;
- (CommandMO *)addCommand:(NSDictionary *)commandInfo toStore:(id)store managedObjectContext:(NSManagedObjectContext *)moc;

//- (CommandMO *)addUserCommandNamed:(NSString *)name type:(NSString *)type description:(NSString *)description data:(NSData *)data text:(NSString *)text;
- (CommandMO *)addTemporaryCommandNamed:(NSString *)name withKey:(NSString *)key;
- (void)removeTemporaryCommandKey:(NSString *)commandKey;
- (CommandMO *)temporaryCommandForCommandKey:(NSString *)commandKey;
- (void)modifyCommand:(CommandMO *)command;
- (void)removeCommand:(CommandMO *)command;
- (void)removeCommands:(NSArray *)commands;
- (BOOL)saveUserCommands:(NSError **)error;
- (BOOL)save:(NSError **)error andReset:(BOOL)reset;
- (void)setVisibility:(BOOL)visibility forAllCommandsWithKey:(NSString *)key;
- (void)deleteHiddenCommandsForApplication:(MSApplicationInfo *)applicationInformation;
- (void)prepareForCommandExecution;


#pragma mark -
#pragma mark Command Loading and Unloading
- (BOOL)reloadUserCommands;
- (BOOL)loadUserCommandsAtPath:(NSString *)commandPath ofType:(NSString *)storeType;
- (NSInteger)loadCommandsAtPath:(NSString *)commandPath ofType:(NSString *)storeType;
- (NSInteger)loadCommandsAtPath:(NSString *)commandPath ofType:(NSString *)storeType recursive:(BOOL)recursive;
- (BOOL)unloadUserCommandsAtPath:(NSString *)commandPath ofType:(NSString *)storeType;
- (NSInteger)unloadCommandsAtPath:(NSString *)commandPath persist:(BOOL)persist;
- (NSInteger)unloadCommandsAtPath:(NSString *)commandPath persist:(BOOL)persist recursive:(BOOL)recursive;
- (BOOL)loadGeneratedCommandsOfType:(MSGeneratedCommandType)commandType;
- (void)unloadGeneratedCommandsOfType:(MSGeneratedCommandType)commandType;
- (void)persistAllROStoresWithReload:(BOOL)reload;
- (NSArray *)loadedStores;
- (NSDictionary *)infoForStorePath:(NSString *)storePath;
- (NSArray *)launchableApplications;

#pragma mark -
#pragma mark Loading Dynamic Data
- (NSInteger)loadDynamicDataAtPath:(NSString *)dynamicDataPath ofType:(NSString *)storeType recursive:(BOOL)recursive;

#pragma mark -
#pragma mark Loading Info
- (NSInteger)loadInfoDataAtPath:(NSString *)infoPath ofType:(NSString *)storeType recursive:(BOOL)recursive;

#pragma mark -
#pragma mark Usage Notes
- (void)addUsageNoteNamed:(NSString *)noteName withKey:(NSString *)usageKey description:(NSString *)usageDesc notes:(NSArray *)notes;
- (void)addUsageNoteNamed:(NSString *)noteName withKey:(NSString *)usageKey description:(NSString *)usageDesc notes:(NSArray *)notes target:(NSObject *)target;
- (void)removeUsageNoteWithKey:(NSString *)usageKey;
- (NSArray *)sortedUsageNoteKeys;
- (MSCommandGroup *)usageNoteForKey:(NSString *)usageKey;

#pragma mark -
#pragma mark Command Importing
- (NSArray *)importUserCommands:(NSArray *)commands error:(NSError **)error;
- (BOOL)importUserStoreAtPath:(NSString *)storePath storeType:(NSString *)storeType;
- (BOOL)importUserDynamicDataAtPath:(NSString *)storePath storeType:(NSString *)storeType;

#pragma mark -
#pragma mark Process Monitoring
- (BOOL)addMonitorForProcessID:(NSInteger)processID named:(NSString *)processName;
- (void)removeMonitorForProcessID:(NSInteger)processID;

#pragma mark -
#pragma mark Accessors
+ (NSString *)defaultStoreType;
- (NSManagedObjectContext *)managedObjectContext;
- (NSManagedObjectContext *)infoDataMoc;
- (NSSet *)vendors;
- (NSSet *)appBundles;
- (NSString *)currentSpokenLanguage;
- (void)setCurrentSpokenLanguage:(NSString *)spokenLanguage;
- (NSString *)currentOsLanguage;
- (void)setCurrentOsLanguage:(NSString *)osLanguage;
- (NSString *)altLanguage;
- (void)setAltLanguage:(NSString *)language;
- (MSLocale *)currentLocale;
- (MSCommandContext *)currentContext;
- (void)setCurrentContext:(MSCommandContext *)context;
- (NSArray *)currentGroups;
- (void)setCurrentGroups:(NSArray *)groups;
- (NSUInteger)groupCount;
- (NSArray *)availableCommands;
- (void)setAvailableCommands:(NSArray *)commands;
- (NSUInteger)availableCommandsCount;
- (WebContext *)webContext;
- (void)setWebContext:(WebContext *)value;


#pragma mark -
#pragma mark Command Retrieval
- (NSArray *)commandsWithCondition:(NSString *)condition error:(NSError **)error;
- (NSArray *)locationsWithCondition:(NSString *)condition error:(NSError **)error;
- (CommandMO *)internalCommandWithID:(NSInteger)commandID;

#pragma mark -
#pragma mark Group Display Names
+ (NSString *)groupNameForBundleIdentifier:(NSString *)bundleIdentifier;
+ (NSString *)globalGroupName;
+ (NSString *)globalApplicationGroupName;
+ (NSString *)globalBookmarkGroupName;
+ (NSString *)globalGeneralGroupName;

#pragma mark -
#pragma mark Framework Version Info
+ (NSInteger)majorVersion;
+ (NSInteger)minorVersion;
+ (NSInteger)buildNumber;
+ (NSString *)versionString;

#pragma mark -
#pragma mark Logging
- (void)logCommands:(NSArray *)commands withDetails:(BOOL)withDetails;
- (void)logAllCommandsWithDetails:(BOOL)withDetails;
- (void)logAllCommandsForMoc:(NSManagedObjectContext *)moc withDetails:(BOOL)withDetails;
- (void)logAllStoreLoaders;
- (void)dumpUserStoreWithTitle:(NSString *)title;

- (void)dumpAllCommandTrackers;
- (void)dumpCommandTrackerForCommandKey:(NSString *)commandKey;
- (void)dumpCommandTrackerSummaryRequireUser:(BOOL)requireUser;

@end


extern NSString *MSCommandsManagerDidChangeCommandsNotification;
extern NSString *MSCommandsManagerDidLoadCommandsNotification;
extern NSString *MSCommandsManagerDidUnloadCommandsNotification;
extern NSString *MSCommandsManagerDidIgnoreCommandNotification;
extern NSString *MSCommandsManagerApplicationActivatedNotification;
extern NSString *MSCommandsManagerProcessTerminatedNotification;
extern NSString *MSCommandsManagerGroupChangedNotification;
extern NSString *MSCommandsManagerStartedCommandNotification;
extern NSString *MSCommandsManagerFinishedCommandNotification;

