/*
 * Copyright 2016 Google LLC. All rights reserved.
 *
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
 * file except in compliance with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under
 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
 * ANY KIND, either express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

#import "GoogleMapsXCFrameworkDemos/Samples/CustomIndoorViewController.h"

#if __has_feature(modules)
@import GoogleMaps;
#else
#import <GoogleMaps/GoogleMaps.h>
#endif

@interface CustomIndoorViewController () <GMSIndoorDisplayDelegate,
                                          UIPickerViewDelegate,
                                          UIPickerViewDataSource>

@end

@implementation CustomIndoorViewController {
  GMSMapView *_mapView;
  UIPickerView *_levelPickerView;
  NSArray *_levels;
}

- (void)viewDidLoad {
  [super viewDidLoad];
  GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:37.78318
                                                          longitude:-122.403874
                                                               zoom:18];

  // Set backgroundColor, otherwise UIPickerView fades into the background
  self.view.backgroundColor = [UIColor grayColor];

  _mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
  _mapView.settings.myLocationButton = NO;
  _mapView.settings.indoorPicker = NO;  // We are implementing a custom level picker.

  _mapView.indoorEnabled = YES;  // Defaults to YES. Set to NO to hide indoor maps.
  _mapView.indoorDisplay.delegate = self;
  _mapView.translatesAutoresizingMaskIntoConstraints = NO;
  [self.view addSubview:_mapView];

  // This UIPickerView will be populated with the levels of the active building.
  _levelPickerView = [[UIPickerView alloc] init];
  _levelPickerView.delegate = self;
  _levelPickerView.dataSource = self;
  _levelPickerView.showsSelectionIndicator = YES;
  _levelPickerView.translatesAutoresizingMaskIntoConstraints = NO;
  [self.view addSubview:_levelPickerView];

  // The height of the UIPickerView, used below in the vertical constraint
  NSDictionary *metrics = @{@"height" : @180.0};
  NSDictionary *views = NSDictionaryOfVariableBindings(_mapView, _levelPickerView);

  // Constraining the map to the full width of the display. The |_levelPickerView| is constrained
  // below with the NSLayoutFormatAlignAll*. See
  // http://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/Articles/formatLanguage.html
  [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_mapView]|"
                                                                    options:0
                                                                    metrics:metrics
                                                                      views:views]];

  // Constraining the _mapView and the _levelPickerView as siblings taking the full height of the
  // display, with _levelPickerView at 200 points high
  [self.view
      addConstraints:[NSLayoutConstraint
                         constraintsWithVisualFormat:@"V:|[_mapView][_levelPickerView(height)]|"
                                             options:NSLayoutFormatAlignAllLeft |
                                                     NSLayoutFormatAlignAllRight
                                             metrics:metrics
                                               views:views]];
}

#pragma mark - GMSIndoorDisplayDelegate

- (void)didChangeActiveBuilding:(GMSIndoorBuilding *)building {
  // Everytime we change active building force the picker to re-display the labels.

  NSMutableArray *levels = [NSMutableArray array];
  if (building.underground) {
    // If this building is completely underground, add a fake 'top' floor. This must be the 'boxed'
    // nil, [NSNull null], as NSArray/NSMutableArray cannot contain nils.
    [levels addObject:[NSNull null]];
  }
  [levels addObjectsFromArray:building.levels];
  _levels = [levels copy];

  [_levelPickerView reloadAllComponents];
  [_levelPickerView selectRow:0 inComponent:0 animated:NO];

  // UIPickerView insists on having some data; disable interaction if there's no levels.
  _levelPickerView.userInteractionEnabled = (_levels.count > 0);
}

- (void)didChangeActiveLevel:(GMSIndoorLevel *)level {
  // On level change, sync our level picker's selection to the IndoorDisplay.
  if (level == nil) {
    level = (id)[NSNull null];  // box nil to NSNull for use in NSArray
  }
  NSUInteger index = [_levels indexOfObject:level];
  if (index != NSNotFound) {
    NSInteger currentlySelectedLevel = [_levelPickerView selectedRowInComponent:0];
    if ((NSInteger)index != currentlySelectedLevel) {
      [_levelPickerView selectRow:index inComponent:0 animated:NO];
    }
  }
}

#pragma mark - UIPickerViewDelegate

- (void)pickerView:(UIPickerView *)pickerView
      didSelectRow:(NSInteger)row
       inComponent:(NSInteger)component {
  // On user selection of a level in the picker, set the right level in IndoorDisplay
  id level = _levels[row];
  if (level == [NSNull null]) {
    level = nil;  // unbox NSNull
  }
  [_mapView.indoorDisplay setActiveLevel:level];
}

- (NSString *)pickerView:(UIPickerView *)pickerView
             titleForRow:(NSInteger)row
            forComponent:(NSInteger)component {
  id object = _levels[row];
  if (object == [NSNull null]) {
    return @"\u2014";  // use an em dash for 'above ground'
  }
  GMSIndoorLevel *level = object;
  return level.name;
}

#pragma mark - UIPickerViewDataSource

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
  return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
  return _levels.count;
}

@end
