//
//  GSFont.h
//  Glyphs
//
//  Created by Georg Seifert on 21.10.05.
//  Copyright 2005 schriftgestaltung.de. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "MGOrderedDictionary.h"

@class GSGlyph;
@class GSDocument;
@class GSFontMaster;
@class GSInstance;
@class GSFeature;
@class GSClass;
@class COFont;
//@class PyObject;

typedef enum {
	Regular,
	Light,
	Bold,
	Condensed,
	Extended,
	LightCondensed,
	LightExtended,
	BoldCondensed,
	BoldExtended
} GSLayerTypes;

typedef enum {
	NotTested = 0,
	NoFigures = 1,
	tosf = 2,	
	osf = 3,
	tf = 4,
	lf = 5
} GSFigureStyles;

/** This class defines the font object.
 
 Font info properties, that have a user interface, have proper accessors, eveything else can be accesed with valueForKey: and setValue:forKey:
 */

@interface GSFont : NSObject <NSCoding, NSCopying> {
	GSDocument				*_parent;
	NSMutableArray			*_glyphs;
	
	NSString				*_familyName;
	NSUInteger				_unitsPerEm;
	NSDate					*_date;
	NSUInteger				_versionMajor;
	NSUInteger				_versionMinor;
	NSString				*_designer, *_designerURL, *_manufacturer, *_manufacturerURL, *_copyright;
	
	
	MGOrderedDictionary		*_fontInfoDict;
	NSMutableArray			*_fontMasters;
	NSMutableArray			*_features;
	NSMutableArray			*_instances;
	NSMutableDictionary		*_userData;
	NSMutableDictionary		*_tempData;
	NSMutableDictionary		*_charsCache;
	UTF32Char				_lastChar;
	//NSDictionary			*_replaceGlyphs;
	NSMutableDictionary		*_kerning;
	NSUInteger				_gridLength;
	BOOL					_disablesNiceNames;
	//NSArrayController		*glyphsController;
//	NSMutableDictionary		*changeCount;
	NSMutableDictionary		*name2Glpyh;
	NSMutableArray			*GlyphDictArray;
	NSMutableArray			*_classes;
	NSMutableArray			*_featurePrefixes;
	NSString				*_tempOTFFont;
	COFont *				_compositorFont;
//	NSMutableDictionary		*_tempData;
	NSMutableDictionary	*	_tempOTFNames;
	BOOL					_disabledChanges;
	NSMutableSet			* _disabledChangeKeys;
	//NSMutableArray *		_supportedScripts;
	NSDate *				_lastAskedForImage;
}
//! The pointer to the document object
@property(assign, nonatomic) GSDocument * parent;

//! An Array of GSGlyph objects
@property(retain, nonatomic) NSArray * glyphs;

//! A Dictionary containing additionally font info.
@property(retain, nonatomic) MGOrderedDictionary * fontInfoDict;

//! An array of the fonts Masters definitions
@property(retain, nonatomic) NSArray * fontMasters;
//! An array of GSFeature objects.
@property(retain, nonatomic) NSArray * features;
//! an array of classes
@property(retain, nonatomic) NSArray * classes;
@property (nonatomic, retain) NSMutableArray *featurePrefixes;
//! An array of GSInstance objects. This define export settings for interpolation and naming.
@property(retain, nonatomic) NSArray * instances;
//! Returns the content of the font object to store it in pList.
/**
 This is used to store the data in the .glyphs file.
 */
@property(readonly, nonatomic) NSMutableDictionary * fontDict;
//! The (family) name of the font.
@property(retain, nonatomic) NSString * familyName;

@property(retain, nonatomic) NSString * note;

/// unitsPerEm (UPM).
@property(assign, nonatomic) NSInteger unitsPerEm;

/// copyright
@property(retain, nonatomic) NSString *copyright;

/// designer
@property(retain, nonatomic) NSString *designer;

/// designerURL
@property(retain, nonatomic) NSString *designerURL;

/// manufacturer
@property(retain, nonatomic) NSString *manufacturer;

/// manufacturerURL
@property(retain, nonatomic) NSString *manufacturerURL;

/// versionMajor
@property(assign, nonatomic) NSUInteger versionMajor;

/// versionMinor
@property(assign, nonatomic) NSUInteger versionMinor;

/// The font date
@property(retain, nonatomic) NSDate * date;

/** the Kerning of the Font

 1) A Dict for each FontMaster (FontMaster id as key)
 2) The Dict contains an entry for each glyph (the glyphID or GroupName (@MMK_L_XXX) is used as key)
 3) These entries hold the values: glyphID or GroupName (@MMK_R_XXX) as key, kerning as value.
 */
