<commit_before>//
//  TKInterAppCommunicator.swift
//  TripKitInterApp-iOS
//
//  Created by <NAME> on 05.04.18.
//  Copyright © 2018 SkedGo. All rights reserved.
//

import Foundation

extension TKInterAppCommunicator {
  
  @objc(canOpenInMapsApp:)
  public static func canOpenInMapsApp(_ segment: TKSegment) -> Bool {
    return turnByTurnMode(segment) != nil
  }
  
  public static func turnByTurnMode(_ segment: TKSegment) -> TKTurnByTurnMode? {
    return segment.template?.turnByTurnMode
  }
  
}

extension TKInterAppCommunicator {
  
  // MARK: - Device Capability
  
  @objc
  public static func deviceHasGoogleMaps() -> Bool {
    let testURL = URL(string: "comgooglemaps-x-callback://")!
    return UIApplication.shared.canOpenURL(testURL)
  }
  
  @objc
  public static func deviceHasWaze() -> Bool {
    let testURL = URL(string: "waze://")!
    return UIApplication.shared.canOpenURL(testURL)
  }
  
  // MARK: - Open Maps Apps From Trip Segment
  
  /**
   Opens the segment in a maps app. Either directly in Apple Maps if nothing else is installed, or it will prompt for using Google Maps or Waze.
   @param segment A segment for which `canOpenInMapsApp` returns YES
   @param controller A controller to present the optional action sheet on
   @param sender An optional sender on which to anchor the optional action sheet
   @param currentLocationHandler Will be called to check if turn-by-turn navigation should start at the current location or at the segment's start location. If `nil` it will start at the current location.
   */
  
  @objc(openSegmentInMapsApp:forViewController:initiatedBy:currentLocationHandler:)
  public static func openSegmentInMapsApp(
      _ segment: TKSegment,
      forViewController controller: UIViewController,
      initiatedBy sender: Any,
      currentLocationHandler: ((TKSegment) -> Bool)?
    ) {
    
    let hasGoogleMaps = deviceHasGoogleMaps()
    let hasWaze = deviceHasWaze()
    
    if !hasGoogleMaps && !hasWaze {
      // just open Apple Maps
      openSegmentInAppleMaps(segment, currentLocationHandler: currentLocationHandler)
    } else {
      let actions = SGActions(title: Loc.GetDirections)
      
      // Apple Maps
      actions.addAction(Loc.AppleMaps) {
        openSegmentInAppleMaps(segment, currentLocationHandler: currentLocationHandler)
      }
      
      // Google Maps
      if (hasGoogleMaps) {
        actions.addAction(Loc.GoogleMaps) {
          openSegmentInGoogleMaps(segment, currentLocationHandler: currentLocationHandler)
        }
      }
      
      // Waze
      if (hasWaze) {
        actions.addAction("Waze") {
          openSegmentInWaze(segment)
        }
      }
      
      actions.hasCancel = true
      actions.showForSender(sender, in: controller)
    }
  }
  
  private static func openSegmentInAppleMaps(_ segment: TKSegment, currentLocationHandler: ((TKSegment) -> Bool)?) {
    guard
      let mode = turnByTurnMode(segment),
      let destination = segment.end
      else {
        assert(false, "Turn by turn navigation does not apply to this segment OR segment does not have a destination")
    }
    
    var origin: MKAnnotation?
    if currentLocationHandler?(segment) == false {
      origin = segment.start
    }
    
    openAppleMaps(in: mode, routeFrom: origin, to: destination)
  }
  
  private static func openSegmentInGoogleMaps(_ segment: TKSegment, currentLocationHandler: ((TKSegment) -> Bool)?) {
    guard
      let mode = turnByTurnMode(segment),
      let destination = segment.end
      else {
        assert(false, "Turn by turn navigation does not apply to this segment OR segment does not have a destination")
    }
    
    var origin: MKAnnotation?
    if currentLocationHandler?(segment) == false {
      origin = segment.start
    }
    
    openGoogleMaps(in: mode, routeFrom: origin, to: destination)
  }
  
  private static func openSegmentInWaze(_ segment: TKSegment) {
    guard
      let destination = segment.end,
      let mode = turnByTurnMode(segment),
      mode == .driving
      else {
      assert(false, "Trying to open Waze without a destination OR the segment isn't a driving.")
    }
    
    openWaze(routeTo: destination)
  }
  
  // MARK: - Open Maps Apps
  
