//
//  GSGlyph.h
//  FontBezier Doc
//
//  Created by Georg Seifert on 20.10.05.
//  Copyright 2005 schriftgestaltung.de. All rights reserved.
//

#import <Cocoa/Cocoa.h>

@class GSFont;
@class GSLayer;
@class GSUndoManager;
@class MGOrderedDictionary;
@class GSInstance;

/**
 The class defining the glyph object
*/

@interface GSGlyph : NSObject <NSCoding, NSCopying> {
	MGOrderedDictionary* _layers;
	NSString* _name;
	NSString* _unicode;
	UTF32Char _unicodeChar;
	NSString* _script;
	NSString* _note;
	GSFont* __unsafe_unretained _parent;
	NSArray* _baseGlyphs;
	NSString* _category;
	NSString* _subCategory;
	NSString* _leftMetricsKey;
	NSString* _widthMetricsKey;
	NSString* _rightMetricsKey;
	NSString* _vertWidthMetricsKey;
	NSString* _topMetricsKey;
	NSString* _bottomMetricsKey;

	NSString* _leftKerningGroup;
	NSString* _rightKerningGroup;
	NSString* _leftKerningGroupId;
	NSString* _rightKerningGroupId;

	NSString* _topKerningGroup;
	NSString* _bottomKerningGroup;
	NSString* _topKerningGroupId;
	NSString* _bottomKerningGroupId;

	NSUInteger _glyphId;
	NSString* _id;
	BOOL _export;
	NSColor* _color;
	NSInteger _colorIndex;
	NSMutableDictionary* _userData;
	NSDate* _lastChange;
	NSInteger _changeCount;
#ifndef GLYPHS_VIEWER
	GSUndoManager* _undoManager;
#endif
	NSString* _sortName;
	NSString* _sortNameKeep;
	NSString* _production;
	NSDictionary* glyphDict;
}
/// @name Properties

/** A pointer to the containing GSFont object */
@property (unsafe_unretained, nonatomic) GSFont* parent;
@property (readonly, nonatomic) GSFont* font;
@property (assign, nonatomic) NSInteger changeCount;

/// The glyphs name
@property (nonatomic, copy) NSString* name;
/// The unicode value of the glyph. This is normaly set automaticaly on setting the name
@property (nonatomic, copy) NSString* unicode;

/** A character code of the glyph of 0 if it has no unicode */
@property (nonatomic, readonly) UTF32Char unicodeChar;

/// The glyphs note
@property (nonatomic, copy) NSString* note;

/** The language/script of the glyph.

 e.g: latin, cyrillic, greek
 This is set from the internal database.
 */
@property (nonatomic, copy) NSString* script;
/** The category of the glyph

e.g: letter, number, punctuation ...
this is set from the internal database.
*/
@property (nonatomic, copy) NSString* category;

/** The sub category of the glyph

e.g: lower case, smallcaps ...
this is set from the internal database.
*/
@property (nonatomic, copy) NSString* subCategory;
/// The glyphs the glyph is composed of.
@property (nonatomic, strong) NSArray* baseGlyphs;
#ifndef GLYPHS_VIEWER
/** The content of the glyph as dictionary to store it in a pList.

This is used to store the data in the .glyphs file.
*/
@property (unsafe_unretained, readonly) NSDictionary* glyphDict;
/// The glyphname of the keyglyph for LSB.
@property (copy, nonatomic) NSString* leftMetricsKey;
@property (copy, nonatomic) NSString* widthMetricsKey;
@property (copy, nonatomic) NSString* vertWidthMetricsKey;
/// The glyphname of the keyglyph for RSB.
@property (copy, nonatomic) NSString* rightMetricsKey;
@property (copy, nonatomic) NSString* topMetricsKey;
@property (copy, nonatomic) NSString* bottomMetricsKey;
#endif
/// The name of the kerning group for left side kerning.
@property (copy, nonatomic) NSString* leftKerningGroup;
/// The name of the kerning group for right side kerning.
@property (copy, nonatomic) NSString* rightKerningGroup;

/** The id of the keyglyph for left side kerning.

this sould look like this: `@MM_L_Name`
*/
@property (copy, nonatomic) NSString* leftKerningGroupId;

/** The id of the key glyph for right side kerning.

this sould look like this: `@MM_R_Name`
*/
@property (copy, nonatomic) NSString* rightKerningGroupId;

@property (copy, nonatomic) NSString* topKerningGroup;

@property (copy, nonatomic) NSString* bottomKerningGroup;

/** The id of the key glyph for top kerning.

this sould look like this: `@MM_T_Name`
*/
@property (copy, nonatomic) NSString* topKerningGroupId;

/** The id of the key glyph for bottom kerning.

this sould look like this: `@MM_B_Name`
*/
@property (copy, nonatomic) NSString* bottomKerningGroupId;

#ifndef __cplusplus //RMX complains about that.

/// If the glyph will end up in the final font
@property (nonatomic) BOOL export;
#endif

/// The NSColor object of the color label
@property (unsafe_unretained, readonly, nonatomic) NSColor* color;

/** Returns the index of the color label

@return 0–11, anything else means no label
*/
@property (assign, nonatomic) NSInteger colorIndex;

/**
 * Place to store custom data.
 * Here it is possible to store something. Please use a unique key.
 * The objects should be able to serialize to a plist. If they are not, they should return all infos to store in description (as String).
*/
@property (nonatomic, strong) NSMutableDictionary* userData;

/** The glyphs undoManager

Each GSGlyph object has its own undoManager

@see [GSFont.undoManager]([GSFont undoManager])

@return a NSUndoManager object
*/

