/*
    ProjectModule.h

    Interface declaration of the ProjectModule class for the
    ProjectManager application.

    Copyright (C) 2005, 2006  Saso Kiselkov

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#import <Foundation/NSObject.h>
#import <AppKit/NSMenu.h>

@class NSString, NSToolbarItem, ProjectDocument, NSView;

extern NSString * const CurrentProjectModuleDidChangeNotification;

/**
 * This protocol declares methods which project modules must implement.
 *
 * A project module is one of the `tabs' in a project's window. Each
 * such project module can take care of one aspect of project management.
 * For example, there's modules for project attribute and file management,
 * building, managing subprojects, etc. These modules can then create
 * their own APIs between themselves and the ProjectType object in
 * charge of the project as a whole.
 *
 * N.B. in the -validateMenuItem: method you should return YES in case
 * the passed menu item doesn't belong to you.
 */
@protocol ProjectModule <NSObject, NSMenuValidation>

/**
 * Should return a unique module identifier name.
 */
+ (NSString *) moduleName;

+ (NSString *) humanReadableModuleName;

/**
 * Designated initializer of project modules.
 */
- initWithDocument: (ProjectDocument *) document
    infoDictionary: (NSDictionary *) infoDict;

/**
 * Finishes the initialization process of the project module. The project
 * module should put all initialization related to querying the project
 * type object in here, since initial project module initialization takes
 * place before the project type object is created. This method is invoked
 * on all project modules afterwards.
 *
 * Also, some project modules interface between each other to obtain some
 * functionality. While this is somewhat discouraged, since the order in
 * which -finishInit is sent to project modules is not guaranteed, it is
 * preferrable to put such intialization logic in here, because all modules
 * should have loaded their persistent state in the first init stage.
 */
- (void) finishInit;

/**
 * Should return the owner project document to which this project module
 * belongs to.
 */
- (ProjectDocument *) document;

/**
 * Instructs the project module to return a view which will be put into
 * the project's window this module becomes the current module.
 */
- (NSView *) view;

/**
 * Instructs the project module to return an archivable version of it's
 * data that it wishes to be saved together with the project. For example,
 * the FileManager module returns it's project file structure in here.
 *
 * If the project module doesn't have any archivable data, it's safe
 * to return `nil' here.
 */
- (NSDictionary *) infoDictionary;

/**
 * Sent to the project module when it is to regenerate it's derived
 * files which are generated from other files/data in the project
 * itself. For example, the Application project type regenerates
 * the project's makefiles in this method.
 */
- (BOOL) regenerateDerivedFiles;

/**
 * Should return an array of NSMenuItem's which will be put into the
 * module's submenu.
 */
- (NSArray *) moduleMenuItems;

/**
 * A module should return the default toolbar item identifiers for
 * it's toolbar. PM automatically adds mandatory ones to this list.
 */
- (NSArray *) toolbarItemIdentifiers;

/**
 * This method asks the module to create a toolbar item for the
 * provided itemIdentifier. This argument is guaranteed to be one
 * of the allowed toolbar item identifiers which the module returned
 * in -allowedToolbarItemIdentifiers.
 */
- (NSToolbarItem *) toolbarItemForItemIdentifier: (NSString *) itemIdentifier;

/**
 * This method is invoked when the project type object is required to
 * validate it's toolbar items.
 */
- (BOOL) validateToolbarItem: (NSToolbarItem *) toolbarItem;

@end

static inline NSMenuItem *
PMMakeMenuItem (NSString * title, SEL action, NSString * keyEquivalent,
                id target)
{
  NSMenuItem * item;

  item = [[[NSMenuItem alloc]
    initWithTitle: title action: action keyEquivalent: keyEquivalent]
    autorelease];
  [item setTarget: target];

  return item;
}
