//
//  GSFrameView.h
//  Glyphs
//
//  Copyright 2006 schriftgestaltung.de. All rights reserved.
//

@class GSEditViewController;

#define PAGEBORDER 600.0

NS_ASSUME_NONNULL_BEGIN

@interface GSFrameView : NSView

@property (unsafe_unretained, nonatomic) IBOutlet NSTextField *zoomText;
@property (unsafe_unretained, nonatomic, nullable) GSEditViewController *controller;
@property (nonatomic) NSRect glyphFrame;
@property (nonatomic) NSInteger minWidth;
@property (nonatomic) NSSize contentSize;
@property (nonatomic) CGFloat minScrollSize;
@property (nonatomic, readonly) NSRect userVisibleRect;
/// The zoom scale of the view (1.0 = 100%)
@property (nonatomic) CGFloat scale;
@property (nonatomic) CGFloat minimumScale;
@property (nonatomic) CGFloat maximumScale;

- (NSRect)userVisibleRectInSafeArea:(BOOL)inSafeArea;

// MARK: High-Level API

/// Zoom in (scale up).
- (void)zoomIn;

- (void)zoomInKeepingPoint:(NSPoint)center;

/// Zoom out (scale down).
- (void)zoomOut;

- (void)zoomOutKeepingPoint:(NSPoint)center;
/// Zooms the view to 100%.
- (void)zoomToActualSize;
/// Zoom by the desired scaling factor.
///
/// A factor of 2.0 will double the zoom scale, from 100% to 200% say, a factor of 0.5 will zoom out.
/// This also maintains the current visible centre point of the view so the zoom remains stable.
- (void)zoomViewByFactor:(CGFloat)factor;
/// Zooms the view by the given factor and centers the passed point.
///
/// - Parameter factor: Relative zoom factor
/// - Parameter p: A point within the view that should be scrolled to the centre of the zoomed view.
- (void)zoomViewByFactor:(CGFloat)factor andCentrePoint:(NSPoint)p;
/// Zoom to a given absolute value.
///
/// The currently centers point remains centers.
///
/// - Parameter newScale: The desired scaling factor.
- (void)zoomViewToAbsoluteScale:(CGFloat)newScale;
/// Zooms so that the passed rect will fit in the view.
///
/// In general this should be used for a zoom OUT, such as a "fit to window" command, though it will zoom in if the view is smaller than the current frame.
- (void)zoomViewToFitRect:(NSRect)rect;
/// Scrolls the view so that the point ends up visually centers.
///
/// - Parameter aPoint: The desired centre point.
- (void)scrollPointToCentre:(NSPoint)aPoint;

// MARK: Low-Level API

/// Zooms the view to fit the given target rect, optionally centering it.
///
/// - Parameter target: The target rect in view points.
/// - Parameter isCenteringRect: If `YES`, the target rect will be centered in the view.
/// Otherwise, no scrolling is performed.
/// - Parameter inSafeArea: If `YES`, the target rect will be zoomed to fit the safe area of the view (the view bounds excluding the the Info box views).
- (void)zoomViewToRect:(NSRect)target centering:(BOOL)isCenteringRect inSafeArea:(BOOL)inSafeArea;
/// Zooms the view by the given scale in addition to the current scale.
///
/// Compared to ``zoomViewByFactor:``, this method does not restore the center point.
- (void)zoomViewByScale:(CGFloat)zoomScale;
/// Scrolls the position of `point` to the position of `referencePoint` in the view.
/// - Parameter point: The point to scroll to the reference point.
/// The coordinates are in view points.
/// - Parameter referencePoint: The point to scroll to.
/// The coordinates are in view points from the origin (top left) of the visible rect of the clip view excluding inserts.
/// The center reference point, for example, would be the mid-x and mid-y of the user visible frame.
- (void)scrollPoint:(NSPoint)point toReferencePoint:(NSPoint)referencePoint;

- (CGPoint)scrollPointInSafeArea:(BOOL)inSafeArea;
/// The scroll origin the viewport animation is animating towards, or the current scroll origin, when no viewport animation is running.
- (NSPoint)targetScrollPoint;
- (NSPoint)scrollPointFromPoint:(NSPoint)point toReferencePoint:(NSPoint)referencePoint;
/// Updates the scale and origin (scroll point) of the viewport (visible part of the frame).
///
/// Animates to the new scale and/or origin when enclosed in a `NSAnimationContext` with implicit animations enabled.
///
/// The animation duration will be no longer than the duration of the animation context.
/// However, the effective animation duration might be shorter to compensate for minor visual adjustments.
///
/// Existing animations will be modified to retarget the new scale and/or origin.
///
/// - Parameter targetScale: The desired scale. `CGFLOAT_MAX` when the scale should not be changed.
/// - Parameter targetOrigin: The desired origin as returned by `-scrollPointFromPoint:toReferencePoint:`.
///   Use an `x` coordinate of `CGFLOAT_MAX` when the origin should not be changed.
- (void)updateViewportToScale:(CGFloat)targetScale origin:(NSPoint)targetOrigin;

// MARK: Compatibility

@property (nonatomic, readonly) NSRect safeVisibleRect GSDeprecated("userVisibleRectInSafeArea:");
- (IBAction)zoomIn:(id)sender GSDeprecated("zoomIn");
- (IBAction)zoomOut:(id)sender GSDeprecated("zoomOut");
- (IBAction)zoomToActualSize:(id)sender GSDeprecated("zoomToActualSize");
- (IBAction)zoomFitInWindow:(id)sender GSDeprecated("zoomViewToFitRect:");
- (void)zoomViewToSaveRect:(NSRect)rect GSDeprecated("zoomViewToRect:centering:inSafeArea:");
- (void)zoomViewToVisibleRect:(NSRect)rect GSDeprecated("zoomViewToRect:centering:inSafeArea:");

@end

NS_ASSUME_NONNULL_END
/*
 This is a very general-purpose view class that provides some handy high-level methods for doing zooming. Simply hook up
 the action methods to suitable menu commands and away you go. The stuff you draw within drawRect: doesn't need to know or
 care abut the zoom of the view - you can just draw as usual and it works.

 NOTE: this class doesn't bother to support NSCding and thereby encoding the view zoom, because it usually isn't important for this
 value to persist. However, if your subclass wants to support coding, your initWithCoder method should reset _scale to 1.0. Otherwise
 it will get initialized to 0.0 and N0THING WILL BE DRAWN.
 */