#ifndef GLYPHS_VIEWER
@property (strong, nonatomic) NSUndoManager* undoManager;
#endif
@property (nonatomic) NSUInteger glyphId;

/** The glyph key is used to access the glyph.

This is used to keep track of the glyph even if is renamed.
It is used for the kerning.
It could look like this: "FBCA074D-FCF3-427E-A700-7E318A949AE5"
*/
@property (strong, nonatomic) NSString* id;
/**
The names is used for sorting.

If set it will be used for sorting inside of
*/
@property (strong, nonatomic) NSString* sortName;
@property (strong, nonatomic) NSString* sortNameKeep;
@property (strong, nonatomic) NSString* production;
@property (nonatomic, strong) NSDate* lastChange;

@property(strong, nonatomic) NSArray* partsSettings;

- (NSString*) charString;

//@property(retain) id itemView;
/// Initialisation
/// Initializes a newly allocated glyph with this name
//- (id) initWithName:(NSString*) Name ;

/** initialises a glyph with a dictionary loaded from a pList.

@param glyphDict A dictionary
*/
- (instancetype)initWithGlyphDict:(NSDictionary*)glyphDict;

#ifndef GLYPHS_VIEWER

/*!
 * @discussionsaves the object to file
 * @param File		a File
 * @param Compact	a bool indecating if it should use a more compact file format
 * @param error	on return an error containig the reason for failiour.
 * @return YES if sucsessful
 */

- (BOOL)saveToFile:(FILE*)File compact:(BOOL)Compact error:(NSError**)error;

#endif
/// @name Methods

#ifndef GLYPHS_VIEWER

- (void)updateChangeCount:(NSDocumentChangeType)changeType;

- (NSError*)validateName:(NSString*)Name;

#endif

- (void)setName:(NSString*)Name changeName:(BOOL)ChangeName;

- (void)setName:(NSString*)Name changeName:(BOOL)ChangeName update:(BOOL)Update;

#pragma Layers

/// @name Layers

/** An array of GSLayer objects.
 
 It should have at least the same count than font.fontMasters.
 
 The keys are the id of the font masters and should be the same as the [GSLayer.associatedMasterId]([GSLayer associatedMasterId]) if the layer that is associated by the key. For 'master layers', it should also be equal to the [GSLayer.layerId]([GSLayer layerId]).
 */
@property (strong, nonatomic) NSDictionary* layers;

/** The number of layers in the glyph
 
 @return The number of layers
 */
- (NSUInteger)countOfLayers;

/** Returns the a layer loacated at a Index.

 @param Key The Id of the layer
 @return A GSLayer object or nil if not found
*/
- (GSLayer*)layerForKey:(NSString*)Key;

- (GSLayer*)layerForName:(NSString*)Key;

/**
 Adds the Layer with the key.
 @discussion If the Key is a id of a GSFontMaster, it will be a masterlayer, otherwise the associated master ID of the layer should be set to a ID of a master.
 @param Layer The GSLayer object.
 @param Key The layer key. For master layers this is the id of the corresponding GSFontMaster.
*/
- (void)setLayer:(GSLayer*)Layer forKey:(id)Key;

#ifndef GLYPHS_VIEWER

/**
 Removes the Layer for the key.

 @param Key The layer key.
*/
- (void)removeLayerForKey:(id)Key;

/**
 Returns if the glyphs has compatibel outlines.

 @return YES if the layers have compatible outlines.
*/
- (BOOL)mastersCompatible;
/**
 Returns if the glyphs has compatibel outlines in the layers for all FontMasterIds
 
 @param FontMasterIds the Master IDs
 @return YES if the layers have compatible outlines.
 */
- (BOOL)mastersCompatibleForLayers:(NSArray*)FontMasterIds;

- (void)sortLayers:(NSMutableArray *)Layers ;

- (NSArray*)layerGroups:(NSArray*)Instances masters:(NSArray*)Masters error:(NSError**)error ;

- (GSLayer*)interpolate:(NSDictionary*)Interpolation NS_DEPRECATED_MAC(10_0, 10_0);

- (GSLayer*)interpolate:(NSDictionary*)Interpolation error:(NSError**)error NS_DEPRECATED_MAC(10_0, 10_0);

/**
 Generates an interpolated layer
 
 @param Instance  The instance that defines the interpolation values
 @param Decompose If components sould be decomposed before interpolation. If not the hole font is interpolated, this should be set
 @param Error if there is a problem, it returnes an NSError object (by reference) that contains details.
 @return The intepolated layer, or nil if something went wrong.
 */
- (GSLayer*)interpolate:(GSInstance*)Instance decompose:(BOOL)Decompose error:(NSError**)Error;

/**
 Replaces the content of the Layer with an interpolation from the remaining layers.
 
 This is useful for 'brace' layers but also for a default state for middle masters.
 @param Layer The Layer that should be recalculated
 */
- (void)replaceLayerWithInterpolation:(GSLayer*)Layer ;

- (NSInteger)bracketLayerInfo:(NSString*)LayerName name:(NSString**)Name mode:(char*)Mode_p otherAxis1:(NSInteger*)OtherAxis1 otherAxis2:(NSInteger*)OtherAxis2 ;

/// Is called from other object after changing some of the glyphs properties.
- (void)outlineHasChanges;

- (id)copyThin:(BOOL)Thin layers:(BOOL)Layers;
/**
 If the glyph has MS color glyph information
 */
- (BOOL)isColorGlyph;

/** If the glyph has Apple color glyph information */
- (BOOL)isAppleColorGlyph;
#endif
@end
