//
//  GSLayer.h
//  Glyphs
//
//  Created by Georg Seifert on 13.8.07.
//  Copyright 2007 schriftgestaltung.de. All rights reserved.
//

#import <Cocoa/Cocoa.h>

typedef struct _GSGlyphMetrics {
	CGFloat width;
	CGFloat ascender;
	CGFloat capHeight;
	CGFloat descender;
	CGFloat xHeight;
	CGFloat italicAngle;
	CGFloat vertWidth;
} GSGlyphMetrics;

@class GSFont;
@class GSGlyph;
@class GSPath;
@class GSNode;
@class GSAnchor;
@class GSComponent;
@class GSHint;
@class GSElement;
#ifndef GLYPHS_VIEWER
#ifndef LIBCORE
@class GSBackgroundLayer;
#endif
#endif
@class GSFontMaster;
@class GSBackgroundImage;
@class GSGuideLine;
@class GSAnnotation;
@class MGOrderedDictionary;
@protocol GSPenProtocol;

/*! The class defining the layer object */

#ifndef GLYPHS_VIEWER

@interface GSLayer : NSObject <NSCoding, NSCopying>
#else
@interface GSLayer : NSObject <NSCopying>
#endif
{
	NSString* _name;

	NSMutableArray* _paths;
	NSMutableDictionary* _anchors;
	NSMutableArray* _components;
#ifndef GLYPHS_VIEWER
#ifndef LIBCORE
	GSBackgroundLayer* _background;
#endif
#endif
	NSMutableDictionary* _userData;
#ifndef GLYPHS_VIEWER
	NSMutableOrderedSet* _selection;
#endif
	GSGlyph* __weak _glyph;
	NSBezierPath* _bezierPath;
	NSBezierPath* _openBezierPath;
	NSBezierPath* _selectionPath;

	NSString* _layerId;
	NSString* _associatedMasterId;
	NSMutableArray* _hints;
	BOOL _locked;
#ifndef LIBCORE
	GSBackgroundImage* _backgroundImage;
#endif
	NSMutableArray* _guideLines;
	BOOL _disableUpdates;
	BOOL _hasDisabledUpdates;
	NSMutableSet* _changedKeys;
	BOOL _isUpdateingMetrics;
	BOOL _isAligning;
	NSString* _leftMetricsKey;
	NSString* _widthMetricsKey;
	NSString* _rightMetricsKey;
	NSString* _topMetricsKey;
	NSString* _vertWidthMetricsKey;
	NSString* _bottomMetricsKey;
	BOOL _visible;
#ifdef DEBUG
	CGFloat _a;
	CGFloat _b;
	CGFloat _penAngle;
#endif
	NSMutableArray* _annotations;
	GSLayer* _cachedDecomposedCopy;
@public
	CGFloat _LSB, _RSB, _width;
	CGFloat _TSB, _BSB;
	CGFloat _vertWidth;
	//NSInteger				updateCount;
	BOOL _hasAlignedWidth;
}

@property (nonatomic, unsafe_unretained, readonly) id content;

/*! Returns the containing GSGlyph object */
@property (weak, nonatomic) GSGlyph* parent;

/*! Returns the containing GSFont object */
@property (readonly, nonatomic) GSFont* font;

/*! A pointer to the containing GSGlyph object */
@property (readonly, nonatomic) GSGlyph* glyph;

/*! The title of the layer.

 for master layers this is the name of the associated FontMaster, otherwise it is a custom string (e.g. a date to keep track of history).
 */
@property (strong, nonatomic) NSString* name;

#ifndef GLYPHS_VIEWER
/*! A dict where custom plugins can store data. It will be stored in the document file.

 The stored object have to conform to the NSCoding protocol.
 */
@property (strong, nonatomic) NSMutableDictionary* userData;
/**
 If the layer is visible 
 
 This is controlled from the Layer panel
 */
@property (nonatomic) BOOL visible;

/*! Returns the content of the layer to store in pList */
@property (nonatomic, unsafe_unretained, readonly) NSDictionary* layerDict;

/*! The layer key is used to access the layer in the glyphs layer dictionary.
 
 For master layers this should be the id of the FontMaster.
 It could look like this: "FBCA074D-FCF3-427E-A700-7E318A949AE5"
 */
@property (strong, nonatomic) NSString* layerId;

