<commit_before>using System;
using System.Globalization;
using System.Collections.Generic;
using System.Threading.Tasks;

using CoreAnimation;
using CoreLocation;
using Foundation;
using MapKit;
using UIKit;

using MyTrips.ViewModel;

using Plugin.Permissions;
using Plugin.Permissions.Abstractions;

namespace MyTrips.iOS
{
	partial class CurrentTripViewController : UIViewController
	{
		List<CLLocationCoordinate2D> route;
		CarAnnotation currentLocationAnnotation;
		TripMapViewDelegate mapDelegate;

		public CurrentTripViewModel CurrentTripViewModel { get; set; }
		public PastTripsDetailViewModel PastTripsDetailViewModel { get; set; }

		public CurrentTripViewController (IntPtr handle) : base (handle)
		{
		}

		public async override void ViewDidLoad()
		{
			base.ViewDidLoad();

			NavigationItem.RightBarButtonItem = null;

			if (PastTripsDetailViewModel == null)
				await ConfigureCurrentTripUserInterface();
			else
				ConfigurePastTripUserInterface();
		}

		public override void ViewDidAppear(bool animated)
		{
			base.ViewDidAppear(animated);
			PopRecordButtonAnimation();
		}

		#region Current Trip User Interface Logic
		async Task ConfigureCurrentTripUserInterface()
		{
			// Configure map
			mapDelegate = new TripMapViewDelegate(true);
			tripMapView.Delegate = mapDelegate;
			tripMapView.ShowsUserLocation = false;
			tripMapView.Camera.Altitude = 5000;

			// Setup record button
			recordButton.Layer.CornerRadius = recordButton.Frame.Width / 2;
			recordButton.Layer.MasksToBounds = true;
			recordButton.Layer.BorderColor = "5C5C5C".ToUIColor().CGColor;
			recordButton.Layer.BorderWidth = 1;
			recordButton.TouchUpInside += RecordButton_TouchUpInside;

			// Hide slider
			tripSlider.Hidden = true;
			wayPointA.Hidden = true;
			wayPointB.Hidden = true;

			UpdateRecordButton(false);
			tripInfoView.Alpha = 0;
			ResetTripInfoView();

			// Setup view model
			CurrentTripViewModel = new CurrentTripViewModel();
			CurrentTripViewModel.Geolocator.PositionChanged += Geolocator_PositionChanged;

			// Start tracking user location, pending permission from user.
			await CurrentTripViewModel.ExecuteStartTrackingTripCommandAsync().ContinueWith(async (task) =>
			{
				// If we don't have permission from the user, prompt a dialog requesting permission.
				await PromptPermissionsChangeDialog();
			});
		}

		void AnimateTripInfoView()
		{
			tripInfoView.FadeIn(0.3, 0);
		}

		void ResetMapViewState()
		{
			InvokeOnMainThread(() =>
		   {
				route = null;
				tripMapView.RemoveAnnotations(tripMapView.Annotations);

			    if (tripMapView.Overlays != null && tripMapView.Overlays.Length > 0)
				{
					tripMapView.RemoveOverlays(tripMapView.Overlays[0]);
				}
		   });
		}

		void ResetTripInfoView()
		{
			labelOneValue.Text = "N/A";
			labelTwoValue.Text = "0";
			labelThreeValue.Text = "0:00";
			labelFourValue.Text = "N/A";
		}

		void UpdateRecordButton(bool isRecording)
		{
			//Corner Radius
			var radiusAnimation = CABasicAnimation.FromKeyPath("cornerRadius");
			radiusAnimation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseIn);
			radiusAnimation.From = NSNumber.FromNFloat(recordButton.Layer.CornerRadius);

			//Border Thickness
			var borderAnimation = CABasicAnimation.FromKeyPath("borderWidth");
			borderAnimation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseIn);
			radiusAnimation.From = NSNumber.FromNFloat(recordButton.Layer.BorderWidth);

			//Animation Group
			var animationGroup = CAAnimationGroup.CreateAnimation();
			animationGroup.Animations = new CAAnimation[] { radiusAnimation, borderAnimation };
			animationGroup.Duration = 0.6;
			animationGroup.FillMode = CAFillMode.Forwards;

			recordButton.Layer.CornerRadius = isRecording ? 4 : recordButton.Frame.Width / 2;
			recordButton.Layer.BorderWidth = isRecording ? 2 : 3;

