<commit_before>﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading.Tasks;
using Xamarin.Forms;
using static System.Math;
using static Xamarin.Forms.AbsoluteLayout;
using IList = System.Collections.IList;

namespace Xamarin.CommunityToolkit.UI.Views
{
	[ContentProperty(nameof(Children))]
	public class SideMenuView : BaseTemplatedView<AbsoluteLayout>
	{
		const string animationName = nameof(SideMenuView);

		const uint animationRate = 16;

		const uint animationLength = 350;

		const int maxTimeShiftItemsCount = 24;

		const int minSwipeTimeShiftItemsCount = 2;

		const double swipeThresholdDistance = 17;

		const double acceptMoveThresholdPercentage = 0.3;

		const uint swipeAnimationAccelerationFactor = 2;

		static readonly Easing animationEasing = Easing.SinOut;

		static readonly TimeSpan swipeThresholdTime = TimeSpan.FromMilliseconds(Device.RuntimePlatform == Device.Android ? 100 : 60);

		readonly List<TimeShiftItem> timeShiftItems = new List<TimeShiftItem>();

		readonly SideMenuElementCollection children = new SideMenuElementCollection();

		View overlayView;

		View mainView;

		View leftMenu;

		View rightMenu;

		View activeMenu;

		View inactiveMenu;

		double zeroShift;

		bool isGestureStarted;

		bool isGestureDirectionResolved;

		bool isSwipe;

		double previousShift;

		public static readonly BindableProperty ShiftProperty
			= BindableProperty.Create(nameof(Shift), typeof(double), typeof(SideMenuView), 0.0, BindingMode.OneWayToSource);

		public static readonly BindableProperty CurrentGestureShiftProperty
			= BindableProperty.Create(nameof(CurrentGestureShift), typeof(double), typeof(SideMenuView), 0.0, BindingMode.OneWayToSource);

		public static readonly BindableProperty GestureThresholdProperty
			= BindableProperty.Create(nameof(GestureThreshold), typeof(double), typeof(SideMenuView), 7.0);

		public static readonly BindableProperty CancelVerticalGestureThresholdProperty
			= BindableProperty.Create(nameof(CancelVerticalGestureThreshold), typeof(double), typeof(SideMenuView), 1.0);

		public static readonly BindableProperty AllowInterceptGestureProperty
			= BindableProperty.Create(nameof(AllowInterceptGesture), typeof(bool), typeof(SideMenuView), false);

		public static readonly BindableProperty StateProperty
			= BindableProperty.Create(nameof(State), typeof(SideMenuState), typeof(SideMenuView), SideMenuState.MainViewShown, BindingMode.TwoWay, propertyChanged: OnStatePropertyChanged);

		public static readonly BindableProperty CurrentGestureStateProperty
			= BindableProperty.Create(nameof(CurrentGestureState), typeof(SideMenuState), typeof(SideMenuView), SideMenuState.MainViewShown, BindingMode.OneWayToSource);

		public static readonly BindableProperty PositionProperty
			= BindableProperty.CreateAttached(nameof(GetPosition), typeof(SideMenuPosition), typeof(SideMenuView), SideMenuPosition.MainView);

		public static readonly BindableProperty MenuWidthPercentageProperty
			= BindableProperty.CreateAttached(nameof(GetMenuWidthPercentage), typeof(double), typeof(SideMenuView), -1.0);

		public static readonly BindableProperty MenuGestureEnabledProperty
			= BindableProperty.CreateAttached(nameof(GetMenuGestureEnabled), typeof(bool), typeof(SideMenuView), true);

		internal void OnPanUpdated(object sender, PanUpdatedEventArgs e)
		{
			var shift = e.TotalX;
			var verticalShift = e.TotalY;
			switch (e.StatusType)
			{
				case GestureStatus.Started:
					OnTouchStarted();
					return;
				case GestureStatus.Running:
					OnTouchChanged(shift, verticalShift);
					return;
				case GestureStatus.Canceled:
				case GestureStatus.Completed:
					if (Device.RuntimePlatform == Device.Android)
						OnTouchChanged(shift, verticalShift);

					OnTouchEnded();
					return;
			}
		}

		internal async void OnSwiped(SwipeDirection swipeDirection)
		{
			await Task.Delay(1);
			if (isGestureStarted)
				return;

			var state = ResolveSwipeState(swipeDirection == SwipeDirection.Right);
			UpdateState(state, true);
		}

		public new ISideMenuList<View> Children
			=> children;

		public double Shift
		{
			get => (double)GetValue(ShiftProperty);
			set => SetValue(ShiftProperty, value);
		}

