//
//  table__g_l_y_f.h
//  GSFontTools
//
//  Created by Georg Seifert on 01.03.12.
//  Copyright (c) 2012 schriftgestaltung.de. All rights reserved.
//

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

@class OTOrderedDictionary;
@class GSFileData;
@class Glyph_g_l_y_f;
@class TTProgram;
@class FTPointArray;
@class GSIntArray;
@class OTBasePen;

typedef enum : u_int8_t {
	TTGlyfFlagOnCurve = 0x01,
	TTGlyfFlagXShort = 0x02,
	TTGlyfFlagYShort = 0x04,
	TTGlyfFlagRepeat = 0x08,
	TTGlyfFlagXsame = 0x10,
	TTGlyfFlagYsame = 0x20,
	TTGlyfFlagOverlapSimple = 0x40,
} TTGlyfGlyphFlags;

typedef enum : u_int16_t {
	TTGlyfComponentFlagARG_1_AND_2_ARE_WORDS = 0x0001, // if set args are words otherwise they are bytes

	TTGlyfComponentFlagARGS_ARE_XY_VALUES = 0x0002,		   // if set args are xy values, otherwise they are points
	TTGlyfComponentFlagROUND_XY_TO_GRID = 0x0004,		   // for the xy values if above is true
	TTGlyfComponentFlagWE_HAVE_A_SCALE = 0x0008,		   // Sx = Sy, otherwise scale == 1.0
	TTGlyfComponentFlagNON_OVERLAPPING = 0x0010,		   // set to same value for all components (obsolete!)
	TTGlyfComponentFlagMORE_COMPONENTS = 0x0020,		   // indicates at least one more glyph after this one
	TTGlyfComponentFlagWE_HAVE_AN_X_AND_Y_SCALE = 0x0040,  // Sx, Sy
	TTGlyfComponentFlagWE_HAVE_A_TWO_BY_TWO = 0x0080,	   // t00, t01, t10, t11
	TTGlyfComponentFlagWE_HAVE_INSTRUCTIONS = 0x0100,	   // instructions follow
	TTGlyfComponentFlagUSE_MY_METRICS = 0x0200,			   // apply these metrics to parent glyph
	TTGlyfComponentFlagOVERLAP_COMPOUND = 0x0400,		   // used by Apple in GX fonts
	TTGlyfComponentFlagSCALED_COMPONENT_OFFSET = 0x0800,   // composite designed to have the component offset scaled (designed for Apple)
	TTGlyfComponentFlagUNSCALED_COMPONENT_OFFSET = 0x1000, // composite designed not to have the component offset scaled (designed for MS)
} TTGlyfComponentFlags;

@interface table__g_l_y_f : TTable
@property (nonatomic, retain) OTOrderedDictionary *glyphs;

- (NSUInteger)countOfGlyphs;
- (NSString *)glyphNameAtIndex:(NSUInteger)glyphID;
- (NSUInteger)indexOfGlyphName:(NSString *)glyphName;
- (Glyph_g_l_y_f *)glyphAtIndex:(NSUInteger)glyphID;
- (Glyph_g_l_y_f *)glyphForName:(NSString *)glyphName;
- (void)addGlyph:(Glyph_g_l_y_f *)glyph forKey:(NSString *)glyphName;

@end

/*
@interface TTNode : NSObject {
	NSPoint _position;
	u_int8_t _flags;
}
@property (nonatomic, assign) NSPoint position;
@property (nonatomic, assign) u_int8_t flags;
@end
*/

@interface GlyphComponent_g_l_y_f : NSObject {
	NSAffineTransformStruct _transformStruct;
	NSString *_glyphName;
	BOOL _haveInstructions;
	BOOL _more;
	u_int16_t _flags;
	u_int16_t _glyphID;
	NSUInteger _firstPt;
	NSUInteger _secondPt;
}
@property (nonatomic, retain) NSString *glyphName;
@property (nonatomic, assign) u_int16_t glyphID;
@property (nonatomic, assign) NSAffineTransformStruct transformStruct;
@property (nonatomic, assign) BOOL haveInstructions;
@property (nonatomic, assign) BOOL more;
@property (nonatomic, assign) u_int16_t flags;
@property (nonatomic, assign) NSUInteger firstPt;
@property (nonatomic, assign) NSUInteger secondPt;

- (BOOL)decompile:(GSFileData *)data glyfTable:(table__g_l_y_f *)glyfTable;
- (NSData *)compileComponents:(table__g_l_y_f *)glyfTable more:(BOOL)more haveInstructions:(BOOL)haveInstructions error:(NSError **)error;
- (void)toXML:(GSXMLWriter *)writer font:(TTFont *)font;

@end

@interface Glyph_g_l_y_f : NSObject {
	NSData *_data;
	short _numberOfContours;
	FTPointArray *_coordinates;
	NSMutableArray<GlyphComponent_g_l_y_f *> *_components;
	GSIntArray *_endPtsOfContours;
	GSIntArray *_flags;
	NSRect _bounds;
	NSInteger _width;
	TTProgram *_program;
	NSString *_name;
}
@property (nonatomic, retain) NSData *data;
@property (nonatomic) short numberOfContours;
@property (nonatomic, retain) FTPointArray *coordinates;
@property (nonatomic, retain) NSMutableArray<GlyphComponent_g_l_y_f *> *components;
@property (nonatomic, retain) TTProgram *program;
@property (nonatomic, retain) GSIntArray *endPtsOfContours;
/// one flag per coordinate
@property (nonatomic, retain) GSIntArray *flags;
@property (nonatomic, assign) NSRect bounds;
@property (nonatomic, assign) NSInteger width;
@property (nonatomic, retain) NSString *name;

- (id)initWithData:(NSData *)data;
- (NSData *)compile:(id)glyfTable recalcBBoxes:(BOOL)recalcBBoxes error:(NSError **)error;
- (void)toXML:(GSXMLWriter *)writer font:(TTFont *)font;
- (void)expand:(table__g_l_y_f *)glyfTable;
- (void)decompileComponents:(NSData *)data glyfTable:(table__g_l_y_f *)glyfTable;
- (BOOL)isComposite;
- (int)lsb:(table__g_l_y_f *)glyfTable;
- (int)rsb:(table__g_l_y_f *)glyfTable;
- (void)draw:(OTBasePen *)pen lsb:(CGFloat)lsb;
- (void)recalcBounds:(table__g_l_y_f *)glyfTable;
@end