/*! The associatedMasterId is used to connect a layer which is not a master layer to a FontMaster.
 
 This is needed for copies of layers (e.g. for different versions) to access vertical metrics stored in the FontMaster.
 It could look like this: "FBCA074D-FCF3-427E-A700-7E318A949AE5"
 */
@property (strong, nonatomic) NSString* associatedMasterId;
#ifndef GLYPHS_VIEWER

@property (readonly, nonatomic) NSDictionary* kerning;

/*! If locked, no user changes are allowed 
 */
@property (nonatomic) BOOL locked;


/*! @methodgroup Metrics */
/*! @name Metrics */

/*! The left sidebearing.
 @see RSB
 @see width
 */
@property (nonatomic) CGFloat LSB;

/*! The right sidebearing.
 @see LSB
 @see width
 */
@property (nonatomic) CGFloat RSB;
#endif

/*! The width.
 @see LSB
 @see RSB
 */
@property (nonatomic, assign) CGFloat width;
#ifndef GLYPHS_VIEWER

/*! The top sidebearing */
@property (nonatomic, assign) CGFloat TSB;

/*! The bottom sidebearing */
@property (nonatomic, assign) CGFloat BSB;

/*! The vertical width */
@property (nonatomic, assign) CGFloat vertWidth;

/*! YES if the layer is automatically aligned */
@property (nonatomic, assign) BOOL hasAlignedWidth;

/*! The metrics key for the left sidebearing */
@property (nonatomic, strong) NSString* leftMetricsKey;
@property (nonatomic, unsafe_unretained) NSString* leftMetricsKeyUI;
- (NSString*)leftMetricsKeyIsInSync:(BOOL*)IsInSync;

/*! The metrics key for the width */
@property (nonatomic, strong) NSString* widthMetricsKey;
@property (nonatomic, unsafe_unretained) NSString* widthMetricsKeyUI;

- (NSString*)widthMetricsKeyUIFast;

- (NSString*)widthMetricsKeyIsInSync:(BOOL*)IsInSync;

/*! The metrics key for the right sidebearing */
@property (nonatomic, strong) NSString* rightMetricsKey;
@property (nonatomic, unsafe_unretained) NSString* rightMetricsKeyUI;
- (NSString*)rightMetricsKeyIsInSync:(BOOL*)IsInSync;

/*! The metrics key for the top sidebearing */
@property (nonatomic, strong) NSString* topMetricsKey;
@property (nonatomic, unsafe_unretained) NSString* topMetricsKeyUI;
//- (NSString*)topMetricsKeyIsInSync:(BOOL*)IsInSync;

/*! The metrics key for the bottom sidebearing */
@property (nonatomic, strong) NSString* bottomMetricsKey;
@property (nonatomic, unsafe_unretained) NSString* bottomMetricsKeyUI;
//- (NSString*)bottomMetricsKeyIsInSync:(BOOL*)IsInSync;

/*! The metrics key for the vertical width */
@property (nonatomic, strong) NSString* vertWidthMetricsKey;
@property (nonatomic, unsafe_unretained) NSString* vertWidthMetricsKeyUI;

- (NSString*)vertWidthMetricsKeyIsInSync:(BOOL*)IsInSync;

#endif

/*! @name Bezier Handling */

/*! Returns the bezierpath for the layer. Ignores open paths.
 @see openBezierPath
 */
@property (nonatomic, strong) NSBezierPath* bezierPath;

/*! Returns the bezierpath for open paths in the layer */
@property (nonatomic, strong) NSBezierPath* openBezierPath;

@property (nonatomic, strong) NSBezierPath* selectionPath;

/** if there is one node selected, return it, otherwise return nil */
@property (nonatomic, unsafe_unretained, readonly) GSNode* selNode;

#endif

@property (nonatomic, strong) NSMutableArray* annotations;

/*! initialises a layer with a dictionary loaded from a pList.

@param layerDict A dictionary
*/
- (instancetype)initWithLayerDict:(NSDictionary*)layerDict;

#ifndef GLYPHS_VIEWER

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

#endif

/*! Returns a string to easily compare the paths of the layers. Layers are compatible if they have the same compareString.
 
 The string has a letter for each node, all components and all anchor names
 
 Offcurve = o, Curve = c, Line = l.

 @return An NSString.
 */
- (NSString*)compareString;