			recordButton.Layer.AddAnimation(animationGroup, "borderChanges");
		}

		async Task PromptPermissionsChangeDialog()
		{
			var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
			if (status == PermissionStatus.Denied)
			{
				InvokeOnMainThread(() =>
				{
					var alertController = UIAlertController.Create("Location Permission Denied", "Tracking your location is required to record trips. Visit the Settings app to change the permission status.", UIAlertControllerStyle.Alert);
					alertController.AddAction(UIAlertAction.Create("Change Permission", UIAlertActionStyle.Default, (obj) =>
					{
						var url = NSUrl.FromString(UIApplication.OpenSettingsUrlString);
						UIApplication.SharedApplication.OpenUrl(url);
					}));

					alertController.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Cancel, null));

					PresentViewController(alertController, true, null);
				});
			}
		}
	
		async void RecordButton_TouchUpInside(object sender, EventArgs e)
		{
			var position = await CurrentTripViewModel.Geolocator.GetPositionAsync();
			var coordinate = position.ToCoordinate();

			var endpoint = !CurrentTripViewModel.IsRecording ? "A" : "B";
			var annotation = new WaypointAnnotation(coordinate, endpoint);
			tripMapView.AddAnnotation(annotation);

			if (!CurrentTripViewModel.IsRecording)
			{
				UpdateRecordButton(true);
				ResetTripInfoView();
				AnimateTripInfoView();

				await CurrentTripViewModel.StartRecordingTrip();
			}
			else
			{
				if (await CurrentTripViewModel.StopRecordingTrip ()) {
					ResetMapViewState();

					UpdateRecordButton(false);
					tripInfoView.Alpha = 0;

					var vc = Storyboard.InstantiateViewController("tripSummaryTableViewController") as TripSummaryTableViewController;
					vc.ViewModel = CurrentTripViewModel;
					PresentModalViewController(vc, true);
				}
			}
		}

		void Geolocator_PositionChanged(object sender, Plugin.Geolocator.Abstractions.PositionEventArgs e)
		{
			var coordinate = e.Position.ToCoordinate();
			UpdateCarAnnotationPosition (coordinate);

			if (CurrentTripViewModel.IsRecording)
			{
				// Update trip information<commit_msg>[iOS] Obliterate map subviews after recording.<commit_after>using System;
using System.Globalization;
using System.Collections.Generic;
using System.Threading.Tasks;

using CoreAnimation;
using CoreLocation;
using Foundation;
using MapKit;
using UIKit;

using MyTrips.ViewModel;

using Plugin.Permissions;
using Plugin.Permissions.Abstractions;

namespace MyTrips.iOS
{
	partial class CurrentTripViewController : UIViewController
	{
		List<CLLocationCoordinate2D> route;
		CarAnnotation currentLocationAnnotation;
		TripMapViewDelegate mapDelegate;

		public CurrentTripViewModel CurrentTripViewModel { get; set; }
		public PastTripsDetailViewModel PastTripsDetailViewModel { get; set; }

		public CurrentTripViewController (IntPtr handle) : base (handle)
		{
		}

		public async override void ViewDidLoad()
		{
			base.ViewDidLoad();

			NavigationItem.RightBarButtonItem = null;

			if (PastTripsDetailViewModel == null)
				await ConfigureCurrentTripUserInterface();
			else
				ConfigurePastTripUserInterface();
		}

		public override void ViewDidAppear(bool animated)
		{
			base.ViewDidAppear(animated);
			PopRecordButtonAnimation();
		}

		#region Current Trip User Interface Logic
		async Task ConfigureCurrentTripUserInterface()
		{
			// Configure map
			mapDelegate = new TripMapViewDelegate(true);
			tripMapView.Delegate = mapDelegate;
			tripMapView.ShowsUserLocation = false;
			tripMapView.Camera.Altitude = 5000;

			// Setup record button
			recordButton.Layer.CornerRadius = recordButton.Frame.Width / 2;
			recordButton.Layer.MasksToBounds = true;
			recordButton.Layer.BorderColor = "5C5C5C".ToUIColor().CGColor;
			recordButton.Layer.BorderWidth = 1;
			recordButton.TouchUpInside += RecordButton_TouchUpInside;

			// Hide slider
			tripSlider.Hidden = true;
			wayPointA.Hidden = true;
			wayPointB.Hidden = true;

			UpdateRecordButton(false);
			tripInfoView.Alpha = 0;
			ResetTripInfoView();

			// Setup view model
			CurrentTripViewModel = new CurrentTripViewModel();
			CurrentTripViewModel.Geolocator.PositionChanged += Geolocator_PositionChanged;

			// Start tracking user location, pending permission from user.
			await CurrentTripViewModel.ExecuteStartTrackingTripCommandAsync().ContinueWith(async (task) =>
			{
				// If we don't have permission from the user, prompt a dialog requesting permission.
				await PromptPermissionsChangeDialog();
			});
		}

		void AnimateTripInfoView()
		{
			tripInfoView.FadeIn(0.3, 0);
		}

		void ResetMapViewState()
		{
			InvokeOnMainThread(() =>
		   {
				route = null;
				tripMapView.RemoveAnnotations(tripMapView.Annotations);

			    if (tripMapView.Overlays != null && tripMapView.Overlays.Length > 0)
				{
					tripMapView.RemoveOverlays(tripMapView.Overlays[0]);
				}
		   });
		}

		void ResetTripInfoView()
		{
			labelOneValue.Text = "N/A";
			labelTwoValue.Text = "0";
			labelThreeValue.Text = "0:00";
			labelFourValue.Text = "N/A";
		}

		void UpdateRecordButton(bool isRecording)
		{
			//Corner Radius
			var radiusAnimation = CABasicAnimation.FromKeyPath("cornerRadius");
			radiusAnimation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseIn);
			radiusAnimation.From = NSNumber.FromNFloat(recordButton.Layer.CornerRadius);

			//Border Thickness
			var borderAnimation = CABasicAnimation.FromKeyPath("borderWidth");
			borderAnimation.TimingFunction = CAMediaTimingFunction.FromName(CAMediaTimingFunction.EaseIn);
			radiusAnimation.From = NSNumber.FromNFloat(recordButton.Layer.BorderWidth);

			//Animation Group
			var animationGroup = CAAnimationGroup.CreateAnimation();
			animationGroup.Animations = new CAAnimation[] { radiusAnimation, borderAnimation };
			animationGroup.Duration = 0.6;
			animationGroup.FillMode = CAFillMode.Forwards;

			recordButton.Layer.CornerRadius = isRecording ? 4 : recordButton.Frame.Width / 2;
			recordButton.Layer.BorderWidth = isRecording ? 2 : 3;

			recordButton.Layer.AddAnimation(animationGroup, "borderChanges");
		}

		async Task PromptPermissionsChangeDialog()
		{
			var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
			if (status == PermissionStatus.Denied)
			{
				InvokeOnMainThread(() =>
				{
					var alertController = UIAlertController.Create("Location Permission Denied", "Tracking your location is required to record trips. Visit the Settings app to change the permission status.", UIAlertControllerStyle.Alert);
					alertController.AddAction(UIAlertAction.Create("Change Permission", UIAlertActionStyle.Default, (obj) =>
					{
						var url = NSUrl.FromString(UIApplication.OpenSettingsUrlString);
						UIApplication.SharedApplication.OpenUrl(url);
					}));

					alertController.AddAction(UIAlertAction.Create("OK", UIAlertActionStyle.Cancel, null));

					PresentViewController(alertController, true, null);
				});
			}
		}
	
		async void RecordButton_TouchUpInside(object sender, EventArgs e)
		{
			var position = await CurrentTripViewModel.Geolocator.GetPositionAsync();
			var coordinate = position.ToCoordinate();

			var endpoint = !CurrentTripViewModel.IsRecording ? "A" : "B";
			var annotation = new WaypointAnnotation(coordinate, endpoint);
			tripMapView.AddAnnotation(annotation);

			if (!CurrentTripViewModel.IsRecording)
			{
				UpdateRecordButton(true);
				ResetTripInfoView();
				AnimateTripInfoView();

				await CurrentTripViewModel.StartRecordingTrip();
			}
			else
			{
				if (await CurrentTripViewModel.StopRecordingTrip ()) {
					ResetMapViewState();
					InvokeOnMainThread (delegate {
						mapDelegate = new TripMapViewDelegate(true);
						tripMapView.Delegate = mapDelegate;
					});

					UpdateRecordButton(false);
					tripInfoView.Alpha = 0;

					var vc = Storyboard.InstantiateViewController("tripSummaryTableViewController") as TripSummaryTableViewController;
					vc.ViewModel = CurrentTripViewModel;
					PresentModalViewController(vc, true);
				}
			}
		}

		void Geolocator_PositionChanged(object sender, Plugin.Geolocator.Abstractions.PositionEventArgs e)
		{
			var coordinate = e.Position.ToCoordinate();
			UpdateCarAnnotationPosition (coordinate);

			if (CurrentTripViewModel.IsRecording)
			{
				// Update trip information
{'fraction_non_alphanumeric': 0.09215574238837645, 'fraction_numerical': 0.004407803444616766, 'mean_word_length': 4.496635262449529, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, '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': '3752678', 'n_tokens_mistral': 4337, 'n_tokens_neox': 3479, 'n_words': 685}