//
//  NSBezierPathHelper.h
//  GlyphsCore
//
//  Created by Georg Seifert on 07.07.19.
//  Copyright © 2019 schriftgestaltung.de. All rights reserved.
//

#import <GlyphsCore/GSDrawPath.h>

NS_ASSUME_NONNULL_BEGIN

typedef NS_CLOSED_ENUM(uint8_t, AMTriangleOrientation) {
	AMTriangleUp = 0,
	AMTriangleDown,
	AMTriangleLeft,
	AMTriangleRight
};

typedef NS_ENUM(uint8_t, INLineArrowStyle) {
	INArrowStyle = 0,
	INCircleStyle,
	INOpenArrowStyle,
	INDiamondStyle,
	INPointYArrowStyle,
};
#ifndef MAC_OS_X_VERSION_14
#ifndef NSBezierPathElementQuadraticCurveTo
#define NSBezierPathElementQuadraticCurveTo 4
#endif
#ifndef NSBezierPathElementCubicCurveTo
#define NSBezierPathElementCubicCurveTo NSBezierPathElementCurveTo
#endif

@interface NSBezierPath (future)
- (CGPathRef)CGPath;
#if !TARGET_OS_IOS
- (void)curveToPoint:(NSPoint)point controlPoint:(NSPoint)controlPoint;
#endif
+ (NSBezierPath *)bezierPathWithCGPath:(CGPathRef)cgPath;
@end
#endif

@interface NSBezierPath (GSDrawPath) <GSDrawPath>

@end

@interface NSBezierPath (Helpers)

+ (NSBezierPath *)bezierPathWithDiamondInRect:(NSRect)rect;

/// Fails if the radius is zero or close to zero.
+ (NSBezierPath *)bezierPathWithRoundedRect:(NSRect)rect cornerRadius:(CGFloat)radius;

+ (NSBezierPath *)bezierPathWithTopRoundedRect:(NSRect)rect radius:(CGFloat)radius;

+ (NSBezierPath *)bezierPathWithRect:(NSRect)rect roundNE:(BOOL)roundNE roundSE:(BOOL)roundSE roundSW:(BOOL)roundSW roundNW:(BOOL)roundNW radius:(CGFloat)radius;

+ (NSBezierPath *)bezierPathWithBottomRoundedRect:(NSRect)rect radius:(CGFloat)radius;

- (void)appendBezierPathWithRoundedRect:(NSRect)rect cornerRadius:(CGFloat)radius;

+ (NSBezierPath *)bezierPathWithTriangleInRect:(NSRect)rect orientation:(AMTriangleOrientation)orientation;

- (void)appendBezierPathWithTriangleInRect:(NSRect)rect orientation:(AMTriangleOrientation)orientation;

+ (NSBezierPath *)bezierPathWithStarInRect:(NSRect)rect;

+ (NSBezierPath *)bezierPathWithLineArrowHeadOfStartPoint:(NSPoint)startPoint endPoint:(NSPoint)endPoint headLineStyle:(INLineArrowStyle)lineHeadStyle width:(CGFloat)width length:(CGFloat)length;

+ (NSBezierPath *)spiralInRect:(NSRect)rect innerRadius:(CGFloat)endRadius;

- (void)strokeInside;

- (void)strokeInsideWithinRect:(NSRect)clipRect;

/// Returns `nil` if the path contains no elements.
- (nullable CGPathRef)quartzPath CF_RETURNS_RETAINED;

- (CGFloat)length;

/**
 Returns the on-curve point for the path element at the given index.

 If the element is of type `NSBezierPathElementClosePath`, then the position of the first element is returned.
 This assumes that the path contains only a single subpath.

 A path with `NSBezierPathElementClosePath` as the first element is considered invalid and `GSPointNull` is returned.
 */
- (NSPoint)positionAtIndex:(NSInteger)idx;

- (nullable NSAffineTransform *)transformWithAngle:(CGFloat)angle center:(CGFloat)center;

/**
 Calculates the area of the path.
 */
- (CGFloat)area;

+ (NSBezierPath *)bezierPathHandlesForCubicSegment:(NSPoint *)segment handleSize:(CGFloat)handleSize;

- (BOOL)isFirstSubpathClockwise;

@end

NS_ASSUME_NONNULL_END
