//
//  GSColorLine.h
//  GlyphsCore
//
//  Created by Florian Pircher on 17.03.23.
//  Copyright © 2023 schriftgestaltung.de. All rights reserved.
//

@class GSGradient;
@class GSColorSpace;
@class GSColorStop;

#import <GlyphsCore/GSPaletteColor.h>

NS_ASSUME_NONNULL_BEGIN

/// A color line is a sorted collection of color stops used to describe a gradient.
///
/// A rendition of the color line uses interpolation to determine the color values between the color stops.
/// Color values are interpolated by linearly interpolating the color components in the linear sRGB color space.
@interface GSColorLine : NSObject <NSCopying>

@property (nonatomic, weak) GSGradient *parent;

/// The color stops of the color line.
///
/// The color stops are sorted by their offset.
/// The array contains at least two color stops: the start color stop and the end color stop.
@property (nonatomic, copy) NSArray<GSColorStop *> *colorStops;
/// The color space in which to perform interpolation of the color stops.
///
/// Note that this color space does not need to match the color space of the color stops themselves.
///
/// The default color space is linear sRGB.
@property (strong) GSColorSpace *colorSpace;

/// Creates a color line with the given color stops.
///
/// Returns `nil` if there are less then two color stops or the first/last color stop does not have an offset of 0/1.
- (nullable instancetype)initWithColorStops:(NSArray<GSColorStop *> *)colorStops NS_DESIGNATED_INITIALIZER;

/// Creates a color line that represented a subtle color sharing based on a single color.
- (instancetype)initWithBaseColor:(NSColor *)baseColor;

/// Creates a color line with the most recently registered color line.
///
/// Register a color line with `+[GSColorLine setRecentColorLine:]`.
- (instancetype)init;

/// Register a color line as the most recently used color line for future reuse with `-[GSColorLine init]`.
+ (void)setRecentColorLine:(GSColorLine *)colorLine;

- (NSUInteger)countOfColorStops;

- (nullable GSColorStop *)objectInColorStopsAtIndex:(NSUInteger)idx;

- (void)removeObjectFromColorStopsAtIndex:(NSUInteger)index;

/// Returns a new color line with equivalent color stops but in reversed order.
///
/// The relative distances between color stops are maintained.
@property (nonatomic, readonly) GSColorLine *reversedColorLine;

- (CGGradientRef)CGGradientForEnvironment:(GSDrawEnvironment *)environment CF_RETURNS_RETAINED;

/// Returns a new color line representing the part of the receiver between `min` and `max`.
///
/// If no color stops exist at the `min` or `max` offset, then new color stops will be interpolated and inserted as the start and end color stops.
/// Color stops outside the range are not included in the new color line.
- (GSColorLine *)colorLineClippedFrom:(CGFloat)min to:(CGFloat)max;

/// Returns a new color line equal to this color line except all color stop offsets are scaled by a given factor.
///
/// The factor must be in the range `0`–`1` where a scale with a factor of `1` returns this color line.
///
/// A scale with a factor less than `1` returns a new color line where the scale factor has been applied to all color stops.
/// This color line contains an additional color stop at offset `1` with the same color as the first color stop.
- (GSColorLine *)colorLineScaledBy:(CGFloat)factor;

/// See the docs for the equivalent method on ``GSFont``.
- (void)transformColorsUsingBlock:(NSColor *(^)(NSColor *))block;

- (BOOL)isEqualToColorLine:(GSColorLine *)colorLine;

- (void)elementDidChange:(id)element;

@end

NS_ASSUME_NONNULL_END
