<commit_before>﻿using System;
using System.ComponentModel;
using Android.App;
using Android.Content;
using Android.Graphics.Drawables;
using Android.Views;
using Android.Widget;
using Xamarin.CommunityToolkit.UI.Views;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using static Android.App.ActionBar;
using AColorRes = Android.Resource.Color;
using AView = Android.Views.View;
using FormsPlatform = Xamarin.Forms.Platform.Android.Platform;
using GravityFlags = Android.Views.GravityFlags;

[assembly: ExportRenderer(typeof(BasePopup), typeof(PopupRenderer))]

namespace Xamarin.CommunityToolkit.UI.Views
{
	public class PopupRenderer : Dialog, IVisualElementRenderer, IDialogInterfaceOnCancelListener
	{
		int? defaultLabelFor;
		VisualElementTracker? tracker;
		ContainerView? container;
		bool isDisposed;

		public BasePopup? Element { get; private set; }

		void IVisualElementRenderer.UpdateLayout() => tracker?.UpdateLayout();

		VisualElement? IVisualElementRenderer.Element => Element;

		AView? IVisualElementRenderer.View => container;

		ViewGroup? IVisualElementRenderer.ViewGroup => null;

		VisualElementTracker? IVisualElementRenderer.Tracker => tracker;

		public event EventHandler<VisualElementChangedEventArgs>? ElementChanged;

		public event EventHandler<PropertyChangedEventArgs>? ElementPropertyChanged;

		public PopupRenderer(Context context)
			: base(context)
		{
		}

		void IVisualElementRenderer.SetElement(VisualElement element)
		{
			if (element == null)
				throw new ArgumentNullException(nameof(element));

			if (element is not BasePopup popup)
				throw new ArgumentNullException("Element is not of type " + typeof(BasePopup), nameof(element));

			var oldElement = Element;
			Element = popup;
			CreateControl(Element);

			if (oldElement != null)
				oldElement.PropertyChanged -= OnElementPropertyChanged;

			element.PropertyChanged += OnElementPropertyChanged;

			if (tracker == null)
				tracker = new VisualElementTracker(this);

			OnElementChanged(new ElementChangedEventArgs<BasePopup?>(oldElement, Element));
		}

		protected virtual void OnElementChanged(ElementChangedEventArgs<BasePopup?> e)
		{
			if (e.NewElement != null && !isDisposed && Element is BasePopup basePopup)
			{
				SetEvents(basePopup);
				SetColor(basePopup);
				SetSize(basePopup);
				SetAnchor(basePopup);
				SetLightDismiss(basePopup);

				Show();
			}

			ElementChanged?.Invoke(this, new VisualElementChangedEventArgs(e.OldElement, e.NewElement));
		}

		public override void Show()
		{
			base.Show();
			Element?.OnOpened();
		}

		protected virtual void OnElementPropertyChanged(object? sender, PropertyChangedEventArgs args)
		{
			if (Element is BasePopup basePopup)
			{
				if (args.PropertyName == BasePopup.VerticalOptionsProperty.PropertyName
					|| args.PropertyName == BasePopup.HorizontalOptionsProperty.PropertyName
					|| args.PropertyName == BasePopup.SizeProperty.PropertyName)
				{
					SetSize(basePopup);
					SetAnchor(basePopup);
				}
				else if (args.PropertyName == BasePopup.ColorProperty.PropertyName)
				{
					SetColor(basePopup);
				}
			}

			ElementPropertyChanged?.Invoke(this, args);
		}

		void CreateControl(in BasePopup basePopup)
		{
			if (container == null)
			{
				container = new ContainerView(Context, basePopup.Content);
				SetContentView(container);
			}
		}

		void SetEvents(in BasePopup basePopup)
		{
			SetOnCancelListener(this);
			basePopup.Dismissed += OnDismissed;
		}

		void SetColor(in BasePopup basePopup) => Window?.SetBackgroundDrawable(new ColorDrawable(basePopup.Color.ToAndroid(AColorRes.BackgroundLight, Context)));

