<commit_before>//
//  MWMLocationButtonView.m
//  Maps
//
//  Created by <NAME> on 14.05.15.
//  Copyright (c) 2015 MapsWithMe. All rights reserved.
//

#import "MWMLocationButtonView.h"
#import "MWMMapViewControlsCommon.h"
#import "UIKitCategories.h"

@interface MWMLocationButtonView()

@property (nonatomic) CGRect defaultBounds;

@end

@implementation MWMLocationButtonView

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
  self = [super initWithCoder:aDecoder];
  if (self)
  {
    self.defaultBounds = self.bounds;
    self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.locationState = location::State::UnknownPosition;
  }
  return self;
}

- (void)layoutSubviews
{
  [super layoutSubviews];
  self.bounds = self.defaultBounds;
  [self layoutXPosition:self.hidden];
  self.maxY = self.superview.height - 2.0 * kViewControlsOffsetToBounds;
}

- (void)layoutXPosition:(BOOL)hidden
{
  if (hidden)
    self.maxX = 0.0;
  else
    self.minX = 2.0 * kViewControlsOffsetToBounds;
}

- (void)setImageNamed:(location::State::Mode)state
{
  if (state == location::State::PendingPosition)
    [self setPendingPositionAnimation];
  else
  {
    static NSDictionary const * const stateMap = @{@(location::State::UnknownPosition).stringValue : @"btn_white_unknow_position",
                                                   @(location::State::NotFollow).stringValue : @"btn_white_target_off_1",
                                                   @(location::State::Follow).stringValue : @"btn_white_target_on",
                                                   @(location::State::RotateAndFollow).stringValue : @"btn_white_direction"};
    [self.imageView stopAnimating];
    NSString * const imageName = stateMap[@(state).stringValue];
    self.highlighted = NO;
    [self setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
    [self setImage:[UIImage imageNamed:[imageName stringByAppendingString:@"_pressed"]] forState:UIControlStateHighlighted];
  }
}

- (void)setAnimation:(NSArray *)animationImages once:(BOOL)once
{
  UIImageView const * const animationIV = self.imageView;
  animationIV.animationImages = animationImages;
  animationIV.animationDuration = framesDuration(animationImages.count);
  animationIV.animationRepeatCount = once ? 1 : 0;
  [animationIV startAnimating];
}

- (void)setPendingPositionAnimation
{
  NSString const * const imageName = @"btn_white_loading_";
  [self setImage:[UIImage imageNamed:[imageName stringByAppendingString:@"1"]] forState:UIControlStateNormal];
  static NSUInteger const animationImagesCount = 18;
  NSMutableArray * const animationImages = [NSMutableArray arrayWithCapacity:animationImagesCount];
  for (NSUInteger i = 0; i < animationImagesCount; ++i)
    animationImages[i] = [UIImage imageNamed:[NSString stringWithFormat:@"%@%@", imageName, @(i+1)]];
  [self setAnimation:animationImages once:NO];
}

- (void)changeButtonFromState:(location::State::Mode)beginState toState:(location::State::Mode)endState
{
  [self setImageNamed:endState];
  static NSDictionary const * const stateMap = @{@(location::State::UnknownPosition).stringValue : @"noposition",
                                                 @(location::State::PendingPosition).stringValue : @"pending",
                                                 @(location::State::NotFollow).stringValue : @"notfollow",
                                                 @(location::State::Follow).stringValue : @"follow",
                                                 @(location::State::RotateAndFollow).stringValue : @"followandrotate"};
  NSString const * const changeAnimation = [NSString stringWithFormat:@"%@_to_%@_", stateMap[@(beginState).stringValue], stateMap[@(endState).stringValue]];
  static NSUInteger const animationImagesCount = 6;
  NSMutableArray * const animationImages = [NSMutableArray arrayWithCapacity:animationImagesCount];
  for (NSUInteger i = 0; i < animationImagesCount; ++i)
    animationImages[i] = [UIImage imageNamed:[NSString stringWithFormat:@"%@%@", changeAnimation, @(i+1)]];
  [self setAnimation:animationImages once:YES];<commit_msg>[ios] Workaround to fix location button animation crash.<commit_after>//
//  MWMLocationButtonView.m
//  Maps
//
//  Created by <NAME> on 14.05.15.
//  Copyright (c) 2015 MapsWithMe. All rights reserved.
//

#import "MWMLocationButtonView.h"
#import "MWMMapViewControlsCommon.h"
#import "UIKitCategories.h"

#import "3party/Alohalytics/src/alohalytics_objc.h"

@interface MWMLocationButtonView()

@property (nonatomic) CGRect defaultBounds;

@end

@implementation MWMLocationButtonView

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
  self = [super initWithCoder:aDecoder];
  if (self)
  {
    self.defaultBounds = self.bounds;
    self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.locationState = location::State::UnknownPosition;
  }
  return self;
}

- (void)layoutSubviews
{
  [super layoutSubviews];
  self.bounds = self.defaultBounds;
  [self layoutXPosition:self.hidden];
  self.maxY = self.superview.height - 2.0 * kViewControlsOffsetToBounds;
}

- (void)layoutXPosition:(BOOL)hidden
{
  if (hidden)
    self.maxX = 0.0;
  else
    self.minX = 2.0 * kViewControlsOffsetToBounds;
}

- (void)setImageNamed:(location::State::Mode)state
{
  if (state == location::State::PendingPosition)
    [self setPendingPositionAnimation];
  else
  {
    static NSDictionary const * const stateMap = @{@(location::State::UnknownPosition).stringValue : @"btn_white_unknow_position",
                                                   @(location::State::NotFollow).stringValue : @"btn_white_target_off_1",
                                                   @(location::State::Follow).stringValue : @"btn_white_target_on",
                                                   @(location::State::RotateAndFollow).stringValue : @"btn_white_direction"};
    [self.imageView stopAnimating];
    NSString * const imageName = stateMap[@(state).stringValue];
    self.highlighted = NO;
    [self setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
    [self setImage:[UIImage imageNamed:[imageName stringByAppendingString:@"_pressed"]] forState:UIControlStateHighlighted];
  }
}

- (void)setAnimation:(NSArray *)animationImages once:(BOOL)once
{
  UIImageView const * const animationIV = self.imageView;
  animationIV.animationImages = animationImages;
  animationIV.animationDuration = framesDuration(animationImages.count);
  animationIV.animationRepeatCount = once ? 1 : 0;
  [animationIV startAnimating];
}

- (void)setPendingPositionAnimation
{
  NSString const * const imageName = @"btn_white_loading_";
  [self setImage:[UIImage imageNamed:[imageName stringByAppendingString:@"1"]] forState:UIControlStateNormal];
  static NSUInteger const animationImagesCount = 18;
  NSMutableArray * const animationImages = [NSMutableArray arrayWithCapacity:animationImagesCount];
  for (NSUInteger i = 0; i < animationImagesCount; ++i)
    animationImages[i] = [UIImage imageNamed:[NSString stringWithFormat:@"%@%@", imageName, @(i+1)]];
  [self setAnimation:animationImages once:NO];
}

- (void)changeButtonFromState:(location::State::Mode)beginState toState:(location::State::Mode)endState
{
  NSAssert1(beginState != endState, @"MWMLocationButtonView::(changeButtonFromState:toState:) states must be different! state:%@", @(beginState));
  [self setImageNamed:endState];
  static NSDictionary const * const stateMap = @{@(location::State::UnknownPosition).stringValue : @"noposition",
                                                 @(location::State::PendingPosition).stringValue : @"pending",
                                                 @(location::State::NotFollow).stringValue : @"notfollow",
                                                 @(location::State::Follow).stringValue : @"follow",
                                                 @(location::State::RotateAndFollow).stringValue : @"followandrotate"};
  NSString const * const changeAnimation = [NSString stringWithFormat:@"%@_to_%@_", stateMap[@(beginState).stringValue], stateMap[@(endState).stringValue]];
  static NSUInteger const animationImagesCount = 6;
  NSMutableArray * const animationImages = [NSMutableArray arrayWithCapacity:animationImagesCount];
  for (NSUInteger i = 0; i < animationImagesCount; ++i)
  {
    NSString * imageName = [NSString stringWithFormat:@"%@%@", changeAnimation, @(i+1)];
    UIImage * image = [UIImage imageNamed:imageName];
    NSAssert1(image, @"MWMLocationButtonView::(changeButtonFromState:toState:) image is nil! imageName: %@", imageName);
    if (image)
    {
      animationImages[i] = image;
    }
    else
    {
      // TODO(grechuhin): Temporary, check Alohalytics logs and clean implementation.
      [Alohalytics logEvent:@"MWMLocationButtonViewChangeButtonFromStateToStateInvalidImageName" withValue:imageName];
      [self changeStateFinish];
      return;
    }
  }
  [self setAnimation:animationImages once:YES];
{'fraction_non_alphanumeric': 0.12220994475138122, 'fraction_numerical': 0.006298342541436464, 'mean_word_length': 3.954022988505747, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 28, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2148306', 'n_tokens_mistral': 2689, 'n_tokens_neox': 2535, 'n_words': 469}