//
//  GSHobbyNodeInfo.h
//  GlyphsCore
//
//  Created by Florian Pircher on 24.06.22.
//  Copyright 2022 schriftgestaltung.de. All rights reserved.
//

#import <GlyphsCore/GSBase.h>

NS_ASSUME_NONNULL_BEGIN

static const CGFloat GSHobbyNodeTensionMin = 0.01; // 1 %
static const CGFloat GSHobbyNodeTensionMax = 1000; // 100_000 %
static const CGFloat GSHobbyNodeTensionUnset = -1;

extern NSString *GSHobbyLeadingFollowKey;
extern NSString *GSHobbyLeadingFollowKey;
extern NSString *GSHobbyTrailingFollowKey;
extern NSString *GSHobbyLeadingDirectionKey;
extern NSString *GSHobbyTrailingDirectionKey;
extern NSString *GSHobbyLeadingTensionKey;
extern NSString *GSHobbyTrailingTensionKey;

@class GSNode;
@class GSFontMaster;

typedef NS_ENUM(int8_t, GSHobbyFollow) {
	GSHobbyFollowUnset = -1,
	/// Follow  no external geometry and use automatic direction instead.
	GSHobbyFollowAutomatic = 0,
	/// Follow  a fixed angle relative to the baseline.
	GSHobbyFollowFixed = 1,
	/// Follow baseline horizontally and italic angle vertically.
	GSHobbyFollowMetrics = 2,
	/// Follow x-axis horizontally and y-axis vertically.
	GSHobbyFollowAxes = 3,
	/// Follow italic angle vertically.
	GSHobbyFollowVerticalMetric = 4,
	/// Follow y-axis vertically.
	GSHobbyFollowVerticalAxis = 5,
	/// Follow x-axis horizontally.
	GSHobbyFollowHorizontalAxis = 6,
};

@interface GSHobbyNodeInfo : NSObject <NSCopying>
@property (nonatomic, weak) GSNode *parent;
@property (nonatomic) GSHobbyFollow leadingFollow;
@property (nonatomic) GSHobbyFollow trailingFollow;
@property (nonatomic) CGFloat leadingDirection;
@property (nonatomic) CGFloat trailingDirection;
@property (nonatomic) CGFloat leadingTension;
@property (nonatomic) CGFloat trailingTension;
@property (nonatomic, readonly) BOOL isDefault;
/// Whether the leading and trailing info is in sync (equal values on both side). A Hobby node might still have a split knob if the node is not smooth.
@property (nonatomic, readonly) BOOL isInSync;

- (instancetype)initWithDict:(NSDictionary *)dict format:(GSFormatVersion)formatVersion;

- (id)propertyListValueFormat:(GSFormatVersion)format error:(out NSError **)error;

+ (GSHobbyFollow)defaultFollowForMaster:(nullable GSFontMaster *)master;
+ (CGFloat)defaultTensionForMaster:(nullable GSFontMaster *)master;
+ (GSHobbyNodeInfo *)defaultInfoForNode:(GSNode *)node inMaster:(nullable GSFontMaster *)master;
+ (GSHobbyNodeInfo *)defaultInfoForNode:(GSNode *)node;

- (BOOL)isEqualToHobbyNodeInfo:(GSHobbyNodeInfo *)info;
/// Syncs the leading and trailing values in case the parent node is smooth. Call this method if the connection type of the parent node changed to `SMOOTH`.
- (void)update;

- (void)setFollow:(GSHobbyFollow)follow;
- (void)setDirection:(CGFloat)direction;
- (void)setTension:(CGFloat)tension;
@end

NS_ASSUME_NONNULL_END
