//
//  GSColorSpace.h
//  GlyphsCore
//
//  Created by Florian Pircher on 04.12.24.
//  Copyright © 2024 schriftgestaltung.de. All rights reserved.
//

#import <GlyphsCore/GSBase.h>

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSUInteger, GSColorSpaceChangeMethod) {
	/// Changes the color space by reinterpreting the component values under the new color space.
	///
	/// The appearance of colors may change when the same components have a different interpretation under the new color space.
	/// Using the method does not introduce rounding errors and can thus be losslessly undone by assigning the previous color space.
	GSColorSpaceChangeMethodAssign,
	/// Changes the color space by updating the component values to maintain their appearance as close as possible under the new color space.
	///
	/// The appearance of colors may change when a color is outside the bounds of new color space.
	/// Using the method does may introduce rounding errors and thus cannot always be losslessly undone by converting to the previous color space.
	GSColorSpaceChangeMethodConvert,
};

@interface GSColorSpace : NSObject

/// Perceptual sRGB.
@property (class, readonly) GSColorSpace *sRGB;
/// Linear sRGB.
@property (class, readonly) GSColorSpace *sRGBLinear;
/// Perceptual Display P3 based on DCI-P3.
@property (class, readonly) GSColorSpace *displayP3;
/// Perceptual generic grayscale color space with γ = 2.2.
@property (class, readonly) GSColorSpace *gray;
/// Perceptual calibrated RGB color space for Apple devices.
///
/// This is the color space used by `+[NSColor colorWithCalibratedRed:green:blue:alpha:]`.
///
/// Avoid using this color space outside of legacy documents.
@property (class, readonly) GSColorSpace *appleRGB;
/// Perceptual calibrated grayscale color space for Apple devices.
///
/// This is the color space used by `+[NSColor colorWithCalibratedWhite:alpha:]`.
///
/// Avoid using this color space outside of legacy documents.
@property (class, readonly) GSColorSpace *appleGray;

@property (nonatomic, readonly) CGColorSpaceRef CGColorSpace CF_RETURNS_NOT_RETAINED NS_SWIFT_NAME(cgColorSpace);

@property (nonatomic, readonly) NSColorSpace *NSColorSpace NS_SWIFT_NAME(nsColorSpace);
/// A string which identifies the color space.
///
/// This tag name is used by ``colorSpaceWithTagName:`` to return a color space matching the name.
@property (nonatomic, readonly, nullable) NSString *tagName;

@property (nonatomic, readonly) NSString *displayName;

- (instancetype)init NS_UNAVAILABLE;

/// Returns a color space matching the given tag name, if any.
///
/// Prefer using the class methods like ``sRGB``.
+ (nullable instancetype)colorSpaceWithTagName:(NSString *)tagName;

+ (instancetype)defaultRGBColorSpaceForFormatVersion:(GSFormatVersion)format;
+ (instancetype)defaultGrayscaleColorSpaceForFormatVersion:(GSFormatVersion)format;

/// Returns a grayscale color space closely matching the receiver.
///
/// Returns `nil` when no such color space is available.
@property (strong, nullable, nonatomic) GSColorSpace *grayscale;

/// Returns an RGB color with the given components in the color space.
///
/// The color space must be using the RGB color space model; otherwise, an exception is thrown.
- (NSColor *)colorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
/// Returns a grayscale color with the given components in the color space.
///
/// The color space must be using the grayscale color space model; otherwise, an exception is thrown.
- (NSColor *)colorWithWhite:(CGFloat)white alpha:(CGFloat)alpha;

@end

NS_ASSUME_NONNULL_END