- (NSDictionary*)differenceToLayer:(GSLayer*)OtherLayer options:(int)Options;

#ifndef GLYPHS_VIEWER

- (GSNode*)nodeAtPoint:(NSPoint)aPoint excludeNode:(GSNode*)Exclude tollerance:(CGFloat)Tolerance;

- (GSNode*)nodeAtPoint:(NSPoint)aPoint excludeNodes:(NSSet*)Excludes traversComponents:(BOOL)traversComponents tollerance:(CGFloat)Tolerance;

#pragma mark Paths

/*! @methodgroup Paths */
/*! @name Paths */

/*! An array of GSPath objects */
@property (/*nonatomic,*/ strong, nonatomic) NSArray* paths;

/*! Inserts a path into the paths array at the location specified by Index.
 
 @param Path  A GSPath object.
 @param Index An index within the paths array.
 */
- (void)insertPath:(GSPath*)Path atIndex:(NSInteger)Index;

/*! Removes path from the layer
 
 @param Index Index of the path that will be removed
 */
- (void)removePathAtIndex:(NSInteger)Index;

#endif

/*! Add a path to the layer
 
 The path will be added to the end of the layer’s paths array.
 
 @param Path A GSPath object.
 */
- (void)addPath:(GSPath*)Path;

#ifndef GLYPHS_VIEWER
//! Removes the path from the layer.
/*!
This is necessary for scripting over Distributed Object (JSTalk)
@param Path The Path to remove from the layer.
*/
- (void)removePath:(GSPath*)Path;

- (void)removePaths:(NSArray*)Paths;

- (void)removePathsAtIndexes:(NSIndexSet*)indexes;

- (void)replacePathAtIndex:(NSUInteger)theIndex withPath:(GSPath*)Path;

- (GSNode*)connectPathsWithNode:(GSNode*)moveNode andNode:(GSNode*)overNode;

//! returnes the node before the opening.
- (GSNode*)dividePathAtNode:(GSNode*)Node;

- (void)connectAllOpenPaths;

/*! Is called from element objects (anchors, components) if it has changed.
 
 @param Element The changed element
 */
- (void)elementDidChange:(GSElement*)Element;

#endif

/*! Returns the count of paths in the layer.
 
 @return The count of paths in the layer.
 */
- (NSUInteger)pathCount;

/*! Returns the path at index.
 
 @param Index An index within the bounds of the the paths array.
 @return A GSPath object.
 */
- (GSPath*)pathAtIndex:(NSInteger)Index;

#ifndef GLYPHS_VIEWER

/*! Returns the layer loacated at index.
 
 @param Path An path object.
 @return The Index of Path in the paths array. If path is not in the paths array it returns NSNotFound.
 */
- (NSInteger)indexOfPath:(GSPath*)Path;

- (GSNode*)nodeAtIndexPath:(NSIndexPath*)IndexPath;

- (NSIndexPath*)indexPathOfNode:(GSNode*)Node;

- (NSInteger)indexOfNode:(GSNode*)Node;

#endif
#pragma mark Anchor

/*! @methodgroup Anchors */
/*! @name Anchors */

/*! An array of GSAnchor objects */
@property (strong, nonatomic) NSDictionary* anchors;

/** The count of the anchors */
- (NSInteger)anchorCount;

#ifndef GLYPHS_VIEWER

/*! Adds the Anchor to the Layer.
 @param Anchor A Anchor.
 */
- (void)addAnchor:(GSAnchor*)Anchor;

/*! Adds a copy of the Anchor to the Layer.

 @param Anchor A Anchor.
 @return A reference to the copy.
 */
//- (GSAnchor*) addAnchorCopy:(GSAnchor*) Anchor;


/*! Removes the anchor from the Layer.
 @param Anchor A GSAnchor object.
 */
- (void)removeAnchor:(GSAnchor*)Anchor;

/*! Removes the anchor with the name AnchorName from the layer.
 @param AnchorName An anchor name.
 */
- (void)removeAnchorWithName:(NSString*)AnchorName;

#endif

/*! Returns the corresponding anchor for an anchor name.
 @param Name The name of the anchor, e.g. "top"
 @return The GSAnchor object for the anchor name.
 */
- (GSAnchor*)anchorForName:(NSString*)Name;

/*! Returns a GSAnchor with for the given name.
 @param Name            The name of the anchor
 @param checkComponents if it should look into components
 @return The anchor or nil
 @see anchorNamesTraversingComponents
 */
