//
//  GlyphsFilterProtocol.h
//  GlyphsCore
//
//  Created by Georg Seifert on 08.05.09.
//  Copyright 2009 schriftgestaltung.de. All rights reserved.
//

@class GSLayer;
@class GSFont;
@class GSDialogController;
@class GSInstance;
@class GSGlyph;
@class GSFontMaster;

#ifndef LIBCORE
#import <GlyphsCore/GSGlyphViewControllerProtocol.h>
#endif

/** The protocol defining the filter plugin interface */
@protocol GlyphsFilter
/** The interface version.*/
@property (nonatomic, readonly) NSUInteger interfaceVersion;
/** The title of the plugin.*/
@property (nonatomic, readonly) NSString *title;
/** The keyEquivalent to select the Filter.*/
@property (nonatomic, readonly) NSString *keyEquivalent;

#ifndef LIBCORE
/** the Controller of type GSEditViewController */
@property (nonatomic, unsafe_unretained) NSViewController<GSGlyphViewControllerProtocol> *controller;
#endif

/// Glyphs will call that before the filter is invoked.
- (NSError *)setup;

/** This method will be called if one layer is active in Edit View (the nodes are visible) Pay attention to the selection.

 @param layer   The active Layer
 @param error   if something goes wrong, retunes an NSError by reference.

 @return YES if successful, otherwise NO. In the later case the error will hold a explanation.
 */

- (BOOL)runFilterWithLayer:(GSLayer *)layer error:(out NSError **)error;

#ifndef LIBCORE
/// This method will be called if the hole glyph is supposed to be processed.
- (BOOL)runFilterWithLayers:(NSArray *)layers error:(out NSError **)error;
#endif

@optional

/// do main initialization
- (void)loadPlugin;

@property (strong) IBOutlet NSView *view;

/// is set, if the user chose "run last Filter". Then it should keep the settings from the last run.
@property (nonatomic) BOOL rerun;

/// The title of the filter dialog.
@property (nonatomic, readonly) NSString *dialogTitle;

/// the returned value will be placed as the title of the "OK" button in the filter dialog.
- (NSString *)actionName;

/** this can be used to control the sorting of the filters in the menu.

 dont implement this method or return nil, if you like the menu item be sorted alphabetically
 */
- (NSString *)menuSortKey;

/// @name Export Filter Support

/// This will be call if the filter should be run from on export of the font. (see: Instance > Custom Properties)
- (BOOL)filterNeedsRemoveOverlap;

/** Is called to process font when called from a 'Filter' custom parameter

 @param font      The font to process
 @param arguments A list of arguments
 */
- (void)processFont:(GSFont *)font withArguments:(NSArray *)arguments;

/** Is called to process a layer when to preview a Filter custom parameter

 @param layer     The layer to process
 @param arguments A list of arguments
 */
- (void)processLayer:(GSLayer *)layer withArguments:(NSArray *)arguments;

/** Is called to process font when called from a 'PreInterpolationFilter' custom parameter
 @param glyph     The glyph to process
 @param arguments A list of arguments
 */
- (void)processGlyph:(GSGlyph *)glyph withArguments:(NSArray *)arguments;
#ifndef LIBCORE
/** This method will be called if one layer is active in Edit View

 This is actually only used for the remove Overlap filter and might be removed when that one goes away.

 @param layer  a Layer
 @param options A dict containing some options. This might be "CheckSelection" : YES/NO.
 @param error   if something goes wrong, retunes an NSError by reference.

 @return YES if successful, otherwise NO. In the later case the error will hold a explanation.
 */
- (BOOL)runFilterWithLayer:(GSLayer *)layer options:(NSDictionary *)options error:(out NSError **)error;
#endif

/// Implement this to enable the
- (NSString *)customParameterString;

/** Implement it if you need to supply your own window.

 @return a GSDialogController that controls the window
 */
- (GSDialogController *)makeWindowController;

/// do update the window
- (void)setupDialog:(GSDialogController *)dialog;

/**
 Return NO, if the plugin should not be added to the Filter menu.

 If not implemented, it defaults to YES.
 */
- (BOOL)needsMenuEntry;
@end

@protocol GlyphsCallback <NSObject>

- (NSUInteger)callOrder;

/** Is called to process a font before output

@param font     The glyph to process
@param instance  the exported instance
@return NO if there was an error
*/

- (BOOL)processFont:(GSFont *)font instance:(GSInstance *)instance error:(out NSError **)error;

/** Is called to process a glyph before output

 @param glyph     The glyph to process
 @param instance  the exported instance
 @return NO if there was an error
 */
- (BOOL)processGlyph:(GSGlyph *)glyph instance:(GSInstance *)instance error:(out NSError **)error;

/** Is called to process the layer preparing it for preview

 @param layer     The layer to process
 @param extraHandles on return, a list of GSHandle objects that are shown as small black dots in the UI
 @return NO if there was an error
 */
- (BOOL)processLayer:(GSLayer *)layer extraHandles:(NSMutableArray *)extraHandles error:(out NSError **)error;

/** Is called to process a layer before output

 @param layer     The layer to process
 @param instance  the exported instance
 @return NO if there was an error
 */
- (BOOL)processLayer:(GSLayer *)layer instance:(GSInstance *)instance error:(out NSError **)error;

/** Is called to process some shapes before output

 This is used when color layers where each set of path with the same attributes has to be processed separately

 @param shapes     The shapes to process
 @param extraHandles on return, a list of GSHandle objects that are shown as small black dots in the UI
 @param didChange if there where any changes
 @return NO if there was an error
*/

- (NSArray *)processShapes:(NSArray *)shapes extraHandles:(NSMutableArray *)extraHandles didChange:(BOOL *)didChange error:(out NSError **)error;

- (BOOL)interpolateMaster:(GSFontMaster *)master font:(GSFont *)font interpolation:(NSDictionary *)interpolation error:(out NSError **)error;

- (BOOL)interpolateLayer:(GSLayer *)layer glyph:(GSGlyph *)glyph interpolation:(NSDictionary *)interpolation error:(out NSError **)error;

- (void)font:(GSFont *)font scaledBy:(CGFloat)scale;

/**
 This is called when a document is opened.

 Please don’t don’t take too long as this will let the use user wait.

 To get to the path, use `font.parent.fileURL`.

 @param font The font object that was opened
 */

- (void)fontDidOpen:(GSFont *)font;

@end
