//
//  MKAnnotationView.h
//  MapKit
//
//  Copyright (c) 2009-2014, Apple Inc. All rights reserved.
//

#import <MapKit/MKFoundation.h>

#if MK_SUPPORTS_VIEW_CLASSES

#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
#else
#import <AppKit/AppKit.h>
#endif

NS_ASSUME_NONNULL_BEGIN

#if !TARGET_OS_WATCH
// Post this notification to re-query callout information.
MK_EXTERN NSString * const MKAnnotationCalloutInfoDidChangeNotification;
#endif

typedef NS_ENUM(NSUInteger, MKAnnotationViewDragState) {
    MKAnnotationViewDragStateNone = 0,      // View is at rest, sitting on the map.
    MKAnnotationViewDragStateStarting,      // View is beginning to drag (e.g. pin lift)
    MKAnnotationViewDragStateDragging,      // View is dragging ("lift" animations are complete)
    MKAnnotationViewDragStateCanceling,     // View was not dragged and should return to its starting position (e.g. pin drop)
    MKAnnotationViewDragStateEnding         // View was dragged, new coordinate is set and view should return to resting position (e.g. pin drop)
} API_AVAILABLE(macos(10.9), ios(4.0)) API_UNAVAILABLE(tvos, watchos);

typedef float MKFeatureDisplayPriority NS_TYPED_EXTENSIBLE_ENUM NS_AVAILABLE(10_13, 11_0) __TVOS_AVAILABLE(11_0) API_UNAVAILABLE(watchos);
static const MKFeatureDisplayPriority MKFeatureDisplayPriorityRequired NS_AVAILABLE(10_13, 11_0) __TVOS_AVAILABLE(11_0) API_UNAVAILABLE(watchos) = 1000;
static const MKFeatureDisplayPriority MKFeatureDisplayPriorityDefaultHigh NS_AVAILABLE(10_13, 11_0) __TVOS_AVAILABLE(11_0) API_UNAVAILABLE(watchos) = 750;
static const MKFeatureDisplayPriority MKFeatureDisplayPriorityDefaultLow NS_AVAILABLE(10_13, 11_0) __TVOS_AVAILABLE(11_0) API_UNAVAILABLE(watchos) = 250;

typedef float MKAnnotationViewZPriority NS_TYPED_EXTENSIBLE_ENUM API_AVAILABLE(ios(14.0), macos(11.0), tvos(14.0)) API_UNAVAILABLE(watchos);
static const MKAnnotationViewZPriority MKAnnotationViewZPriorityMax API_AVAILABLE(ios(14.0), macos(11.0), tvos(14.0)) API_UNAVAILABLE(watchos) = 1000;
static const MKAnnotationViewZPriority MKAnnotationViewZPriorityDefaultSelected API_AVAILABLE(ios(14.0), macos(11.0), tvos(14.0)) API_UNAVAILABLE(watchos) = 1000;
static const MKAnnotationViewZPriority MKAnnotationViewZPriorityDefaultUnselected API_AVAILABLE(ios(14.0), macos(11.0), tvos(14.0)) API_UNAVAILABLE(watchos) = 500;
static const MKAnnotationViewZPriority MKAnnotationViewZPriorityMin API_AVAILABLE(ios(14.0), macos(11.0), tvos(14.0)) API_UNAVAILABLE(watchos) = 0;

typedef NS_ENUM(NSInteger, MKAnnotationViewCollisionMode) {
    MKAnnotationViewCollisionModeRectangle,
    MKAnnotationViewCollisionModeCircle,
    MKAnnotationViewCollisionModeNone API_AVAILABLE(ios(14.0), macos(11.0), tvos(14.0)) API_UNAVAILABLE(watchos)
} API_AVAILABLE(ios(11.0), macos(10.13), tvos(11.0)) API_UNAVAILABLE(watchos);

@protocol MKAnnotation;

#if TARGET_OS_IPHONE
NS_CLASS_AVAILABLE(NA, 3_0) __TVOS_AVAILABLE(9_2) API_UNAVAILABLE(watchos)
@interface MKAnnotationView : UIView
#else
NS_CLASS_AVAILABLE(10_9, NA)
@interface MKAnnotationView : NSView
#endif

- (instancetype)initWithAnnotation:(nullable id <MKAnnotation>)annotation reuseIdentifier:(nullable NSString *)reuseIdentifier NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;

@property (nonatomic, readonly, nullable) NSString *reuseIdentifier;

// Classes that override must call super.
- (void)prepareForReuse;

- (void)prepareForDisplay NS_REQUIRES_SUPER API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0)) API_UNAVAILABLE(watchos);

@property (nonatomic, strong, nullable) id <MKAnnotation> annotation;

#if TARGET_OS_IPHONE
@property (nonatomic, strong, nullable) UIImage *image;
#else
@property (nonatomic, strong, nullable) NSImage *image;
#endif

// By default, the center of annotation view is placed over the coordinate of the annotation.
// centerOffset is the offset in screen points from the center of the annotion view.
@property (nonatomic) CGPoint centerOffset;

