//
//  VarLibModels.h
//  GSFontTools
//
//  Created by Georg Seifert on 21.09.23.
//  Copyright © 2023 schriftgestaltung.de. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <GSFontTools/TTFont.h>

NS_ASSUME_NONNULL_BEGIN

@interface VarLibModel : NSObject

@property (nonatomic, strong) NSArray *origLocations;
@property (nonatomic, strong) NSArray *axisOrder;
@property (nonatomic) BOOL extrapolate;
@property (nonatomic, strong, nullable) NSDictionary *axisRanges;
@property (nonatomic, strong) NSArray *locations;
@property (nonatomic, readonly) int *mapping;
@property (nonatomic, readonly) int *reverseMapping;
@property (nonatomic, strong) NSDictionary *subModels;
@property (nonatomic, strong) NSArray <NSDictionary *> *supports;
@property (nonatomic, strong) NSArray *deltaWeights;

- (instancetype)initWithLocations:(NSArray <NSDictionary <OTAxisTag, NSNumber *> *> *)locations axisOrder:(nullable NSArray *)axisOrder extrapolate:(BOOL)extrapolate;

+ (NSDictionary *)computeAxisRanges:(NSArray *)locations;

- (NSArray *)reorderMasters:(NSArray *)master_list mapping:(NSArray *)mapping;

- (CGFloat)interpolateFromDeltas:(NSArray<NSNumber *> *)deltas location:(NSDictionary *)loc;

- (CGFloat)interpolateFromMasters:(NSArray<NSNumber *> *)masterValues
						 location:(NSDictionary *)loc
							round:(BOOL)roundFlag;

- (CGFloat)interpolateFromMasters:(NSArray<NSNumber *> *)masterValues
						  scalars:(NSArray<NSNumber *> *)scalars
							round:(BOOL)roundFlag;

/**
 Return multipliers for each master, for the given location.
 If interpolating many master-values at the same location,
 this function allows speed up by fetching the scalars once.
 Note that the scalars used in interpolateFromMastersAndScalars(),
 are *not* the same as the ones returned here. They are the result
 of getScalars().
 */
- (NSArray *)masterScalarsForLocation:(NSDictionary *)targetLocation;

@end

@interface VarLibModel (ListUtils)

+ (BOOL)normalizeValue:(CGFloat)value
			   axisMin:(CGFloat)axisMin
			  axisPeak:(CGFloat)axisPeak
			   axisMax:(CGFloat)axisMax
			  valueMin:(CGFloat *)valueMin
			 valuePeak:(CGFloat *)valuePeak
			  valueMax:(CGFloat *)valueMax;

+ (BOOL)normalizeValue:(CGFloat)value
			   axisMin:(CGFloat)axisMin
			  axisPeak:(CGFloat)axisPeak
			   axisMax:(CGFloat)axisMax
			  valueMin:(CGFloat *)valueMin
			 valuePeak:(CGFloat *)valuePeak
			  valueMax:(CGFloat *)valueMax
		   extrapolate:(BOOL)extrapolate;

+ (CGFloat)deNormalizeValue:(CGFloat)value
					axisMin:(CGFloat)axisMin
				   axisPeak:(CGFloat)axisPeak
					axisMax:(CGFloat)axisMax;

+ (NSDictionary<NSString *, NSNumber *> *)normalizeLocation:(NSDictionary<NSString *, NSNumber *> *)location
													   axes:(NSDictionary<NSString *, NSArray<NSNumber *> *> *)axes
												extrapolate:(BOOL)extrapolate;

+ (CGFloat)supportScalarForLocation:(NSDictionary<NSString *, NSNumber *> *)location
							support:(NSDictionary<NSString *, NSArray<NSNumber *> *> *)support
								 ot:(BOOL)ot
						extrapolate:(BOOL)extrapolate
						 axisRanges:(nullable NSDictionary<NSString *, NSArray<NSNumber *> *> *)axisRanges;

@end

NS_ASSUME_NONNULL_END
