OSDN Git Service

2608f3efa926a63c1cf56d9298742e62f3ea671d
[kcd/KCD.git] / KCD / HMFleetViewController.m
1 //
2 //  HMFleetViewController.m
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2015/03/01.
6 //  Copyright (c) 2015年 Hori,Masaki. All rights reserved.
7 //
8
9 #import "HMFleetViewController.h"
10 #import "HMShipDetailViewController.h"
11
12 #import "HMAppDelegate.h"
13
14 #import "HMKCShipObject+Extensions.h"
15 #import "HMKCDeck+Extension.h"
16
17 #import "HMServerDataStore.h"
18
19 #import "HMAnchorageRepairManager.h"
20
21
22 const NSInteger maxFleetNumber = 4;
23
24 @interface HMFleetViewController ()
25
26 @property (readwrite) HMFleetViewType type;
27
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;
34
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;
42
43 @property (readonly) NSArray *shipKeys;
44
45
46 @property (strong) NSArray *anchorageRepairHolder;
47 @property (strong) HMAnchorageRepairManager *anchorageRepair;
48 @property (readonly) NSNumber *repairTime;
49 @property (readonly) NSNumber *repairableShipCount;
50
51 @end
52
53 @implementation HMFleetViewController
54 @synthesize fleetNumber = _fleetNumber;
55 @synthesize shipOrder = _shipOrder;
56
57 - (instancetype)initWithViewType:(HMFleetViewType)type
58 {
59         NSString *nibName = nil;
60         switch (type) {
61                 case detailViewType:
62                         nibName = NSStringFromClass([self class]);
63                         break;
64                 case minimumViewType:
65                         nibName = @"HMFleetMinimumViewController";
66                         break;
67                 case miniVierticalType:
68                         nibName = @"HMVerticalFleetViewController";
69                         break;
70         }
71         assert(nibName);
72         
73         self = [super initWithNibName:nibName bundle:nil];
74         if(self) {
75                 _type = type;
76                 
77                 [self buildAnchorageRepairHolder];
78                 [self loadView];
79         }
80         return self;
81 }
82 + (instancetype)viewControlerWithViewType:(HMFleetViewType)type
83 {
84         return [[self alloc] initWithViewType:type];
85 }
86
87 - (void)dealloc
88 {
89         for(NSString *key in self.shipKeys) {
90                 [self.representedObject removeObserver:self
91                                                                         forKeyPath:key];
92         }
93 }
94
95 - (void)awakeFromNib
96 {
97         HMShipDetailViewType viewType;
98         switch(self.type) {
99                 case detailViewType:
100                         viewType = full;
101                         break;
102                 case minimumViewType:
103                         viewType = medium;
104                         break;
105                 case miniVierticalType:
106                         viewType = minimum;
107                         break;
108         }
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];
115                 
116                 [details addObject:detail];
117         }];
118         self.details = details;
119         
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];
127         }];
128         
129         self.fleetNumber = 1;
130 }
131
132 - (NSArray *)shipKeys
133 {
134         static NSArray *shipKeys = nil;
135         if(shipKeys) return shipKeys;
136         
137         shipKeys = @[@"ship_0", @"ship_1", @"ship_2", @"ship_3", @"ship_4", @"ship_5"];
138         return shipKeys;
139 }
140
141 - (void)setShipOfViewForKey:(NSString *)key
142 {
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]];
148         }
149 }
150
151 - (void)setShipID:(NSInteger)shipId toDetail:(HMShipDetailViewController *)detail
152 {
153         HMServerDataStore *store = [HMServerDataStore defaultManager];
154         NSError *error = nil;
155         HMKCShipObject *ship = nil;
156         NSArray *array = [store objectsWithEntityName:@"Ship"
157                                                                                         error:&error
158                                                                   predicateFormat:@"id = %ld", shipId];
159         if(error) {
160                 NSLog(@"%s error: %@", __PRETTY_FUNCTION__, error);
161         }
162         if(array.count != 0) {
163                 ship = array[0];
164         }
165         detail.ship = ship;
166         
167         [self willChangeValueForKey:@"repairableShipCount"];
168         [self didChangeValueForKey:@"repairableShipCount"];
169 }
170 - (void)setFleet:(HMKCDeck *)fleet
171 {
172         for(NSString *key in self.shipKeys) {
173                 [self.representedObject removeObserver:self
174                                                                         forKeyPath:key];
175                 
176                 [fleet addObserver:self
177                                 forKeyPath:key
178                                    options:0
179                                    context:NULL];
180         }
181         
182         self.representedObject = fleet;
183         self.title = fleet.name;
184         
185         for(NSString *key in self.shipKeys) {
186                 [self setShipOfViewForKey:key];
187         }
188 }
189 - (HMKCDeck *)fleet
190 {
191         return self.representedObject;
192 }
193
194 - (void)setFleetNumber:(NSInteger)fleetNumber
195 {
196         HMServerDataStore *store = [HMServerDataStore defaultManager];
197         NSError *error = nil;
198         NSArray *array = [store objectsWithEntityName:@"Deck"
199                                                                                         error:NULL
200                                                                   predicateFormat:@"id = %ld", fleetNumber];
201         if(error) {
202                 NSLog(@"%s error: %@", __PRETTY_FUNCTION__, error);
203                 return;
204         }
205         if(array.count == 0) {
206                 return;
207         }
208         
209         self.fleet = array[0];
210         _fleetNumber = fleetNumber;
211         
212         self.anchorageRepair = self.anchorageRepairHolder[fleetNumber - 1];
213 }
214 - (NSInteger)fleetNumber
215 {
216         return _fleetNumber;
217 }
218
219 - (void)setShipOrder:(HMFleetViewShipOrder)shipOrder
220 {
221         if(_shipOrder == shipOrder) return;
222         _shipOrder = shipOrder;
223         
224         switch(shipOrder) {
225                 case doubleLine:
226                         [self reorderShipToDoubleLine];
227                         break;
228                 case leftToRight:
229                         [self reorderShipToLeftToRight];
230                         break;
231         }
232 }
233 - (HMFleetViewShipOrder)shipOrder
234 {
235         return _shipOrder;
236 }
237
238 - (BOOL)canDivide
239 {
240         return self.type == detailViewType;
241 }
242 - (CGFloat)normalHeight
243 {
244         switch(self.type) {
245                 case detailViewType:
246                         return HMFleetViewController.detailViewHeight;
247                 case minimumViewType:
248                         return HMFleetViewController.oldStyleFleetViewHeight;
249                 case miniVierticalType:
250                         //
251                         break;
252         }
253         return 0;
254 }
255 - (CGFloat)upsideHeight
256 {
257         switch(self.type) {
258                 case detailViewType:
259                         return 159;
260                 case minimumViewType:
261                         return HMFleetViewController.oldStyleFleetViewHeight;
262                 case miniVierticalType:
263                         //
264                         break;
265         }
266         return 0;
267 }
268
269 + (CGFloat)oldStyleFleetViewHeight
270 {
271         return 128;
272 }
273 + (CGFloat)detailViewHeight
274 {
275         return 288;
276 }
277 + (CGFloat)heightDifference
278 {
279         return self.detailViewHeight - self.oldStyleFleetViewHeight;
280 }
281
282
283 + (NSSet *)keyPathsForValuesAffectingTotalSakuteki
284 {
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",
292                         nil];
293 }
294 - (NSNumber *)totalSakuteki
295 {
296         NSInteger total = 0;
297         for(HMShipDetailViewController *detail in self.details) {
298                 HMKCShipObject *ship = detail.ship;
299                 total += ship.sakuteki_0.integerValue;
300         }
301         return @(total);
302 }
303
304 + (NSSet *)keyPathsForValuesAffectingTotalSeiku
305 {
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",
313                         nil];
314 }
315 - (NSNumber *)totalSeiku
316 {
317         NSInteger total = 0;
318         for(HMShipDetailViewController *detail in self.details) {
319                 HMKCShipObject *ship = detail.ship;
320                 total += ship.seiku.integerValue;
321         }
322         return @(total);
323 }
324 + (NSSet *)keyPathsForValuesAffectingTotalCalclatedSeiku
325 {
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",
333                         nil];
334 }
335 - (NSNumber *)totalCalclatedSeiku
336 {
337         NSInteger total = 0;
338         for(HMShipDetailViewController *detail in self.details) {
339                 HMKCShipObject *ship = detail.ship;
340                 total += ship.seiku.integerValue;
341                 total += ship.extraSeiku.integerValue;
342         }
343         return @(total);
344 }
345 + (NSSet *)keyPathsForValuesAffectingTotalLevel
346 {
347         return [NSSet setWithObjects:
348                         @"detail01.ship.lv",
349                         @"detail02.ship.lv",
350                         @"detail03.ship.lv",
351                         @"detail04.ship.lv",
352                         @"detail05.ship.lv",
353                         @"detail06.ship.lv",
354                         nil];
355 }
356 - (NSNumber *)totalLevel
357 {
358         NSInteger total = 0;
359         for(HMShipDetailViewController *detail in self.details) {
360                 HMKCShipObject *ship = detail.ship;
361                 total += ship.lv.integerValue;
362         }
363         return @(total);
364 }
365 + (NSSet *)keyPathsForValuesAffectingTotalDrums
366 {
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",
374                         nil];
375 }
376 - (NSNumber *)totalDrums
377 {
378         NSInteger total = 0;
379         for(HMShipDetailViewController *detail in self.details) {
380                 HMKCShipObject *ship = detail.ship;
381                 total += ship.totalDrums.integerValue;
382         }
383         return @(total);
384 }
385
386 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
387 {
388         if([self.shipKeys containsObject:keyPath]) {
389                 [self setShipOfViewForKey:keyPath];
390                 return;
391         }
392         
393         return [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
394 }
395
396 - (IBAction)selectNextFleet:(id)sender
397 {
398         NSInteger next = self.fleetNumber + 1;
399         self.fleetNumber = next <= maxFleetNumber ? next : 1;
400 }
401 - (IBAction)selectPreviousFleet:(id)sender
402 {
403         NSInteger prev = self.fleetNumber - 1;
404         self.fleetNumber = prev > 0 ? prev : 4;
405 }
406
407
408 - (void)reorderShipToDoubleLine
409 {
410         NSView *view02 = self.detail02.view;
411         NSView *view03 = self.detail03.view;
412         NSView *view04 = self.detail04.view;
413         NSView *view05 = self.detail05.view;
414         
415         NSAutoresizingMaskOptions options02 = view02.autoresizingMask;
416         NSAutoresizingMaskOptions options03 = view03.autoresizingMask;
417         NSAutoresizingMaskOptions options04 = view04.autoresizingMask;
418         NSAutoresizingMaskOptions options05 = view05.autoresizingMask;
419         
420         view02.autoresizingMask = options04;
421         view03.autoresizingMask = options02;
422         view04.autoresizingMask = options05;
423         view05.autoresizingMask = options03;
424         
425         NSRect frame02 = view02.frame;
426         NSRect frame03 = view03.frame;
427         NSRect frame04 = view04.frame;
428         NSRect frame05 = view05.frame;
429         
430         if(self.enableAnimation) {
431                 view02.animator.frame = frame04;
432                 view03.animator.frame = frame02;
433                 view04.animator.frame = frame05;
434                 view05.animator.frame = frame03;
435         } else {
436                 view02.frame = frame04;
437                 view03.frame = frame02;
438                 view04.frame = frame05;
439                 view05.frame = frame03;
440         }
441 }
442 - (void)reorderShipToLeftToRight
443 {
444         NSView *view02 = self.detail02.view;
445         NSView *view03 = self.detail03.view;
446         NSView *view04 = self.detail04.view;
447         NSView *view05 = self.detail05.view;
448         
449         NSAutoresizingMaskOptions options02 = view02.autoresizingMask;
450         NSAutoresizingMaskOptions options03 = view03.autoresizingMask;
451         NSAutoresizingMaskOptions options04 = view04.autoresizingMask;
452         NSAutoresizingMaskOptions options05 = view05.autoresizingMask;
453         
454         view02.autoresizingMask = options03;
455         view03.autoresizingMask = options05;
456         view04.autoresizingMask = options02;
457         view05.autoresizingMask = options04;
458         
459         NSRect frame02 = view02.frame;
460         NSRect frame03 = view03.frame;
461         NSRect frame04 = view04.frame;
462         NSRect frame05 = view05.frame;
463         
464         if(self.enableAnimation) {
465                 view02.animator.frame = frame03;
466                 view03.animator.frame = frame05;
467                 view04.animator.frame = frame02;
468                 view05.animator.frame = frame04;
469         } else {
470                 view02.frame = frame03;
471                 view03.frame = frame05;
472                 view04.frame = frame02;
473                 view05.frame = frame04;
474         }
475 }
476
477
478 - (void)buildAnchorageRepairHolder
479 {
480         HMServerDataStore *store = [HMServerDataStore defaultManager];
481         NSError *error = nil;
482         NSArray *array = [store objectsWithEntityName:@"Deck"
483                                                                   sortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"id" ascending:YES]]
484                                                                                 predicate:nil
485                                                                                         error:&error];
486         if(error) {
487                 NSLog(@"%s error: %@", __PRETTY_FUNCTION__, error);
488                 return;
489         }
490         if(array.count == 0) {
491                 return;
492         }
493         if(array.count < 4) {
494                 NSBeep();
495                 NSLog(@"hogehoge");
496                 return;
497         }
498         NSMutableArray *anchorageRepairs = [NSMutableArray new];
499         for(HMKCDeck *deck in array) {
500                 id anchorageRepair = [[HMAnchorageRepairManager alloc] initWithDeck:deck];
501                 [anchorageRepairs addObject:anchorageRepair];
502         }
503         self.anchorageRepairHolder = anchorageRepairs;
504         
505         HMAppDelegate *appDelegate = [[NSApplication sharedApplication] delegate];
506         [appDelegate addCounterUpdateBlock:^{
507                 [self willChangeValueForKey:@"repairTime"];
508                 [self didChangeValueForKey:@"repairTime"];
509         }];
510 }
511 + (NSSet *)keyPathsForValuesAffectingRepairTime
512 {
513         return [NSSet setWithObjects:@"anchorageRepair.repairTime", @"anchorageRepair", nil];
514 }
515 - (NSNumber *)repairTime
516 {
517         NSDate *compTimeValue = self.anchorageRepair.repairTime;
518         if(!compTimeValue) return nil;
519         
520         NSTimeInterval compTime = [compTimeValue timeIntervalSince1970];
521         NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0];
522         NSTimeInterval diff = compTime - [now timeIntervalSince1970];
523         return @(diff + 20 * 60);
524 }
525 + (NSSet *)keyPathsForValuesAffectingRepairableShipCount
526 {
527         return [NSSet setWithObjects:
528                         @"anchorageRepair.repairableShipCount", @"anchorageRepair",
529                         
530                         
531                         nil];
532 }
533 - (NSNumber *)repairableShipCount
534 {
535         return self.anchorageRepair.repairableShipCount;
536 }
537
538 @end