		public double CurrentGestureShift
		{
			get => (double)GetValue(CurrentGestureShiftProperty);
			set => SetValue(CurrentGestureShiftProperty, value);
		}

		public double GestureThreshold
		{
			get => (double)GetValue(GestureThresholdProperty);
			set => SetValue(GestureThresholdProperty, value);
		}

		public double CancelVerticalGestureThreshold
		{
			get => (double)GetValue(CancelVerticalGestureThresholdProperty);
			set => SetValue(CancelVerticalGestureThresholdProperty, value);
		}

		public bool AllowInterceptGesture
		{
			get => (bool)GetValue(AllowInterceptGestureProperty);
			set => SetValue(AllowInterceptGestureProperty, value);
		}

		public SideMenuState State
		{
			get => (SideMenuState)GetValue(StateProperty);
			set => SetValue(StateProperty, value);
		}

		public SideMenuState CurrentGestureState
		{
			get => (SideMenuState)GetValue(CurrentGestureStateProperty);
			set => SetValue(CurrentGestureStateProperty, value);
		}

		public static SideMenuPosition GetPosition(BindableObject bindable)
			=> (SideMenuPosition)bindable.GetValue(PositionProperty);

		public static void SetPosition(BindableObject bindable, SideMenuPosition value)
			=> bindable.SetValue(PositionProperty, value);

		public static double GetMenuWidthPercentage(BindableObject bindable)
			=> (double)bindable.GetValue(MenuWidthPercentageProperty);

		public static void SetMenuWidthPercentage(BindableObject bindable, double value)
			=> bindable.SetValue(MenuWidthPercentageProperty, value);

		public static bool GetMenuGestureEnabled(BindableObject bindable)
			=> (bool)bindable.GetValue(MenuGestureEnabledProperty);

		public static void SetMenuGestureEnabled(BindableObject bindable, bool value)
			=> bindable.SetValue(MenuGestureEnabledProperty, value);