@property(retain, nonatomic) NSMutableDictionary * kerning;
/** Place for plugins to store custom data.

 Here it is possible to store something. Please use a unique key.
 The objects should be able to serialize to a plist. If they are not, they should return all infos to store in description (as String).
 */
@property(retain, nonatomic) NSMutableDictionary * userData;

@property (nonatomic, retain) NSMutableDictionary *tempData;
/** The size of the grid.

 if it is "0", all values are stored as floats. "1" and above will ALWAYS round the coordinates.
 */
@property NSUInteger gridLength;
//@property (nonatomic, retain) NSMutableArray *supportedScripts;
/** disablesNiceNames

 This is to prevent the automatic glyph name substitution.
 */
@property BOOL disablesNiceNames;

@property (nonatomic, retain) NSString *tempOTFFont;
@property (nonatomic, retain) COFont *compositorFont;
@property (nonatomic, retain) NSMutableDictionary *tempOTFNames;

@property (nonatomic, retain) NSMutableSet *disabledChangeKeys;

/** @name Creating and Initializing a GSFont object */
/** initialises a font with a dictionary loaded from a pList.

 @param fontDict A dictionary
 */
- (id) initWithFontDict:(NSDictionary *) fontDict;
- (BOOL) saveToFile:(FILE*) File error:(NSError**) error; 
/** @name Font Methods */

/** Scale the hole font.

 @param multiplyer for scale the font (glyphs, kerning and metrics)
 */
- (void) scaleBy:(CGFloat) Scale ;

#pragma mark glyphs
/** @name Glyphs */
/** Returns the count of glyphs in the font */
- (NSUInteger) count;

/** Returns the glyph object located at index.
 
 @param Index An index within the bounds of the the glyphs array.
 @return a GSGlyph object.
 */
- (GSGlyph *) glyphAtIndex:(NSInteger) Index;
/** Returns the index of the glyph.*/
- (NSInteger) indexOfGlyph:(GSGlyph *) Glyph ;
/** Returns the GSGlyph with this name.

 @warning This is a bit slow.

 @param Name the name of the glyph.
 @return a GSGlyph object.
 */
- (GSGlyph *) glyphForName:(NSString * ) Name;
- (void) setCacheGlyphs:(BOOL) CacheGlyphs;
- (GSGlyph *) glyphForUnicode:(NSString * ) Unicode;
//- (void) addGlyphWithName:(NSString*) GlyphName;
- (GSGlyph*) newGlyphWithName:(NSString*) GlyphName ;
- (GSGlyph*) newGlyphWithName:(NSString*) GlyphName changeName:(BOOL) ChangeName ;
- (NSString*) saveNameForGlyph:(GSGlyph*) Glyph ;
- (NSString*) saveNameForName:(NSString*) GlyphName ;
/** Returns the GSGlyph with this ID.

 @warning This is a bit slow.
 
 @param Id the ID of the glyph.
 @return a GSGlyph object.
 */
- (GSGlyph *) glyphForId:(NSString * ) Id;

- (BOOL) keepsGlyphs:(NSArray*) Glyphs ;
// Returns a Boolean value if the font contains the glyph.
- (BOOL) hasGlyphs:(NSArray*) Glyphs ;

- (NSArray*) filterGlyphs:(NSArray*) GlyphNames ;
/** Returns the glyph with the chars unicode.

@param Char A (unicode) char.
@return a GSGlyph object
@sa characterForGlyph
 */
- (GSGlyph *) glyphForCharacter:(UTF32Char) Char;

/** Returnes a UTF32Char for the glyph.

It uses the unicode to find the char value. For unencoded glyphs it returns a cached PUA value.

@param Glyph a GSGlyph object
@return a UTF32Char
@sa glyphForCharacter:
*/
- (UTF32Char) characterForGlyph:(GSGlyph*) Glyph;

- (NSInteger) indexForGlyphWithName:(NSString *) Name; // Wird nicht verwendet ????

/** Addes the GSGlyph object to the font.

@param Glyph A GSGlyph Object.
 */
- (void) addGlyph:(GSGlyph *) Glyph;

/** Inserts the GSGlyph objects at the specified indexes to the font.

@param Glyph A GSGlyph Object.
@param indexes A NSIndexSet 
 */
//- (void) insertGlyphs:(NSArray *)newGlyphs atIndexes:(NSIndexSet *)indexes ;

/** Removes the GSGlyph from the font

@param Glyph A GSGlyph to remove from the font.
 */
- (void) removeGlyph:(GSGlyph*) Glyph;

- (void) sortGlyphs ;
/** returnes if the Glyph will be exported or not.

@param Glyph The Glyph object
 */
