1//
2//  AIRUrlTileOverlay.m
3//  AirMaps
4//
5//  Created by cascadian on 3/19/16.
6//  Copyright © 2016. All rights reserved.
7//
8
9#import "AIRMapUrlTile.h"
10#import <React/UIView+React.h>
11#import "AIRMapUrlTileCachedOverlay.h"
12
13@implementation AIRMapUrlTile
14
15- (void)setShouldReplaceMapContent:(BOOL)shouldReplaceMapContent
16{
17    _shouldReplaceMapContent = shouldReplaceMapContent;
18    if (self.tileOverlay) {
19        self.tileOverlay.canReplaceMapContent = _shouldReplaceMapContent;
20    }
21    [self update];
22}
23
24- (void)setMaximumZ:(NSInteger)maximumZ
25{
26    _maximumZ = maximumZ;
27    if (self.tileOverlay) {
28        self.tileOverlay.maximumZ = _maximumZ;
29    }
30    [self update];
31}
32
33- (void)setMaximumNativeZ:(NSInteger)maximumNativeZ
34{
35    _maximumNativeZ = maximumNativeZ;
36    _maximumNativeZSet = YES;
37    if (_cachedOverlayCreated) {
38        self.tileOverlay.maximumNativeZ = _maximumNativeZ;
39    } else {
40        [self createTileOverlayAndRendererIfPossible];
41    }
42    [self update];
43}
44
45- (void)setMinimumZ:(NSInteger)minimumZ
46{
47    _minimumZ = minimumZ;
48    if (self.tileOverlay) {
49        self.tileOverlay.minimumZ = _minimumZ;
50    }
51    [self update];
52}
53
54- (void)setFlipY:(BOOL)flipY
55{
56    _flipY = flipY;
57    _flipYSet = YES;
58    if (self.tileOverlay) {
59        self.tileOverlay.geometryFlipped = _flipY;
60    }
61    [self update];
62}
63
64- (void)setUrlTemplate:(NSString *)urlTemplate
65{
66    _urlTemplate = urlTemplate;
67    _urlTemplateSet = YES;
68    [self createTileOverlayAndRendererIfPossible];
69    [self update];
70}
71
72- (void)setTileSize:(NSInteger)tileSize
73{
74    _tileSize = tileSize;
75    _tileSizeSet = YES;
76    [self createTileOverlayAndRendererIfPossible];
77    [self update];
78}
79
80- (void)setTileCachePath:(NSString *)tileCachePath{
81    if (!tileCachePath) return;
82    _tileCachePath = tileCachePath;
83    _tileCachePathSet = YES;
84    [self createTileOverlayAndRendererIfPossible];
85    [self update];
86}
87
88- (void)setTileCacheMaxAge:(NSInteger)tileCacheMaxAge{
89    _tileCacheMaxAge = tileCacheMaxAge;
90    _tileCacheMaxAgeSet = YES;
91    if (_cachedOverlayCreated) {
92        self.tileOverlay.tileCacheMaxAge = _tileCacheMaxAge;
93    } else {
94        [self createTileOverlayAndRendererIfPossible];
95    }
96    [self update];
97}
98
99- (void)setOfflineMode:(BOOL)offlineMode
100{
101    _offlineMode = offlineMode;
102    if (_cachedOverlayCreated) {
103        self.tileOverlay.offlineMode = _offlineMode;
104    }
105    if (self.renderer) [self.renderer reloadData];
106}
107
108- (void)setOpacity:(CGFloat)opacity
109{
110    _opacity = opacity;
111    _opacitySet = YES;
112    if (self.renderer) {
113        self.renderer.alpha = opacity;
114    } else {
115        [self createTileOverlayAndRendererIfPossible];
116    }
117    [self update];
118}
119
120- (void)createTileOverlayAndRendererIfPossible
121{
122    if (!_urlTemplateSet) return;
123    if (_tileCachePathSet || _maximumNativeZSet) {
124        NSLog(@"tileCache dir %@", _tileCachePath);
125        self.tileOverlay = [[AIRMapUrlTileCachedOverlay alloc] initWithURLTemplate:self.urlTemplate];
126        _cachedOverlayCreated = YES;
127        if (_tileCachePathSet) {
128            NSURL *urlPath = [NSURL URLWithString:[self.tileCachePath stringByAppendingString:@"/"]];
129            if (urlPath.fileURL) {
130                self.tileOverlay.tileCachePath = urlPath;
131            } else {
132                NSURL *filePath = [NSURL fileURLWithPath:self.tileCachePath isDirectory:YES];
133                self.tileOverlay.tileCachePath = filePath;
134            }
135
136            if (_tileCacheMaxAgeSet) {
137                self.tileOverlay.tileCacheMaxAge = self.tileCacheMaxAge;
138            }
139        }
140    } else {
141        NSLog(@"tileCache normal overlay");
142        self.tileOverlay = [[MKTileOverlay alloc] initWithURLTemplate:self.urlTemplate];
143        _cachedOverlayCreated = NO;
144    }
145
146    [self updateProperties];
147
148    self.renderer = [[MKTileOverlayRenderer alloc] initWithTileOverlay:self.tileOverlay];
149    if (_opacitySet) {
150        self.renderer.alpha = self.opacity;
151    }
152}
153
154- (void)updateProperties
155{
156    self.tileOverlay.canReplaceMapContent = self.shouldReplaceMapContent;
157
158    if(self.minimumZ) {
159        self.tileOverlay.minimumZ = self.minimumZ;
160    }
161    if (self.maximumZ) {
162        self.tileOverlay.maximumZ = self.maximumZ;
163    }
164    if (_cachedOverlayCreated && self.maximumNativeZ) {
165        self.tileOverlay.maximumNativeZ = self.maximumNativeZ;
166    }
167    if (_flipYSet) {
168        self.tileOverlay.geometryFlipped = self.flipY;
169    }
170    if (_tileSizeSet) {
171        self.tileOverlay.tileSize = CGSizeMake(self.tileSize, self.tileSize);
172    }
173    if (_cachedOverlayCreated && self.offlineMode) {
174        self.tileOverlay.offlineMode = self.offlineMode;
175    }
176}
177
178- (void)update
179{
180    if (!_renderer) return;
181
182    if (_map == nil) return;
183    [_map removeOverlay:self];
184    [_map addOverlay:self level:MKOverlayLevelAboveLabels];
185    for (id<MKOverlay> overlay in _map.overlays) {
186        if ([overlay isKindOfClass:[AIRMapUrlTile class]]) {
187            continue;
188        }
189        [_map removeOverlay:overlay];
190        [_map addOverlay:overlay];
191    }
192}
193
194#pragma mark MKOverlay implementation
195
196- (CLLocationCoordinate2D)coordinate
197{
198    return self.tileOverlay.coordinate;
199}
200
201- (MKMapRect)boundingMapRect
202{
203    return self.tileOverlay.boundingMapRect;
204}
205
206- (BOOL)canReplaceMapContent
207{
208    return self.tileOverlay.canReplaceMapContent;
209}
210
211@end
212