//
//  GSComponent.h
//  Glyphs
//
//  Created by Georg Seifert on 30.3.08.
//  Copyright 2008 schriftgestaltung.de. All rights reserved.
//

#import <Cocoa/Cocoa.h>
#import "GSElement.h"

@class GSGlyph;
@class GSFont;
@class GSLayer;
@class GSNotifyingDictionary;

/// This class defines the component object. It is a subclass of GSElement

@interface GSComponent : GSElement {
	NSString* componentName;
	GSGlyph* component;
@public
	NSAffineTransformStruct transformStruct;
	NSString* anchor;
	BOOL disableAlignment;
	BOOL locked;
	CGFloat _keepWeight;
	GSLayer* _cachedLayer;
	NSDate* _lastChange;
}
/** components are referenced by the glyph name.

If you set the componentName the component value is set and this is used during runtime. So you can change the glyph name of the base glyph during runtime.
*/
@property (strong, nonatomic) NSString* componentName;

/** The base glyph

This is readonly. To set the base glyph use componentName: newBaseGlyph.name.
@see componentName
*/
@property (unsafe_unretained, readonly) GSGlyph* component;

/** The transformation of the component.

The values of the struct are:
{m11, m12, m21, m22, tX, tY}
this is equivalent to the glif attributes
{xScale, xyScale, yxScale, yScale, xOffset, yOffset}
in the same order.
The initial value is {1,0,0,1,0,0}.
*/
@property (assign, nonatomic) NSAffineTransformStruct transformStruct;

/** If more than once anchor/_anchor pair would match this property can be used to set the anchor to use
 
 This can be set from the anchor button in the component info box in the UI
 */
@property (copy, nonatomic) NSString* anchor;
@property (assign, nonatomic) CGFloat keepWeight;

@property (nonatomic, assign) BOOL disableAlignment;
@property (nonatomic) BOOL locked;
@property (strong, nonatomic) GSNotifyingDictionary * pieceSettings;

/** The bounds of the components
 
 @return the bounds
 */
- (NSRect) bounds;

/// The bezierPath of the component. It is already transformed.
- (NSBezierPath*)bezierPath;

/// The bezierPath of open paths of the component. It is already transformed.
- (NSBezierPath*)openBezierPath;

- (NSData*)bezierData;

- (void)updateComponentGlyph;

/** The Layer that the component is linked to.
 
 The is usually just the layer from the components glyph but might be the computed result of a smart component.
 
 @return the Layer that represents the component.
 */
- (GSLayer*)componentLayer;

/** Retunes on reference the scale and rotation of the component
 
 This will take apart the transformStruct.
 
 This might not work correctly if you have applied a skew transform.
 
 @param sX On return, the horizontal scale
 @param sY On return, the vertical scale
 @param R  On return, the rotation
 */
- (void)getScaleX:(CGFloat*)sX scaleY:(CGFloat*)sY rotation:(CGFloat*)R;

#ifndef GLYPHS_VIEWER

/** Sets the transformation.
 
 @param sX the horizontal scale
 @param sY the vertical scale
 @param R  the rotation
 */
- (void)setScaleX:(CGFloat)sX scaleY:(CGFloat)sY rotation:(CGFloat)R;

/** Decomposes the component to the containing Layer

It need to parent property set correctly. It calls `[_parent decomposeComponent:self]`.
*/
- (void)decompose;

#ifndef GLYPHS_LITE

/** If the component overlaps with the OtherComponent
 
 @param OtherComponent The OtherComponent to test overlap.

 @return Returns YES if both components do overlap, otherwise NO.
 */
- (BOOL)intersects:(GSComponent*)OtherComponent;

#endif

/** It makes the component the first in the containing Layer

It need to parent property set correctly. It calls `[_parent makeFirstComponent:self]`.
*/
- (void)makeFirst;

- (void)makeDisableAlignment;

- (void)makeEnableAlignment;
#endif
@end