//- (BOOL) keepGlyph:(GSGlyph*) Glyph ;
- (NSUndoManager*) undoManager ;
- (void) elementDidChange:(id) element ;

#pragma mark fontInfoDict accessors

- (NSUInteger) countOfFontInfoDict;
- (id)objectInFontInfoDictAtIndex:(NSUInteger)theIndex;
- (id)objectInFontInfoDictForKey:(id)Key ;
- (void)insertObject:(id)obj inFontInfoDictForKey:(id) Key atIndex:(NSUInteger)theIndex;
- (void)insertObject:(id)obj inFontInfoDictForKey:(id)Key;
- (void)removeObjectFromFontInfoDictAtIndex:(NSUInteger)theIndex;
- (void)removeObjectFromFontInfoDictForKey:(id) Key;

//- (NSArray*) familyBlueValues ;
//- (NSArray*) familyOtherBlues ;
- (NSMutableArray*) openTypeOS2Panose ;
#pragma mark masters
/** @name Masters */

/** The count of defined layers in the font.

@return The number of layers currently in the font.
 */
- (NSInteger) countOfFontMasters;

- (NSInteger) masterCount;

/** Returns the fontmaster located at the index

 @param Index An index within the bounds of the receiver.
 @return A GSFontMaster instance.
 */
- (GSFontMaster *) fontMasterAtIndex:(NSInteger) Index;

/** Returns the fontmaster with this id

 @param Id The ID of the font master. This is supposed to be a Unique id
 @return A GSFontMaster instance.
 */
- (GSFontMaster *) fontMasterForId:(NSString*) Id;
/** Insterts the FontMaster at Index */
- (void) insertFontMaster:(GSFontMaster*)FontMaster atIndex:(NSUInteger)theIndex ;
/** Adds the Fontmaster to the font */
- (void) addFontMaster:(GSFontMaster*) FontMaster ;
/** removes the FontMaster */
- (void) removeFontMaster:(GSFontMaster*) FontMaster ;
- (void) replaceFontMasterAtIndex:(NSUInteger)theIndex withFontMaster:(GSFontMaster*)FontMaster ;
/** Removes the fontmaster with this id

 @param Index The index of the FontMaster to remove.
 */
- (void) removeFontMasterAtIndex:(NSInteger) Index ;

- (void) updateMetrics:(NSNotification *)notification;
#pragma mark instances

/** @name Instances */
/** Returns the count of the Instances 

 @return The number of Instances currently in the Font.
 */
- (NSUInteger) countOfInstances ;

/** Returns the Instance at index
 
 @param index The index of the instance.
 @return The Instance located at _index_.
 */
- (GSInstance*) instanceAtIndex:(NSUInteger) index ;

/** Insterts the instance at Index
 
 @param Instance The instance to instert.
 @param index The _index_ at what to insert the _instance_.
 */
- (void) insertInstance:(GSInstance*) Instance atIndex:(NSUInteger) index ;

/** Adds the Instance
 
 @param Instance The Instance to add to the font.
 */
- (void) addInstance:(GSInstance*)Instance ;

/**
	Removes the Instance at Index.
 
	@param index The of the Instance to be removed.
 */
- (void) removeInstanceAtIndex:(NSUInteger) index ;

- (void) replaceInstanceAtIndex:(NSUInteger) theIndex withInstance:(GSInstance*) Instance ;

- (GSFontMaster*) interpolateFontMaster: (GSInstance*) Instance;
/** Generates an instance

 It returnes a new GSFont object with one master interpolated all glyphs/layers according to the settings in Instance.
 
 @param Instance The Instance to use for interpolation.
 */
- (GSFont *) copyInterpolateInstance: (GSInstance*) Instance error:(NSError**) Error ;
//- (GSFont *) copyInterpolateInstance: (GSInstance*) Instance ;

#pragma mark kerning
/** @name Kerning */
- (NSDictionary*) kerningDict ;
/** Compresses the kerning

 if a GSGlyph has a Kerning Group and Direct Kerning, the Kerning is changed to Class Kerning.
 */
- (void) compressKerning ;
/** returnes a kerning value
 
 @param FontMasterID The Master id
 @param LeftKey either a glyph id or a glyph group (@MM_L_XXX)
 @param RightKey either a glyph id or a glyph group (@MM_R_XXX)
 @return the kerning value
 */
- (CGFloat) kerningForFontMasterID:(id) FontMasterID LeftKey:(id) LeftKey RightKey:(id) RightKey ;

/** adds a kerning value

 @param FontMasterID The Master id
 @param LeftKey either a glyph id or a glyph group (@MM_L_XXX)
 @param RightKey either a glyph id or a glyph group (@MM_R_XXX)
 @param Value the kerning value
 */
