
NS_ASSUME_NONNULL_BEGIN

/// Controls how subviews are positioned horizontally within each row.
typedef NS_ENUM(NSInteger, FlowViewAlignment) {
	/// Subviews are packed toward the leading edge. (Default)
	FlowViewAlignmentLeading = 0,
	/// Each row is centered horizontally within the available width.
	FlowViewAlignmentCenter = 1,
	/// Slack space is distributed across each full row. Views whose horizontal
	/// content-hugging priority is below NSLayoutPriorityDefaultHigh (750) are
	/// stretched to absorb the slack. If no view on the row is stretchable the
	/// slack is distributed as extra gap between views instead.
	/// The last (incomplete) row always falls back to leading alignment.
	FlowViewAlignmentJustified = 2,
};

/// A view that arranges its managed subviews in a left-to-right, wrapping flow
/// layout — similar to NSStackView but multi-line. The view sizes itself to the
/// height required to fit all subviews at the current width.
///
/// Pin the view's width with a constraint (or let a parent dictate it).
/// The height will be driven by intrinsicContentSize automatically.
///
/// Subviews can be added either programmatically via -addArrangedSubview: or
/// directly in Interface Builder. IB-added subviews are picked up automatically
/// in -awakeFromNib in the order they appear in the XIB.
///
/// All subviews must have a fixed size either via their own intrinsicContentSize
/// or via explicit width/height constraints attached to the subview itself.
IB_DESIGNABLE
@interface GSFlowView : NSView

/// Horizontal gap between subviews on the same row. Default: 8.
@property (nonatomic, assign) IBInspectable CGFloat horizontalSpacing;

/// Vertical gap between rows. Default: 8.
@property (nonatomic, assign) IBInspectable CGFloat verticalSpacing;

/// Top inset applied inside the view's bounds before layout. Default: 0.
@property (nonatomic, assign) IBInspectable CGFloat contentInsetTop;

/// Left inset applied inside the view's bounds before layout. Default: 0.
@property (nonatomic, assign) IBInspectable CGFloat contentInsetLeft;

/// Bottom inset applied inside the view's bounds before layout. Default: 0.
@property (nonatomic, assign) IBInspectable CGFloat contentInsetBottom;

/// Right inset applied inside the view's bounds before layout. Default: 0.
@property (nonatomic, assign) IBInspectable CGFloat contentInsetRight;

/// How subviews are aligned horizontally within each row. Default: FlowViewAlignmentLeading.
/// IBInspectable surfaces this as an integer: 0 = Leading, 1 = Center, 2 = Justified.
@property (nonatomic, assign) IBInspectable NSInteger flowAlignmentValue;

/// Typed convenience wrapper around flowAlignmentValue.
@property (nonatomic, assign) FlowViewAlignment flowAlignment;

/// Convenience accessor that aggregates the four inset properties.
/// Setting this updates all four individual inset properties.
@property (nonatomic, assign) NSEdgeInsets contentInsets;

/// The subviews currently managed by the flow layout.
/// Use -addArrangedSubview: / -removeArrangedSubview: rather than the raw
/// NSView add/remove methods when managing subviews programmatically.
@property (nonatomic, readonly, copy) NSArray<NSView *> *arrangedSubviews;

- (void)addArrangedSubview:(NSView *)view;
- (void)insertArrangedSubview:(NSView *)view atIndex:(NSUInteger)index;
- (void)removeArrangedSubview:(NSView *)view;

@end

NS_ASSUME_NONNULL_END
