using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Threading;

//====================================================
// Описание работы классов и методов исходника на:
// https://www.interestprograms.ru
// Исходные коды программ и игр
//====================================================

namespace WpfHappyNewYear
{
	/// <summary>
	/// Interaction logic for MainWindow.xaml
	/// </summary>
	public partial class MainWindow : Window
	{
		/// <summary>
		/// Добавочное смещение окна программы при расположении выше экрана
		/// </summary>
		private readonly double _offsetWindow = 50;
		/// <summary>
		/// Временной период повторений по умолчанию.
		/// </summary>
		private int _repeatPeriod = 5*60;
		/// <summary>
		/// Количество повторений по умолчанию до закрытия программы.
		/// </summary>
		private int _mainCounter = 12;
		/// <summary>
		/// Время, в течение которого опускается окно поздравления.
		/// </summary>
		private double _durationDropdown = 2;
		/// <summary>
		/// Время исчезновения гланого окна после обратной анимации.
		/// </summary>
		private double _durationOpacity = 1;


		public MainWindow()
		{
			InitializeComponent();

			// Инициализация окон ввода значениями по умолчанию
			repeatNumber.Text = _mainCounter.ToString();
			tbRepeatPeriod.Text = _repeatPeriod.ToString();
		}



		#region Основные методы анимированного поздравления

		/// <summary>
		/// Запуск программы новогоднего поздравления.
		/// </summary>
		private void Start()
		{
			// Скрываем панель управления
			Admin.Visibility = Visibility.Collapsed;
			// Иконка окна на панели задач будет отсутствовать.
			ShowInTaskbar = false;
			// Поле гланого окна становится прозрачным
			Background = Brushes.Transparent;
			// Для полностью прозрачного окна не должно быть никаких стилей.
			WindowStyle = WindowStyle.None;
			// Главное окно будет поверх всех окон.
			Topmost = true;
			// Удаляем верхнюю планку изменения размеров окна.
			ResizeMode = ResizeMode.NoResize;

			
			Top = -(System.Windows.SystemParameters.PrimaryScreenHeight + _offsetWindow);
			Left = 0;

			// Габариты окна принимают размеры экрана.
			Width = System.Windows.SystemParameters.PrimaryScreenWidth;
			Height = System.Windows.SystemParameters.PrimaryScreenHeight;

			DelayAnimation();
		}


		/// <summary>
		/// Запуск анимации поздравления через определенное время.
		/// </summary>
		private void DelayAnimation()
		{
			DispatcherTimer timer = new() { Interval = TimeSpan.FromSeconds(_repeatPeriod) };
			timer.Tick += (sender, args) =>
			{
				timer.Stop();

				// Запуск рабочей анимации новогоднего поздравления.
				AnimationWindow();
			};

			timer.Start();
		}


		/// <summary>
		/// Последовательная анимация новогоднего поздравления
		/// </summary>
		private void AnimationWindow()
		{
			// Координаты начального положения окна
			double fromY = -(Height + _offsetWindow);
			double toY = 0;

			// Подготовка объекта анимации.
			AnimationObject animObject = new(mainGrid);

			// Настройки анимации спуска окна сверху экрана.
			DoubleAnimation yAnimation = new()
			{
				From = fromY,
				To = toY,
				Duration = new Duration(TimeSpan.FromSeconds(_durationDropdown)),
				FillBehavior = FillBehavior.Stop,
			};


			yAnimation.Completed += (sender, eArgs) =>
			{

				animObject.CompletedEvent += () =>
				{
					DoubleAnimation opacity = new()
					{
						From = 1,
						To = 0,
						Duration = new Duration(TimeSpan.FromSeconds(_durationOpacity)),
						FillBehavior = FillBehavior.Stop,
					};

					// Локальное определение обработчика события завершения анимации прозрачности.
					opacity.Completed += (sender, eArgs) =>
					{
						// Возврат окна к исходной позиции
						Top = -(Height + _offsetWindow);

						// Уменьшаем счетчик повторений анимированного поздравления.
						_mainCounter--;


						if (_mainCounter <= 0)
						{
							// Закрытие программы новогоднего поздравления.
							Close();


							return;
						}

						// Запуск повтора анимации поздравления через определенное время.
						DelayAnimation();
					};


					BeginAnimation(OpacityProperty, opacity);
				};

				
				animObject.Animation();

			};

			
			BeginAnimation(TopProperty, yAnimation);
		}


		#endregion


		#region Управление запуском отложенного поздравления

		/// <summary>
		/// Кнопка старт запускает отложенную анимацию
		/// новогоднего поздравления.
		/// </summary>
		private void Button_Click(object sender, RoutedEventArgs e)
		{
			Start();
		}

		#endregion


		#region Коррекция ввода чисел в элементы TextBox

		private void textbox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
		{
			TextBox activeTextBox = (TextBox)sender;
			string onlyNumber = activeTextBox.Text;

			if (activeTextBox.Text == "") return;


			if (Char.IsDigit(onlyNumber[onlyNumber.Length - 1]) == false)
			{
				activeTextBox.Text = onlyNumber.Substring(0, onlyNumber.Length - 1);
				activeTextBox.CaretIndex = onlyNumber.Length - 1;
			}
			else
			{
				if (activeTextBox == repeatNumber) _mainCounter = int.Parse(activeTextBox.Text);
				if (activeTextBox == tbRepeatPeriod) _repeatPeriod = int.Parse(activeTextBox.Text);
			}
		}


		private void textbox_LostFocus(object sender, RoutedEventArgs e)
		{
			TextBox activeTextBox = (TextBox)sender;

			if (activeTextBox == repeatNumber) activeTextBox.Text = _mainCounter.ToString();
			if (activeTextBox == tbRepeatPeriod) activeTextBox.Text = _repeatPeriod.ToString();
		}


		#endregion


		#region Функциональность перемещения окна

		private bool _canMove = false;
		private Point _offsetPoint = new(0, 0);
		private void Window_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
			{
				Close();
				return; // Обязательно надо
			}

			Point p = e.MouseDevice.GetPosition(this);
			_canMove = true;

			_offsetPoint.X = PointToScreen(p).X - this.Left;
			_offsetPoint.Y = PointToScreen(p).Y - this.Top;

			// --- / ---

			e.MouseDevice.Capture(this);
		}

		private void Window_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
		{
			if (_canMove == true)
			{
				Point p = e.MouseDevice.GetPosition(this);

				Left = PointToScreen(p).X - _offsetPoint.X;
				Top = PointToScreen(p).Y - _offsetPoint.Y;
			}
		}

		private void Window_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			_canMove = false;
			e.MouseDevice.Capture(null);
		}

		#endregion


		#region Исходные коды на interestprograms.ru

		private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
		{
			Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true });
			e.Handled = true;
		}

		#endregion

	}
}