- (GSAnchor*)anchorForName:(NSString*)Name traverseComponents:(BOOL)checkComponents;

/*! All anchor names from nested components
 @return A list of anchor names
 */
- (NSArray*)anchorNamesTraversingComponents;

#ifndef GLYPHS_VIEWER

- (void)anchorChangedName:(GSAnchor*)Anchor;

/*! Decomposes only the anchors.*/
- (void)copyAnchorsFromComponents;

#endif
#pragma mark Components
/*! @methodgroup Components */
/*! @name Components */

/*! The array of GSComponents objects */
@property (strong, nonatomic) NSArray* components;

/*! Number of components in the layer. */
- (NSUInteger)componentCount;

/*! Returns the component located at theIndex.

 @param theIndex An index within the bounds of the the paths array.
 @return A GSComponent object.
 */
- (GSComponent*)componentAtIndex:(NSUInteger)theIndex;

/*! Adds the Component to the Layer.

 @param Component A GSComponent object.
 */
- (void)addComponent:(GSComponent*)Component;

- (void)addComponentFast:(GSComponent*)aComponent;
#ifndef GLYPHS_VIEWER

/*! Adds a component at a specified index.
 
 @param aComponent A GSComponent object.
 @param Index      An index within the components array.
 */
- (void)insertComponent:(GSComponent*)aComponent atIndex:(NSUInteger)Index;

/*! Removes a component from the Layer.

 @param Component A GSComponent object.
 */
- (void)removeComponent:(GSComponent*)Component;

/*! Removes a component from the Layer
 
 @param Index The index of the component to be removed.
 */
- (void)removeComponentAtIndex:(NSInteger)Index;

/*! Helper function to fix component position.

 Call this every time you need to access the component.
 If the first component is a letter and the second is a accent, the Letter is placed at the origin, the width of the glyphs is copied from the referenced Glyph. If it find corresponding anchors it alignes the accents on it.
 */
- (void)alignComponents;

/*! Builds the compound glyph from the components suggested in GlyphData.xml (decompose attribute).
 */
- (void)makeComponents;

/*! A GSLayer copy with all components decomposed.
 
 @return The layer containing only paths.
 @see decomposeComponent:
 @see decomposeComponentDontNotifiy:
 */
- (GSLayer*)copyDecomposedLayer;

/*! Decomposes components.
 
 This will also effect nested compontens.
 */

- (void)decomposeComponents;

/*! Decomposes the Component.
 
 @param Component The componet to decompose
 */
- (void)decomposeComponent:(GSComponent*)Component;

/*! Decomposes the Component but does not trigger a UI update
 
 This is helpful in places where you just need the result but not need to redraw automatically
 
 @param aComponent The componet to decompose
 */
- (void)decomposeComponentDontNotifiy:(GSComponent*)aComponent;

/*! Makes the component first.
 
 @param Component The components that should be first.
 */
- (void)makeFirstComponent:(GSComponent*)Component;

/*! An array containing names of the components in the layer
 
 @warning This replaces all components in the layer.
 */
@property (strong, nonatomic) NSArray* componentNames;

#pragma mark Background

/*! @methodgroup Background */
/*! @name Background */

#ifndef GLYPHS_VIEWER
/*! The background layer for this layer */
@property (strong, nonatomic) GSLayer* background;
#endif

/*! Moves objects to the background.
 
 @param CheckSelection Only selected objects if YES.
 @param Keep           Replaces background layer if NO.
 */
- (void)contentToBackgroundCheckSelection:(BOOL)CheckSelection keepOldBackground:(BOOL)Keep;

/*! Moves objects from the layer to its background layer and vice versa.
 */
- (void)swapForgroundWithBackground;

/*! Empties the background layer.
 */
- (void)clearBackground;

#pragma mark BackgroundImage

/*! @methodgroup Image */
/*! @name Image */


#ifndef LIBCORE
/*! The image placed in the layer */
@property (strong, nonatomic) GSBackgroundImage* backgroundImage;
#endif

/*! Add the image at the given URL as layer image.
 
 It verifies if it really is an Image.
 @param URL The Image URL
 */
- (void)addBackgroundImageWithURL:(NSURL*)URL;

#pragma mark Guides

/*! @methodgroup Guides */
/*! @name Guides */