		protected override void OnControlInitialized(AbsoluteLayout control)
		{
			children.CollectionChanged += OnChildrenCollectionChanged;

			overlayView = SetupMainViewLayout(new BoxView
			{
				InputTransparent = true,<commit_msg>Set SideMenuView -> overlayView.BackgrounColor = Transparent (#423)<commit_after>﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Threading.Tasks;
using Xamarin.Forms;
using static System.Math;
using static Xamarin.Forms.AbsoluteLayout;
using IList = System.Collections.IList;

namespace Xamarin.CommunityToolkit.UI.Views
{
	[ContentProperty(nameof(Children))]
	public class SideMenuView : BaseTemplatedView<AbsoluteLayout>
	{
		const string animationName = nameof(SideMenuView);

		const uint animationRate = 16;

		const uint animationLength = 350;

		const int maxTimeShiftItemsCount = 24;

		const int minSwipeTimeShiftItemsCount = 2;

		const double swipeThresholdDistance = 17;

		const double acceptMoveThresholdPercentage = 0.3;

		const uint swipeAnimationAccelerationFactor = 2;

		static readonly Easing animationEasing = Easing.SinOut;

		static readonly TimeSpan swipeThresholdTime = TimeSpan.FromMilliseconds(Device.RuntimePlatform == Device.Android ? 100 : 60);

		readonly List<TimeShiftItem> timeShiftItems = new List<TimeShiftItem>();

		readonly SideMenuElementCollection children = new SideMenuElementCollection();

		View overlayView;

		View mainView;

		View leftMenu;

		View rightMenu;

		View activeMenu;

		View inactiveMenu;

		double zeroShift;

		bool isGestureStarted;

		bool isGestureDirectionResolved;

		bool isSwipe;

		double previousShift;

		public static readonly BindableProperty ShiftProperty
			= BindableProperty.Create(nameof(Shift), typeof(double), typeof(SideMenuView), 0.0, BindingMode.OneWayToSource);

		public static readonly BindableProperty CurrentGestureShiftProperty
			= BindableProperty.Create(nameof(CurrentGestureShift), typeof(double), typeof(SideMenuView), 0.0, BindingMode.OneWayToSource);

		public static readonly BindableProperty GestureThresholdProperty
			= BindableProperty.Create(nameof(GestureThreshold), typeof(double), typeof(SideMenuView), 7.0);

		public static readonly BindableProperty CancelVerticalGestureThresholdProperty
			= BindableProperty.Create(nameof(CancelVerticalGestureThreshold), typeof(double), typeof(SideMenuView), 1.0);

		public static readonly BindableProperty AllowInterceptGestureProperty
			= BindableProperty.Create(nameof(AllowInterceptGesture), typeof(bool), typeof(SideMenuView), false);

		public static readonly BindableProperty StateProperty
			= BindableProperty.Create(nameof(State), typeof(SideMenuState), typeof(SideMenuView), SideMenuState.MainViewShown, BindingMode.TwoWay, propertyChanged: OnStatePropertyChanged);

		public static readonly BindableProperty CurrentGestureStateProperty
			= BindableProperty.Create(nameof(CurrentGestureState), typeof(SideMenuState), typeof(SideMenuView), SideMenuState.MainViewShown, BindingMode.OneWayToSource);

		public static readonly BindableProperty PositionProperty
			= BindableProperty.CreateAttached(nameof(GetPosition), typeof(SideMenuPosition), typeof(SideMenuView), SideMenuPosition.MainView);

		public static readonly BindableProperty MenuWidthPercentageProperty
			= BindableProperty.CreateAttached(nameof(GetMenuWidthPercentage), typeof(double), typeof(SideMenuView), -1.0);

		public static readonly BindableProperty MenuGestureEnabledProperty
			= BindableProperty.CreateAttached(nameof(GetMenuGestureEnabled), typeof(bool), typeof(SideMenuView), true);

		internal void OnPanUpdated(object sender, PanUpdatedEventArgs e)
		{
			var shift = e.TotalX;
			var verticalShift = e.TotalY;
			switch (e.StatusType)
			{
				case GestureStatus.Started:
					OnTouchStarted();
					return;
				case GestureStatus.Running:
					OnTouchChanged(shift, verticalShift);
					return;
				case GestureStatus.Canceled:
				case GestureStatus.Completed:
					if (Device.RuntimePlatform == Device.Android)
						OnTouchChanged(shift, verticalShift);

					OnTouchEnded();
					return;
			}
		}

		internal async void OnSwiped(SwipeDirection swipeDirection)
		{
			await Task.Delay(1);
			if (isGestureStarted)
				return;

			var state = ResolveSwipeState(swipeDirection == SwipeDirection.Right);
			UpdateState(state, true);
		}

		public new ISideMenuList<View> Children
			=> children;

		public double Shift
		{
			get => (double)GetValue(ShiftProperty);
			set => SetValue(ShiftProperty, value);
		}

		public double CurrentGestureShift
		{
			get => (double)GetValue(CurrentGestureShiftProperty);
			set => SetValue(CurrentGestureShiftProperty, value);
		}

		public double GestureThreshold
		{
			get => (double)GetValue(GestureThresholdProperty);
			set => SetValue(GestureThresholdProperty, value);
		}

		public double CancelVerticalGestureThreshold
		{
			get => (double)GetValue(CancelVerticalGestureThresholdProperty);
			set => SetValue(CancelVerticalGestureThresholdProperty, value);
		}

		public bool AllowInterceptGesture
		{
			get => (bool)GetValue(AllowInterceptGestureProperty);
			set => SetValue(AllowInterceptGestureProperty, value);
		}

		public SideMenuState State
		{
			get => (SideMenuState)GetValue(StateProperty);
			set => SetValue(StateProperty, value);
		}

		public SideMenuState CurrentGestureState
		{
			get => (SideMenuState)GetValue(CurrentGestureStateProperty);
			set => SetValue(CurrentGestureStateProperty, value);
		}

		public static SideMenuPosition GetPosition(BindableObject bindable)
			=> (SideMenuPosition)bindable.GetValue(PositionProperty);

		public static void SetPosition(BindableObject bindable, SideMenuPosition value)
			=> bindable.SetValue(PositionProperty, value);

		public static double GetMenuWidthPercentage(BindableObject bindable)
			=> (double)bindable.GetValue(MenuWidthPercentageProperty);

		public static void SetMenuWidthPercentage(BindableObject bindable, double value)
			=> bindable.SetValue(MenuWidthPercentageProperty, value);

		public static bool GetMenuGestureEnabled(BindableObject bindable)
			=> (bool)bindable.GetValue(MenuGestureEnabledProperty);

		public static void SetMenuGestureEnabled(BindableObject bindable, bool value)
			=> bindable.SetValue(MenuGestureEnabledProperty, value);

		protected override void OnControlInitialized(AbsoluteLayout control)
		{
			children.CollectionChanged += OnChildrenCollectionChanged;

			overlayView = SetupMainViewLayout(new BoxView
			{
				InputTransparent = true,
				Color = Color.Transparent,
{'fraction_non_alphanumeric': 0.08119895329474268, 'fraction_numerical': 0.004837047022440726, 'mean_word_length': 5.9564258135686705, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 54, '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': '5395714', 'n_tokens_mistral': 4107, 'n_tokens_neox': 3457, 'n_words': 743}