- (void) setKerningForFontMasterID:(id) FontMasterID LeftKey:(id) LeftKey RightKey:(id) RightKey Value:(CGFloat) Value ;

/** removes a kerning value

 @param FontMasterID The Master id
 @param LeftKey either a glyph id or a glyph group (@MM_L_XXX)
 @param RightKey either a glyph id or a glyph group (@MM_R_XXX)
 */
- (void) removeKerningForFontMasterID:(id) FontMasterID LeftKey:(id) LeftKey RightKey:(id) RightKey ;

#pragma mark features

/** @name Features */
- (NSMutableArray*) mutableFeatures ;
/** Returns the count of the features
 
 @return The number of features in the Font.
 */
- (NSUInteger) featuresCount ;

/** Returns the feature at index
 
 @param index The index of the feature
 @return The feature located at _index_.
 */
- (id) featureAtIndex:(NSUInteger)theIndex ;
//! Insters the Feature at theIndex
- (void) insertFeature:(GSFeature*)Feature atIndex:(NSUInteger)theIndex ;
//! Adds the Feature
- (void) addFeature:(GSFeature*)Feature ;
//! Removes the Feature at theIndex
- (void) removeFeatureAtIndex:(NSUInteger)theIndex ;
- (void) removeFeature:(GSFeature*) Feature ;
- (void) replaceFeatureAtIndex:(NSUInteger)theIndex withFeature:(GSFeature*)Feature ;

/** Returnes the feature with the name or tag.

@param Tag The feature tag (like "smcp")
 */
- (GSFeature *) featureForTag: (NSString*) Tag;

#pragma mark Classes 
/** @name Classes */
- (NSMutableArray*) mutableClasses ;
//! Returns the count of the classes
- (NSUInteger) countOfClasses ;
- (id) objectInClassesAtIndex:(NSUInteger)theIndex ;

/** Returnes the class with the name.

@param Tag The class tag.
 */
- (GSClass *) classForTag: (NSString*) Tag ;
//- (void) getClasses:(id *)objsPtr range:(NSRange)range ;
/** Adds the class */
- (void) addClass:(GSClass*)theClass ;
- (void) insertObject:(GSClass*)obj inClassesAtIndex:(NSUInteger)theIndex ;
- (void) removeObjectFromClassesAtIndex:(NSUInteger)theIndex ;
- (void) removeClass: (GSClass*) obj ;
- (void) replaceObjectInClassesAtIndex:(NSUInteger)theIndex withObject:(GSClass*)obj;
/** Add the class from the text
 
@param Text the class in FDK syntax
 */
- (void) addClassFromCode:(NSString *) Text ;
#pragma mark featurePrefixes
- (void) addFeaturePrefix:(GSClass*)obj;
- (NSUInteger) countOfFeaturePrefixes ;
- (GSClass *) featurePrefixForTag: (NSString*) Tag;
- (void) insertObject:(id)obj inFeaturePrefixesAtIndex:(unsigned)theIndex;
- (void) removeFeaturePrefix:(GSClass*) obj;
#pragma mark display
- (NSString*) charStringFromDisplayString:(NSString *) String ;
- (void) setUndoValue:(id)value forKey:(NSString *)key ;
- (void) disableUpdateInterface;
- (void) enableUpdateInterface;
- (BOOL) isUpdateInterfaceEnabled;
- (void) updateInterface;
#pragma mark Metrics
- (BOOL) importAFM:(NSString*) AFMString fontMaster:(GSFontMaster*) FontMaster metrics:(BOOL) doMetrics kerning:(BOOL) doKerning error:(NSError**) error;
- (BOOL) compileTempFontError:(NSError**) theError ;
//- (NSString*) composeString:(NSString*) String features:(NSArray*) Features ;
//- (NSAttributedString*) composeString:(NSAttributedString*) String features:(NSArray*) Features ;
//- (NSArray *)supportedScripts ;
//- (NSUInteger) countOfSupportedScripts;
//- (id) supportedScriptAtIndex:(unsigned)theIndex;
//- (void) getSupportedScripts:(id *)objsPtr range:(NSRange)range ;
//- (void) insertObject:(id)obj inSupportedScriptsAtIndex:(unsigned)theIndex ;
//- (void) addSupportedScript:(NSString*) SupportedScript;
//- (void) removeSupportedScript:(NSString*) SupportedScript;
//- (void) removeSupportedScriptsAtIndex:(unsigned)theIndex ;
//- (void)removeObjectFromSupportedScriptsAtIndex:(unsigned)theIndex ;
	
@end
