//
//  GMSCameraPosition.h
//  Google Maps SDK for iOS
//
//  Copyright 2013 Google Inc.
//
//  Usage of this SDK is subject to the Google Maps/Google Earth APIs Terms of
//  Service: https://developers.google.com/maps/terms
//

#import <CoreLocation/CoreLocation.h>

/**
* An immutable class that aggregates all camera position parameters.
 */
@interface GMSCameraPosition : NSObject <NSCopying, NSMutableCopying>

/**
 * Location on the Earth towards which the camera points.
 */
@property(nonatomic, readonly) CLLocationCoordinate2D target;

/**
 * Zoom level. Zoom uses an exponentional scale, where zoom 0 represents the entire world as a
 * 256 x 256 square. Each successive zoom level increases magnification by a factor of 2. So at
 * zoom level 1, the world is 512x512, and at zoom level 2, the entire world is 1024x1024.
 */
@property(nonatomic, readonly) float zoom;

/**
 * Bearing of the camera, in degrees clockwise from true north.
 */
@property(nonatomic, readonly) CLLocationDirection bearing;

/**
 * The angle, in degrees, of the camera angle from the nadir (directly facing the Earth). 0 is
 * straight down, 90 is parallel to the ground. Note that the maximum angle allowed is 45 degrees.
 */
@property(nonatomic, readonly) double viewingAngle;

/**
 * Designated initializer. Configures this GMSCameraPosition with all available camera properties.
 * Building a GMSCameraPosition via this initializer (or by the following convenience constructors)
 * will implicitly clamp camera values.
 *
 * @param target location on the earth which the camera points
 * @param zoom the zoom level near the center of the screen
 * @param bearing of the camera in degrees from true north
 * @param viewingAngle in degrees, of the camera angle from the nadir
 */
- (id)initWithTarget:(CLLocationCoordinate2D)target
                zoom:(float)zoom
             bearing:(CLLocationDirection)bearing
        viewingAngle:(double)viewingAngle;

/**
 * Convenience constructor for GMSCameraPosition for a particular target and zoom level. This will
 * set the bearing and viewingAngle properties of this camera to zero defaults (i.e., directly
 * facing the Earth's surface, with the top of the screen pointing north).
 */
+ (instancetype)cameraWithTarget:(CLLocationCoordinate2D)target zoom:(float)zoom;

/**
 * Convenience constructor for GMSCameraPosition, as per cameraWithTarget:zoom:.
 */
+ (instancetype)cameraWithLatitude:(CLLocationDegrees)latitude
                         longitude:(CLLocationDegrees)longitude
                              zoom:(float)zoom;

/**
 * Convenience constructor for GMSCameraPosition, with all camera properties as per
 * initWithTarget:zoom:bearing:viewingAngle:.
 */
+ (instancetype)cameraWithTarget:(CLLocationCoordinate2D)target
                            zoom:(float)zoom
                         bearing:(CLLocationDirection)bearing
                    viewingAngle:(double)viewingAngle;

/**
 * Convenience constructor for GMSCameraPosition, with latitude/longitude and all other camera
 * properties as per initWithTarget:zoom:bearing:viewingAngle:.
 */
+ (instancetype)cameraWithLatitude:(CLLocationDegrees)latitude
                         longitude:(CLLocationDegrees)longitude
                              zoom:(float)zoom
                           bearing:(CLLocationDirection)bearing
                      viewingAngle:(double)viewingAngle;

/**
 * Get the zoom level at which |meters| distance, at given |coord| on Earth, correspond to the
 * specified number of screen |points|.
 *
 * For extremely large or small distances the returned zoom level may be smaller or larger than the
 * minimum or maximum zoom level allowed on the camera.
 *
 * This helper method is useful for building camera positions that contain specific physical areas
 * on Earth.
 */
+ (float)zoomAtCoordinate:(CLLocationCoordinate2D)coordinate
                forMeters:(CLLocationDistance)meters
                perPoints:(CGFloat)points;

@end

/** Mutable version of GMSCameraPosition. */
@interface GMSMutableCameraPosition : GMSCameraPosition
@property(nonatomic, assign) CLLocationCoordinate2D target;
@property(nonatomic, assign) float zoom;
@property(nonatomic, assign) CLLocationDirection bearing;
@property(nonatomic, assign) double viewingAngle;
@end

/** The maximum zoom (closest to the Earth's surface) permitted by the map camera. */
FOUNDATION_EXTERN const float kGMSMaxZoomLevel;

/** The minimum zoom (farthest from the Earth's surface) permitted by the map camera. */
FOUNDATION_EXTERN const float kGMSMinZoomLevel;
