2 // HMFleetViewController.m
5 // Created by Hori,Masaki on 2015/03/01.
6 // Copyright (c) 2015年 Hori,Masaki. All rights reserved.
9 #import "HMFleetViewController.h"
10 #import "HMShipDetailViewController.h"
12 #import "HMAppDelegate.h"
14 #import "HMKCShipObject+Extensions.h"
15 #import "HMKCDeck+Extension.h"
17 #import "HMServerDataStore.h"
19 #import "HMAnchorageRepairManager.h"
22 const NSInteger maxFleetNumber = 4;
24 @interface HMFleetViewController ()
26 @property (readwrite) HMFleetViewType type;
28 @property (nonatomic, weak) IBOutlet NSView *placeholder01;
29 @property (nonatomic, weak) IBOutlet NSView *placeholder02;
30 @property (nonatomic, weak) IBOutlet NSView *placeholder03;
31 @property (nonatomic, weak) IBOutlet NSView *placeholder04;
32 @property (nonatomic, weak) IBOutlet NSView *placeholder05;
33 @property (nonatomic, weak) IBOutlet NSView *placeholder06;
35 @property (strong) HMShipDetailViewController *detail01;
36 @property (strong) HMShipDetailViewController *detail02;
37 @property (strong) HMShipDetailViewController *detail03;
38 @property (strong) HMShipDetailViewController *detail04;
39 @property (strong) HMShipDetailViewController *detail05;
40 @property (strong) HMShipDetailViewController *detail06;
41 @property (strong) NSArray *details;
43 @property (readonly) NSArray *shipKeys;
46 @property (strong) NSArray *anchorageRepairHolder;
47 @property (strong) HMAnchorageRepairManager *anchorageRepair;
48 @property (readonly) NSNumber *repairTime;
49 @property (readonly) NSNumber *repairableShipCount;
53 @implementation HMFleetViewController
54 @synthesize fleetNumber = _fleetNumber;
55 @synthesize shipOrder = _shipOrder;
57 - (instancetype)initWithViewType:(HMFleetViewType)type
59 NSString *nibName = nil;
62 nibName = NSStringFromClass([self class]);
65 nibName = @"HMFleetMinimumViewController";
67 case miniVierticalType:
68 nibName = @"HMVerticalFleetViewController";
73 self = [super initWithNibName:nibName bundle:nil];
77 [self buildAnchorageRepairHolder];
82 + (instancetype)viewControlerWithViewType:(HMFleetViewType)type
84 return [[self alloc] initWithViewType:type];
89 for(NSString *key in self.shipKeys) {
90 [self.representedObject removeObserver:self
97 HMShipDetailViewType viewType;
102 case minimumViewType:
105 case miniVierticalType:
109 NSMutableArray *details = [NSMutableArray new];
110 NSArray *detailKeys = @[@"detail01", @"detail02", @"detail03", @"detail04", @"detail05", @"detail06"];
111 [detailKeys enumerateObjectsUsingBlock:^(id detailKey, NSUInteger idx, BOOL *stop) {
112 HMShipDetailViewController *detail = [HMShipDetailViewController viewControllerWithType:viewType];
113 detail.title = [NSString stringWithFormat:@"%ld", idx + 1];
114 [self setValue:detail forKey:detailKey];
116 [details addObject:detail];
118 self.details = details;
120 NSArray *placeholderKeys = @[@"placeholder01", @"placeholder02", @"placeholder03", @"placeholder04", @"placeholder05", @"placeholder06"];
121 [placeholderKeys enumerateObjectsUsingBlock:^(id placeholderKey, NSUInteger idx, BOOL *stop) {
122 NSView *view = [self valueForKey:placeholderKey];
123 HMShipDetailViewController *detail = self.details[idx];
124 [detail.view setFrame:[view frame]];
125 [detail.view setAutoresizingMask:[view autoresizingMask]];
126 [[view superview] replaceSubview:view with:detail.view];
129 self.fleetNumber = 1;
132 - (NSArray *)shipKeys
134 static NSArray *shipKeys = nil;
135 if(shipKeys) return shipKeys;
137 shipKeys = @[@"ship_0", @"ship_1", @"ship_2", @"ship_3", @"ship_4", @"ship_5"];
141 - (void)setShipOfViewForKey:(NSString *)key
143 NSUInteger index = [self.shipKeys indexOfObject:key];
144 if(index != NSNotFound) {
145 NSUInteger shipID = [[self.fleet valueForKey:key] integerValue];
146 [self setShipID:shipID
147 toDetail:self.details[index]];
151 - (void)setShipID:(NSInteger)shipId toDetail:(HMShipDetailViewController *)detail
153 HMServerDataStore *store = [HMServerDataStore defaultManager];
154 NSError *error = nil;
155 HMKCShipObject *ship = nil;
156 NSArray *array = [store objectsWithEntityName:@"Ship"
158 predicateFormat:@"id = %ld", shipId];
160 NSLog(@"%s error: %@", __PRETTY_FUNCTION__, error);
162 if(array.count != 0) {
167 [self willChangeValueForKey:@"repairableShipCount"];
168 [self didChangeValueForKey:@"repairableShipCount"];
170 - (void)setFleet:(HMKCDeck *)fleet
172 for(NSString *key in self.shipKeys) {
173 [self.representedObject removeObserver:self
176 [fleet addObserver:self
182 self.representedObject = fleet;
183 self.title = fleet.name;
185 for(NSString *key in self.shipKeys) {
186 [self setShipOfViewForKey:key];
191 return self.representedObject;
194 - (void)setFleetNumber:(NSInteger)fleetNumber
196 HMServerDataStore *store = [HMServerDataStore defaultManager];
197 NSError *error = nil;
198 NSArray *array = [store objectsWithEntityName:@"Deck"
200 predicateFormat:@"id = %ld", fleetNumber];
202 NSLog(@"%s error: %@", __PRETTY_FUNCTION__, error);
205 if(array.count == 0) {
209 self.fleet = array[0];
210 _fleetNumber = fleetNumber;
212 self.anchorageRepair = self.anchorageRepairHolder[fleetNumber - 1];
214 - (NSInteger)fleetNumber
219 - (void)setShipOrder:(HMFleetViewShipOrder)shipOrder
221 if(_shipOrder == shipOrder) return;
222 _shipOrder = shipOrder;
226 [self reorderShipToDoubleLine];
229 [self reorderShipToLeftToRight];
233 - (HMFleetViewShipOrder)shipOrder
240 return self.type == detailViewType;
242 - (CGFloat)normalHeight
246 return HMFleetViewController.detailViewHeight;
247 case minimumViewType:
248 return HMFleetViewController.oldStyleFleetViewHeight;
249 case miniVierticalType:
255 - (CGFloat)upsideHeight
260 case minimumViewType:
261 return HMFleetViewController.oldStyleFleetViewHeight;
262 case miniVierticalType:
269 + (CGFloat)oldStyleFleetViewHeight
273 + (CGFloat)detailViewHeight
277 + (CGFloat)heightDifference
279 return self.detailViewHeight - self.oldStyleFleetViewHeight;
283 + (NSSet *)keyPathsForValuesAffectingTotalSakuteki
285 return [NSSet setWithObjects:
286 @"detail01.ship.sakuteki_0",
287 @"detail02.ship.sakuteki_0",
288 @"detail03.ship.sakuteki_0",
289 @"detail04.ship.sakuteki_0",
290 @"detail05.ship.sakuteki_0",
291 @"detail06.ship.sakuteki_0",
294 - (NSNumber *)totalSakuteki
297 for(HMShipDetailViewController *detail in self.details) {
298 HMKCShipObject *ship = detail.ship;
299 total += ship.sakuteki_0.integerValue;
304 + (NSSet *)keyPathsForValuesAffectingTotalSeiku
306 return [NSSet setWithObjects:
307 @"detail01.ship.seiku",
308 @"detail02.ship.seiku",
309 @"detail03.ship.seiku",
310 @"detail04.ship.seiku",
311 @"detail05.ship.seiku",
312 @"detail06.ship.seiku",
315 - (NSNumber *)totalSeiku
318 for(HMShipDetailViewController *detail in self.details) {
319 HMKCShipObject *ship = detail.ship;
320 total += ship.seiku.integerValue;
324 + (NSSet *)keyPathsForValuesAffectingTotalCalclatedSeiku
326 return [NSSet setWithObjects:
327 @"detail01.ship.seiku",
328 @"detail02.ship.seiku",
329 @"detail03.ship.seiku",
330 @"detail04.ship.seiku",
331 @"detail05.ship.seiku",
332 @"detail06.ship.seiku",
335 - (NSNumber *)totalCalclatedSeiku
338 for(HMShipDetailViewController *detail in self.details) {
339 HMKCShipObject *ship = detail.ship;
340 total += ship.seiku.integerValue;
341 total += ship.extraSeiku.integerValue;
345 + (NSSet *)keyPathsForValuesAffectingTotalLevel
347 return [NSSet setWithObjects:
356 - (NSNumber *)totalLevel
359 for(HMShipDetailViewController *detail in self.details) {
360 HMKCShipObject *ship = detail.ship;
361 total += ship.lv.integerValue;
365 + (NSSet *)keyPathsForValuesAffectingTotalDrums
367 return [NSSet setWithObjects:
368 @"detail01.ship.totalDrums",
369 @"detail02.ship.totalDrums",
370 @"detail03.ship.totalDrums",
371 @"detail04.ship.totalDrums",
372 @"detail05.ship.totalDrums",
373 @"detail06.ship.totalDrums",
376 - (NSNumber *)totalDrums
379 for(HMShipDetailViewController *detail in self.details) {
380 HMKCShipObject *ship = detail.ship;
381 total += ship.totalDrums.integerValue;
386 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
388 if([self.shipKeys containsObject:keyPath]) {
389 [self setShipOfViewForKey:keyPath];
393 return [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
396 - (IBAction)selectNextFleet:(id)sender
398 NSInteger next = self.fleetNumber + 1;
399 self.fleetNumber = next <= maxFleetNumber ? next : 1;
401 - (IBAction)selectPreviousFleet:(id)sender
403 NSInteger prev = self.fleetNumber - 1;
404 self.fleetNumber = prev > 0 ? prev : 4;
408 - (void)reorderShipToDoubleLine
410 NSView *view02 = self.detail02.view;
411 NSView *view03 = self.detail03.view;
412 NSView *view04 = self.detail04.view;
413 NSView *view05 = self.detail05.view;
415 NSAutoresizingMaskOptions options02 = view02.autoresizingMask;
416 NSAutoresizingMaskOptions options03 = view03.autoresizingMask;
417 NSAutoresizingMaskOptions options04 = view04.autoresizingMask;
418 NSAutoresizingMaskOptions options05 = view05.autoresizingMask;
420 view02.autoresizingMask = options04;
421 view03.autoresizingMask = options02;
422 view04.autoresizingMask = options05;
423 view05.autoresizingMask = options03;
425 NSRect frame02 = view02.frame;
426 NSRect frame03 = view03.frame;
427 NSRect frame04 = view04.frame;
428 NSRect frame05 = view05.frame;
430 if(self.enableAnimation) {
431 view02.animator.frame = frame04;
432 view03.animator.frame = frame02;
433 view04.animator.frame = frame05;
434 view05.animator.frame = frame03;
436 view02.frame = frame04;
437 view03.frame = frame02;
438 view04.frame = frame05;
439 view05.frame = frame03;
442 - (void)reorderShipToLeftToRight
444 NSView *view02 = self.detail02.view;
445 NSView *view03 = self.detail03.view;
446 NSView *view04 = self.detail04.view;
447 NSView *view05 = self.detail05.view;
449 NSAutoresizingMaskOptions options02 = view02.autoresizingMask;
450 NSAutoresizingMaskOptions options03 = view03.autoresizingMask;
451 NSAutoresizingMaskOptions options04 = view04.autoresizingMask;
452 NSAutoresizingMaskOptions options05 = view05.autoresizingMask;
454 view02.autoresizingMask = options03;
455 view03.autoresizingMask = options05;
456 view04.autoresizingMask = options02;
457 view05.autoresizingMask = options04;
459 NSRect frame02 = view02.frame;
460 NSRect frame03 = view03.frame;
461 NSRect frame04 = view04.frame;
462 NSRect frame05 = view05.frame;
464 if(self.enableAnimation) {
465 view02.animator.frame = frame03;
466 view03.animator.frame = frame05;
467 view04.animator.frame = frame02;
468 view05.animator.frame = frame04;
470 view02.frame = frame03;
471 view03.frame = frame05;
472 view04.frame = frame02;
473 view05.frame = frame04;
478 - (void)buildAnchorageRepairHolder
480 HMServerDataStore *store = [HMServerDataStore defaultManager];
481 NSError *error = nil;
482 NSArray *array = [store objectsWithEntityName:@"Deck"
483 sortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"id" ascending:YES]]
487 NSLog(@"%s error: %@", __PRETTY_FUNCTION__, error);
490 if(array.count == 0) {
493 if(array.count < 4) {
498 NSMutableArray *anchorageRepairs = [NSMutableArray new];
499 for(HMKCDeck *deck in array) {
500 id anchorageRepair = [[HMAnchorageRepairManager alloc] initWithDeck:deck];
501 [anchorageRepairs addObject:anchorageRepair];
503 self.anchorageRepairHolder = anchorageRepairs;
505 HMAppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
506 [appDelegate addCounterUpdateBlock:^{
507 [self willChangeValueForKey:@"repairTime"];
508 [self didChangeValueForKey:@"repairTime"];
511 + (NSSet *)keyPathsForValuesAffectingRepairTime
513 return [NSSet setWithObjects:@"anchorageRepair.repairTime", @"anchorageRepair", nil];
515 - (NSNumber *)repairTime
517 NSDate *compTimeValue = self.anchorageRepair.repairTime;
518 if(!compTimeValue) return nil;
520 NSTimeInterval compTime = [compTimeValue timeIntervalSince1970];
521 NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0];
522 NSTimeInterval diff = compTime - [now timeIntervalSince1970];
523 return @(diff + 20 * 60);
525 + (NSSet *)keyPathsForValuesAffectingRepairableShipCount
527 return [NSSet setWithObjects:
528 @"anchorageRepair.repairableShipCount", @"anchorageRepair",
533 - (NSNumber *)repairableShipCount
535 return self.anchorageRepair.repairableShipCount;