		void SetSize(in BasePopup basePopup)
		{
			if (basePopup.Content != null && basePopup.Size != default)
			{
				var decorView = (ViewGroup)(Window?.DecorView ?? throw new NullReferenceException());
				var child = (FrameLayout)(decorView?.GetChildAt(0) ?? throw new NullReferenceException());<commit_msg>Fixes app crash [Android] on SetSize API; Removed cast from child object (#1367)<commit_after>﻿using System;
using System.ComponentModel;
using Android.App;
using Android.Content;
using Android.Graphics.Drawables;
using Android.Views;
using Android.Widget;
using Xamarin.CommunityToolkit.UI.Views;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using static Android.App.ActionBar;
using AColorRes = Android.Resource.Color;
using AView = Android.Views.View;
using FormsPlatform = Xamarin.Forms.Platform.Android.Platform;
using GravityFlags = Android.Views.GravityFlags;

[assembly: ExportRenderer(typeof(BasePopup), typeof(PopupRenderer))]

namespace Xamarin.CommunityToolkit.UI.Views
{
	public class PopupRenderer : Dialog, IVisualElementRenderer, IDialogInterfaceOnCancelListener
	{
		int? defaultLabelFor;
		VisualElementTracker? tracker;
		ContainerView? container;
		bool isDisposed;

		public BasePopup? Element { get; private set; }

		void IVisualElementRenderer.UpdateLayout() => tracker?.UpdateLayout();

		VisualElement? IVisualElementRenderer.Element => Element;

		AView? IVisualElementRenderer.View => container;

		ViewGroup? IVisualElementRenderer.ViewGroup => null;

		VisualElementTracker? IVisualElementRenderer.Tracker => tracker;

		public event EventHandler<VisualElementChangedEventArgs>? ElementChanged;

		public event EventHandler<PropertyChangedEventArgs>? ElementPropertyChanged;

		public PopupRenderer(Context context)
			: base(context)
		{
		}

		void IVisualElementRenderer.SetElement(VisualElement element)
		{
			if (element == null)
				throw new ArgumentNullException(nameof(element));

			if (element is not BasePopup popup)
				throw new ArgumentNullException("Element is not of type " + typeof(BasePopup), nameof(element));

			var oldElement = Element;
			Element = popup;
			CreateControl(Element);

			if (oldElement != null)
				oldElement.PropertyChanged -= OnElementPropertyChanged;

			element.PropertyChanged += OnElementPropertyChanged;

			if (tracker == null)
				tracker = new VisualElementTracker(this);

			OnElementChanged(new ElementChangedEventArgs<BasePopup?>(oldElement, Element));
		}

		protected virtual void OnElementChanged(ElementChangedEventArgs<BasePopup?> e)
		{
			if (e.NewElement != null && !isDisposed && Element is BasePopup basePopup)
			{
				SetEvents(basePopup);
				SetColor(basePopup);
				SetSize(basePopup);
				SetAnchor(basePopup);
				SetLightDismiss(basePopup);

				Show();
			}

			ElementChanged?.Invoke(this, new VisualElementChangedEventArgs(e.OldElement, e.NewElement));
		}

		public override void Show()
		{
			base.Show();
			Element?.OnOpened();
		}

		protected virtual void OnElementPropertyChanged(object? sender, PropertyChangedEventArgs args)
		{
			if (Element is BasePopup basePopup)
			{
				if (args.PropertyName == BasePopup.VerticalOptionsProperty.PropertyName
					|| args.PropertyName == BasePopup.HorizontalOptionsProperty.PropertyName
					|| args.PropertyName == BasePopup.SizeProperty.PropertyName)
				{
					SetSize(basePopup);
					SetAnchor(basePopup);
				}
				else if (args.PropertyName == BasePopup.ColorProperty.PropertyName)
				{
					SetColor(basePopup);
				}
			}

			ElementPropertyChanged?.Invoke(this, args);
		}

		void CreateControl(in BasePopup basePopup)
		{
			if (container == null)
			{
				container = new ContainerView(Context, basePopup.Content);
				SetContentView(container);
			}
		}

		void SetEvents(in BasePopup basePopup)
		{
			SetOnCancelListener(this);
			basePopup.Dismissed += OnDismissed;
		}

		void SetColor(in BasePopup basePopup) => Window?.SetBackgroundDrawable(new ColorDrawable(basePopup.Color.ToAndroid(AColorRes.BackgroundLight, Context)));

		void SetSize(in BasePopup basePopup)
		{
			if (basePopup.Content != null && basePopup.Size != default)
			{
				var decorView = (ViewGroup)(Window?.DecorView ?? throw new NullReferenceException());
				var child = decorView?.GetChildAt(0) ?? throw new NullReferenceException();
{'fraction_non_alphanumeric': 0.09904233870967742, 'fraction_numerical': 0.0007560483870967742, 'mean_word_length': 4.92755787901419, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 23, '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': '4944933', 'n_tokens_mistral': 2591, 'n_tokens_neox': 2282, 'n_words': 485}