/*! An array containing all GSGuideLine objects of the layer */
@property (strong, nonatomic) NSArray* guideLines;

/*! Number of guidelines in the layer.
 
 @return NSUInteger containing the count of local guidelines.
 */
- (NSUInteger)guideLineCount;

/*! Returns the guideline loacated at theIndex.

 @param theIndex An index within the bounds of the the guidelines array.
 @return A GSComponent object.
 */
- (id)guideLineAtIndex:(NSUInteger)theIndex;

//- (void) getGuideLines:(id*)objsPtr range:(NSRange)range ;

- (void)insertGuideLine:(GSGuideLine*)obj atIndex:(NSUInteger)theIndex;

- (void)addGuideLine:(GSGuideLine*)GuideLine;

- (void)removeGuideLine:(GSGuideLine*)GuideLine;

- (void)removeGuideLineAtIndex:(NSUInteger)theIndex;

- (void)replaceGuideLineAtIndex_:(NSUInteger)theIndex withGuideLine:(GSGuideLine*)GuideLine;

#pragma mark Hints

/*! @methodgroup Hints */

/*! The array of hints */
@property (nonatomic, strong) NSArray* hints;

/*! The number of hints in the layer
 @return Count of hints.
 */
- (NSUInteger)countOfHints;

/*! Adds the Hint to the Layer.
 
 @param Hint A GSHint.
*/
- (void)addHint:(GSHint*)Hint;

//! Adds a copy of the Hint to the Layer.
/*!
@param Hint A Hint.
@return The copied Hint.
*/
//- (GSHint*) addHintCopy:(GSHint*) Hint ;

/*! Returns the GSHint at the specified index.
 
 @param theIndex An index within the bounds of the hints array.
 
 @return The GSHint object for the specified hint index.
 */
- (GSHint*)hintAtIndex:(NSUInteger)theIndex;

- (void)insertHint:(GSHint*)Hint atIndex:(NSUInteger)theIndex;


/*! Removes the Hint from the Layer.

 @param Hint A Hint.
*/
- (void)removeHint:(GSHint*)Hint;

#pragma Annotations

- (void)addAnnotation:(GSAnnotation*)anAnnotation;

- (void)removeAnnotation:(GSAnnotation*)anAnnotation;

#endif

- (NSUInteger)countOfAnnotations;

#ifndef GLYPHS_VIEWER

//- (void)getAnnotations:(id*)buffer range:(NSRange)inRange;

- (GSAnnotation*)objectInAnnotationsAtIndex:(NSUInteger)idx;

//- (void)insertObject:(GSAnnotation*)aGSAnnotation inAnnotationsAtIndex:(NSUInteger)idx;
//- (void)insertAnnotations:(NSArray*)_annotationArray atIndexes:(NSIndexSet*)indexes;

- (void)removeObjectFromAnnotationsAtIndex:(NSUInteger)idx;

//- (void)removeAnnotationsAtIndexes:(NSIndexSet*)indexes;
//- (void)replaceObjectInAnnotationsAtIndex:(NSUInteger)idx withObject:(GSAnnotation*)aGSAnnotation;
//- (void)replaceAnnotationsAtIndexes:(NSIndexSet*)indexes withAnnotations:(NSArray*)_annotationArray;

- (void)saveHints;

- (void)restoreHints;

- (void)updateHints;

#endif
#pragma mark Kerning

/*! @methodgroup Kerning */

/*! Return the kern value for the sequence LeftLayer + self.
 
 This checks if there is class kerning or exception.
 
 @param LeftLayer The GSLayer before the current layer
 
 @warning returnes MaxInt if no value is defined for that pair
 @return The kerning value as float or MaxInt if there is no value
 */
- (CGFloat)leftKerningForLayer:(GSLayer*)LeftLayer;

/*! Return the kern value for the sequence self + RightLayer.

 This checks if there is class kerning or exception.
 @param RightLayer The GSLayer after the current layer
 @warning returnes MaxInt if no value is defined for that pair
 @return The kerning value as float or MaxInt if there is no value
*/
- (CGFloat)rightKerningForLayer:(GSLayer*)RightLayer;

#ifndef GLYPHS_VIEWER
/*! Sets the kerning for the sequence LeftLayer + self.

 This checks if there is class kerning or exception.
 @param Value the kern value as float
 @param LeftLayer The GSLayer before the current layer
*/
- (void)setLeftKerning:(CGFloat)Value forLayer:(GSLayer*)LeftLayer;