// The offset (in points) that selection accessories reference.
//
// By default, the center point of an annotation view is referenced
// by accessories positioned adjacent to the annotation view on the map.
// You can use this property to reposition the reference point as
// necessary. MapKit measures the x- and y-offset values in points.
// Positive offset values move the reference point down and to the right,
// and negative values move it up and to the left.
@property (nonatomic, assign) CGPoint accessoryOffset
API_AVAILABLE(ios(18.0), macos(15.0), visionos(2.0))
API_UNAVAILABLE(watchos, tvos);

// calloutOffset is the offset in screen points from the top-middle of the annotation view, where the anchor of the callout should be shown.
@property (nonatomic) CGPoint calloutOffset;

// leftCalloutOffset is the offset in screen points from the middle-left of the annotation view, where the anchor of the callout should be shown when oriented off the left side of the annotation view
@property (nonatomic) CGPoint leftCalloutOffset API_AVAILABLE(macos(10.9), macCatalyst(13.0)) API_UNAVAILABLE(ios, tvos, watchos);

// rightCalloutOffset is the offset in screen points from the middle-right of the annotation view, where the anchor of the callout should be shown when oriented off the right side of the annotation view
@property (nonatomic) CGPoint rightCalloutOffset API_AVAILABLE(macos(10.9), macCatalyst(13.0)) API_UNAVAILABLE(ios, tvos, watchos);

// Defaults to YES. If NO, ignores touch events and subclasses may draw differently.
@property (nonatomic, getter=isEnabled) BOOL enabled;

// Defaults to NO. This gets set/cleared automatically when touch enters/exits during tracking and cleared on up.
@property (nonatomic, getter=isHighlighted) BOOL highlighted;

// Defaults to NO. Becomes YES when tapped/clicked on in the map view.
@property (nonatomic, getter=isSelected) BOOL selected;
- (void)setSelected:(BOOL)selected animated:(BOOL)animated;

// If YES, a standard callout bubble will be shown when the annotation is selected.
// The annotation must have a title for the callout to be shown.
@property (nonatomic) BOOL canShowCallout;

// The left accessory view to be used in the standard callout.
#if TARGET_OS_IPHONE
@property (strong, nonatomic, nullable) UIView *leftCalloutAccessoryView;
#else
@property (strong, nonatomic, nullable) NSView *leftCalloutAccessoryView;
#endif

// The right accessory view to be used in the standard callout.
#if TARGET_OS_IPHONE
@property (strong, nonatomic, nullable) UIView *rightCalloutAccessoryView;
#else
@property (strong, nonatomic, nullable) NSView *rightCalloutAccessoryView;
#endif

// The detail accessory view to be used in the standard callout.
#if TARGET_OS_IPHONE
@property (nonatomic, strong, nullable) UIView *detailCalloutAccessoryView API_AVAILABLE(macos(10.11), ios(9.0), tvos(9.2)) API_UNAVAILABLE(watchos);
#else
@property (nonatomic, strong, nullable) NSView *detailCalloutAccessoryView NS_AVAILABLE(10_11, 9_0);
#endif

// If YES and the underlying id<MKAnnotation> responds to setCoordinate:, 
// the user will be able to drag this annotation view around the map.
@property (nonatomic, getter=isDraggable) BOOL draggable API_AVAILABLE(macos(10.9), ios(4.0)) API_UNAVAILABLE(tvos, watchos);

// Automatically set to MKAnnotationViewDragStateStarting, Canceling, and Ending when necessary.
// Implementer is responsible for transitioning to Dragging and None states as appropriate.
@property (nonatomic) MKAnnotationViewDragState dragState API_AVAILABLE(macos(10.9), ios(4.0)) API_UNAVAILABLE(tvos, watchos);

// Developers targeting iOS 4.2 and after must use setDragState:animated: instead of setDragState:.
- (void)setDragState:(MKAnnotationViewDragState)newDragState animated:(BOOL)animated API_AVAILABLE(macos(10.9), ios(4.2)) API_UNAVAILABLE(tvos, watchos);

// Annotation views with equal non-nil identifiers can cluster together.
@property (nonatomic, copy, nullable) NSString *clusteringIdentifier API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0)) API_UNAVAILABLE(watchos);

// If non-nil this is the annotation view this view is clustered into.
@property (nonatomic, weak, readonly, nullable) MKAnnotationView *clusterAnnotationView API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0)) API_UNAVAILABLE(watchos);

// Default is MKFeatureDisplayPriorityRequired, other values opts into collision occlusion by priority.
@property (nonatomic) MKFeatureDisplayPriority displayPriority API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0)) API_UNAVAILABLE(watchos);

@property (nonatomic) MKAnnotationViewZPriority zPriority API_AVAILABLE(ios(14.0), macos(11.0), tvos(14.0)) API_UNAVAILABLE(watchos);
@property (nonatomic) MKAnnotationViewZPriority selectedZPriority API_AVAILABLE(ios(14.0), macos(11.0), tvos(14.0)) API_UNAVAILABLE(watchos);

// Default collision mode is rectangle.
@property (nonatomic) MKAnnotationViewCollisionMode collisionMode API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0)) API_UNAVAILABLE(watchos);

@end

NS_ASSUME_NONNULL_END

#endif // MK_SUPPORTS_VIEW_CLASSES