  public static func openMapsApp(
      in mode: TKTurnByTurnMode,
      routeFrom origin: MKAnnotation?,
      to destination: MKAnnotation,
      viewController controller: UIViewController,
      initiatedBy sender: Any
    ) {
    
    let hasGoogleMaps = deviceHasGoogleMaps()<commit_msg>sender can be optional<commit_after>//
//  TKInterAppCommunicator.swift
//  TripKitInterApp-iOS
//
//  Created by <NAME> on 05.04.18.
//  Copyright © 2018 SkedGo. All rights reserved.
//

import Foundation

extension TKInterAppCommunicator {
  
  @objc(canOpenInMapsApp:)
  public static func canOpenInMapsApp(_ segment: TKSegment) -> Bool {
    return turnByTurnMode(segment) != nil
  }
  
  public static func turnByTurnMode(_ segment: TKSegment) -> TKTurnByTurnMode? {
    return segment.template?.turnByTurnMode
  }
  
}

extension TKInterAppCommunicator {
  
  // MARK: - Device Capability
  
  @objc
  public static func deviceHasGoogleMaps() -> Bool {
    let testURL = URL(string: "comgooglemaps-x-callback://")!
    return UIApplication.shared.canOpenURL(testURL)
  }
  
  @objc
  public static func deviceHasWaze() -> Bool {
    let testURL = URL(string: "waze://")!
    return UIApplication.shared.canOpenURL(testURL)
  }
  
  // MARK: - Open Maps Apps From Trip Segment
  
  /**
   Opens the segment in a maps app. Either directly in Apple Maps if nothing else is installed, or it will prompt for using Google Maps or Waze.
   @param segment A segment for which `canOpenInMapsApp` returns YES
   @param controller A controller to present the optional action sheet on
   @param sender An optional sender on which to anchor the optional action sheet
   @param currentLocationHandler Will be called to check if turn-by-turn navigation should start at the current location or at the segment's start location. If `nil` it will start at the current location.
   */
  
  @objc(openSegmentInMapsApp:forViewController:initiatedBy:currentLocationHandler:)
  public static func openSegmentInMapsApp(
      _ segment: TKSegment,
      forViewController controller: UIViewController,
      initiatedBy sender: Any,
      currentLocationHandler: ((TKSegment) -> Bool)?
    ) {
    
    let hasGoogleMaps = deviceHasGoogleMaps()
    let hasWaze = deviceHasWaze()
    
    if !hasGoogleMaps && !hasWaze {
      // just open Apple Maps
      openSegmentInAppleMaps(segment, currentLocationHandler: currentLocationHandler)
    } else {
      let actions = SGActions(title: Loc.GetDirections)
      
      // Apple Maps
      actions.addAction(Loc.AppleMaps) {
        openSegmentInAppleMaps(segment, currentLocationHandler: currentLocationHandler)
      }
      
      // Google Maps
      if (hasGoogleMaps) {
        actions.addAction(Loc.GoogleMaps) {
          openSegmentInGoogleMaps(segment, currentLocationHandler: currentLocationHandler)
        }
      }
      
      // Waze
      if (hasWaze) {
        actions.addAction("Waze") {
          openSegmentInWaze(segment)
        }
      }
      
      actions.hasCancel = true
      actions.showForSender(sender, in: controller)
    }
  }
  
  private static func openSegmentInAppleMaps(_ segment: TKSegment, currentLocationHandler: ((TKSegment) -> Bool)?) {
    guard
      let mode = turnByTurnMode(segment),
      let destination = segment.end
      else {
        assert(false, "Turn by turn navigation does not apply to this segment OR segment does not have a destination")
    }
    
    var origin: MKAnnotation?
    if currentLocationHandler?(segment) == false {
      origin = segment.start
    }
    
    openAppleMaps(in: mode, routeFrom: origin, to: destination)
  }
  
  private static func openSegmentInGoogleMaps(_ segment: TKSegment, currentLocationHandler: ((TKSegment) -> Bool)?) {
    guard
      let mode = turnByTurnMode(segment),
      let destination = segment.end
      else {
        assert(false, "Turn by turn navigation does not apply to this segment OR segment does not have a destination")
    }
    
    var origin: MKAnnotation?
    if currentLocationHandler?(segment) == false {
      origin = segment.start
    }
    
    openGoogleMaps(in: mode, routeFrom: origin, to: destination)
  }
  
  private static func openSegmentInWaze(_ segment: TKSegment) {
    guard
      let destination = segment.end,
      let mode = turnByTurnMode(segment),
      mode == .driving
      else {
      assert(false, "Trying to open Waze without a destination OR the segment isn't a driving.")
    }
    
    openWaze(routeTo: destination)
  }
  
  // MARK: - Open Maps Apps
  
  public static func openMapsApp(
      in mode: TKTurnByTurnMode,
      routeFrom origin: MKAnnotation?,
      to destination: MKAnnotation,
      viewController controller: UIViewController,
      initiatedBy sender: Any?
    ) {
    
    let hasGoogleMaps = deviceHasGoogleMaps()
{'fraction_non_alphanumeric': 0.08103028963077603, 'fraction_numerical': 0.002210921954455008, 'mean_word_length': 2.9369016536118364, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6340403', 'n_tokens_mistral': 2673, 'n_tokens_neox': 2584, 'n_words': 768}