/*! Sets the kerning for the sequence self + RightLayer.

 This checks if there is class kerning or exception.
 @param Value the kern value as float
 @param RightLayer The GSLayer after the current layer
*/
- (void)setRightKerning:(CGFloat)Value forLayer:(GSLayer*)RightLayer;

#endif
/*! Returns a boolean value if LeftLayer + self has a kerning exeption.

 @param LeftLayer The GSLayer before the current layer
 @return `True` if there is an exeption
*/
- (BOOL)leftKerningExeptionForLayer:(GSLayer*)LeftLayer;

#ifndef GLYPHS_VIEWER

/*! Sets, if LeftLayer + self has a exception or not.

@param Exeption	if it is a exetion or not
@param LeftLayer The layer on the left
*/
- (void)setLeftKerningExeption:(BOOL)Exeption forLayer:(GSLayer*)LeftLayer;

#endif

/*! Returns a boolean value if self + RightLayer has a kerning exeption.

@param RightLayer The GSLayer after the current layer
@return `True` if there is an exeption
*/
- (BOOL)rightKerningExeptionForLayer:(GSLayer*)RightLayer;

#ifndef GLYPHS_VIEWER

/*! Sets, if LeftLayer + self has a exception or not.

@param Exeption	if it is a exetion or not
@param RightLayer	The layer to the right
*/
- (void)setRightKerningExeption:(BOOL)Exeption forLayer:(GSLayer*)RightLayer;

- (CGFloat)topKerningForLayer:(GSLayer*)LeftLayer;

- (CGFloat)bottomKerningForLayer:(GSLayer*)RightLayer;

- (void)setBottomKerning:(CGFloat)Value forLayer:(GSLayer*)RightLayer;

- (void)setTopKerning:(CGFloat)Value forLayer:(GSLayer*)LeftLayer;

- (BOOL)topKerningExeptionForLayer:(GSLayer*)LeftLayer;

- (BOOL)bottomKerningExeptionForLayer:(GSLayer*)RightLayer;

- (void)setTopKerningExeption:(BOOL)Exeption forLayer:(GSLayer*)LeftLayer;

- (void)setBottomKerningExeption:(BOOL)Exeption forLayer:(GSLayer*)RightLayer;

#endif

#ifndef GLYPHS_VIEWER

#pragma mark Selection

/*! @methodgroup Selection */
/*! @name Selection */

/*! An array of GSElement objects.
 
 All currently selected elements, otherwise nil.
 */
@property (strong, nonatomic) NSMutableOrderedSet* selection;

/*! adds a element to the selection.

@param newSelection The element to add to the selection.
*/

- (void)addSelection:(GSElement*)newSelection;

- (void)addObjectsFromArrayToSelection:(NSArray*)Objects;

- (void)removeObjectFromSelectionAtIndex:(NSUInteger)theIndex;

- (void)removeObjectFromSelection:(id)Object;

- (void)removeObjectsFromSelection:(NSArray*)Objects;

- (void)clearSelection;

#pragma mark updates

/*! @name Updating */

@property (nonatomic) BOOL disableUpdates;

/** Disables updating
 @warning Always make sure to call setEnableUpdates
 @see setEnableUpdates
 */
- (void)setDisableUpdates;

/** Enables updating and combined notifies for all changes that occured while disabled.
 @see setDisableUpdates
 @see enableFutureUpdates
 */
- (void)setEnableUpdates;

/** Enables updating but does not notifies for past changes
 @see setDisableUpdates
 @see setEnableUpdates
 */
- (void)enableFutureUpdates;

/// Is called from an object after it changed the outline of the layer.
- (void)updatePath;

/// marks the RSB and LSB to need update.
- (void)setNeedUpdateMetrics;

/// Recalculates the LSB and RSB using the metrics keys.
- (void)syncMetrics;

/// Recalculates the LSB using the metrics keys.
- (void)syncLeftMetrics;

- (void)syncWidthMetrics;

/// Recalculates the RSB using the metrics keys.
- (void)syncRightMetrics;

/// Recalculates the LSB and RSB.
- (void)updateMetrics;

#endif

/*! The master to which the layer belongs.
 
 @return The GSFontMaster to which the layer belongs.
 */
- (GSFontMaster*)associatedFontMaster;

/*! Metrics for the Layer

 @return The vertical metrics from the fonts fontMaster with the same layerId/associatedlayerId and the width of the layer.
 */
- (GSGlyphMetrics)glyphMetrics;

/// The Bounding box of the path.

/*! The bounding box of the layer.
 
 @return An NSRect encompassing all paths and components in the layer.
 */
- (NSRect)bounds;

#ifndef GLYPHS_VIEWER

/*! The bounding box of the current selection.
 
 @return An NSRect encompassing all selected paths, components and anchors on the layer.
 */
- (NSRect)boundsOfSelection;

/*! Tidies up paths in the layer (removes double points, unnecessary nodes, etc.)
 */
- (void)cleanUpPaths;

/*! Checks is all nodes have the correct connection setting and corrects them if necessary.
 */
- (void)checkConnections;

/*! Corrects the path directions and reorders the paths in the layer.
 */
- (void)correctPathDirection;

- (void)roundSelectedCoordinates;

- (void)roundCoordinates;

/*! Add Extreme Points to all paths.
 */
- (void)addExtremePoints;

/*! Add Extreme Points to all paths.
 
 @param Force Forces extremes if YES.
 */
- (void)addExtremePointsForce:(BOOL)Force;

/*! Adds nodes in segment inflections.
 */
- (void)addInflectionPoints;
/**
 Calculates the intersection of all Paths with the line between StartPoint and EndPoint
 
 @param StartPoint the first point
 @param EndPoint   the second point
 
 @return a list of point values
 */
- (NSArray*)calculateIntersectionsStartPoint:(NSPoint)StartPoint endPoint:(NSPoint)EndPoint ;

/**
 Calculates the intersection of all Paths with the line between StartPoint and EndPoint
 
 @param StartPoint the first point
 @param EndPoint   the second point
 @param Decompose  indecates if components should be intersected, too.
 
 @return a list of point values
 */
- (NSArray*)calculateIntersectionsStartPoint:(NSPoint)StartPoint endPoint:(NSPoint)EndPoint decompose:(BOOL)Decompose ;

/*! The undoManager of the parent (GSGlyph).
 
 @return An NSUndoManager object.
 */
- (NSUndoManager*)undoManager;

#endif


/*! The glyph to which the layer belongs. Equivalent to the parent property.
 
 @return The GSGlyph object for the layer.
 */
- (GSGlyph*)glyph;

#ifndef GLYPHS_VIEWER

/// Returns the element dicts of all selected elements
- (NSDictionary*)selectedObjects;

+ (NSData*)layerDataFromDict:(NSDictionary*)Dict;

#endif

/*! Returns the bezierpath encoded as NSData.

This is necessary to send the bezierpath over the Distributed Objects Bridge.
@return a bezierpath encoded as NSData.
*/
- (NSData*)bezierData;

#ifndef GLYPHS_VIEWER

/*! Transforms all selected elements.

This applies the Transform to all elements in the selection.
*/
- (void)transformSelection:(NSAffineTransform*)Transform;

- (void)transform:(NSAffineTransform*)Transform checkForSelection:(BOOL)CheckForSelection;

- (void)transform:(NSAffineTransform*)Transform checkForSelection:(BOOL)CheckForSelection doComponents:(BOOL)DoComponents ;

/*! Shifts the layer horizontally
 
 This OtherShifts dict contains the shift values that will be applied to other glyphs at the same time. This is used to prevent diplacemnt of components if the base glyphs are shifted.
 
 @param Shift       The Shift value.
 @param OtherShifts A dict with shift values for the hole shift operation. Keys are glyphs names, value NSNumbers.
 */
- (void)horizontalShift:(CGFloat)Shift otherShifts:(NSDictionary*)OtherShifts;

#endif

- (id)copyThin:(BOOL)Thin;

- (id)copyThin:(BOOL)Thin selection:(BOOL)Selection;

/*! Draw the layer with a pen object
 
 @param Pen An object that conforms to the GSPenProtocol
 */
- (void)drawInPen:(NSObject <GSPenProtocol>*)Pen;

/*! The color for the layer.
 
 This can be a Palette entry (for MS color fonts) or the Master color for color layer fonts
 
 @return the color as NSColor
 */
- (NSColor*)layerColor;
@end
