using System;
using Windows.ApplicationModel;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;

namespace ClockRack
{
    public sealed partial class MainPage : Page
    {
        TimeZoneManager timeZoneManager = new TimeZoneManager();
        IPropertySet appSettings = ApplicationData.Current.LocalSettings.Values;

        public MainPage()
        {
            this.InitializeComponent();

            // Ładowanie ustawień aplikacji dla zegarów
            int index = 0;

            while (appSettings.ContainsKey(index.ToString() + "Location"))
            {
                string preface = index.ToString();

                TimeZoneClock clock = new TimeZoneClock
                {
                    DataContext = new TimeZoneClockViewModel
                    {
                        Location = appSettings[preface + "Location"] as string,
                        TimeZoneKey = appSettings[preface + "TimeZoneKey"] as string,
                        ForegroundName = appSettings[preface + "Foreground"] as string,
                        BackgroundName = appSettings[preface + "Background"] as string 
                    },
                };
                uniformGrid.Children.Add(clock);
                index += 1;
            }

            // Jeżeli nie ma ustawień, utwórz domyślny zegar
            if (uniformGrid.Children.Count == 0)
            {
                TimeZoneClock clock = new TimeZoneClock
                {
                    DataContext = new TimeZoneClockViewModel()
                };
                uniformGrid.Children.Add(clock);
            }

            // Ustawienie metody obsługo zdarzenia Suspending
            Application.Current.Suspending += OnApplicationSuspending;

            // Uruchomienie zdarzenia Rendering
            CompositionTarget.Rendering += OnCompositionTargetRendering;
        }

        void OnApplicationSuspending(object sender, SuspendingEventArgs args)
        {
            appSettings.Clear();

            for (int index = 0; index < uniformGrid.Children.Count; index++)
            {
                TimeZoneClock timeZoneClock = uniformGrid.Children[index] as TimeZoneClock;
                TimeZoneClockViewModel viewModel =
                        timeZoneClock.DataContext as TimeZoneClockViewModel;
                string preface = index.ToString();

                appSettings[preface + "Location"] = viewModel.Location;
                appSettings[preface + "TimeZoneKey"] = viewModel.TimeZoneKey;
                appSettings[preface + "Foreground"] = viewModel.ForegroundName;
                appSettings[preface + "Background"] = viewModel.BackgroundName;
            }
        }

        void OnCompositionTargetRendering(object sender, object args)
        {
            // Jendokrotne pobranie czasu
            DateTime utc = DateTime.UtcNow;

            foreach (UIElement child in uniformGrid.Children)
            {
                TimeZoneClockViewModel viewModel = 
                        (child as FrameworkElement).DataContext as TimeZoneClockViewModel;
                string timeZoneKey = viewModel.TimeZoneKey;

                // Ustawienie czasu lokalnego z TimeZoneManager
                viewModel.DateTime = timeZoneManager.GetLocalTime(timeZoneKey, utc);
            }
        }

        async protected override void OnRightTapped(RightTappedRoutedEventArgs args)
        {
            // Wyszukanie właściwego obiektu TimeZoneClock
            FrameworkElement element = args.OriginalSource as FrameworkElement;

            while (element != null)
            {
                if (element is TimeZoneClock)
                    break;

                element = element.Parent as FrameworkElement;
            }

            if (element == null)
                return;

            // Tworzenie PopupMenu 
            PopupMenu popupMenu = new PopupMenu();
            popupMenu.Commands.Add(new UICommand("Dodaj", OnAddMenuItem, element));
            popupMenu.Commands.Add(new UICommand("Edytuj...", OnEditMenuItem, element));

            if (uniformGrid.Children.Count > 1)
                popupMenu.Commands.Add(new UICommand("Usuń", OnDeleteMenuItem, element));

            args.Handled = true;
            base.OnRightTapped(args);

            // Wyświetlenie menu
            await popupMenu.ShowAsync(args.GetPosition(this));
        }

        void OnAddMenuItem(IUICommand command)
        {
            // Utworzenie TimeZoneClock
            TimeZoneClock timeZoneClock = new TimeZoneClock
            {
                DataContext = new TimeZoneClockViewModel()
            };

            // Wstawienie za klikniętym zegarem
            TimeZoneClock clickedClock = command.Id as TimeZoneClock;
            int index = uniformGrid.Children.IndexOf(clickedClock);
            uniformGrid.Children.Insert(index + 1, timeZoneClock);
        }

        void OnEditMenuItem(IUICommand command)
        {
            TimeZoneClock timeZoneClock = command.Id as TimeZoneClock;
            SettingsDialog settingsDialog = new SettingsDialog(timeZoneManager);
            settingsDialog.DataContext = timeZoneClock.DataContext;

            // Tworzenie okna Popup z SettingsDialog
            Popup popup = new Popup
            {
                Child = settingsDialog,
                IsLightDismissEnabled = true
            };

            settingsDialog.SizeChanged += (sender, args) =>
                {
                    // Odczyt środka zegara
                    Point position = new Point(timeZoneClock.ActualWidth / 2,
                                                timeZoneClock.ActualHeight / 2);

                    // Konwersja na współrzędne Page
                    position = timeZoneClock.TransformToVisual(this).TransformPoint(position);

                    // Ustawienie okna tak, aby lewy dolny i prawy dolny narożnik
                    //      były wyrównane do środka edytowanego zegara
                    if (position.X > this.ActualWidth / 2)
                        position.X -= settingsDialog.ActualWidth;

                    position.Y -= settingsDialog.ActualHeight;

                    // Korekcja rozmiaru strony
                    if (position.X + settingsDialog.ActualWidth > this.ActualWidth)
                        position.X = this.ActualWidth - settingsDialog.ActualWidth;

                    if (position.X < 0)
                        position.X = 0;

                    if (position.Y < 0)
                        position.Y = 0;

                    // Ustawienie położenia okna Popup
                    popup.HorizontalOffset = position.X;
                    popup.VerticalOffset = position.Y;
                };

            popup.IsOpen = true;
        }

        async void OnDeleteMenuItem(IUICommand command)
        {
            TimeZoneClock timeZoneClock = command.Id as TimeZoneClock;
            TimeZoneClockViewModel viewModel = timeZoneClock.DataContext as TimeZoneClockViewModel;

            MessageDialog msgdlg = new MessageDialog("Usunąć zegar ze zbioru?", 
                                                        viewModel.Location);
            msgdlg.Commands.Add(new UICommand("OK"));
            msgdlg.Commands.Add(new UICommand("Anuluj"));
            msgdlg.DefaultCommandIndex = 0;
            msgdlg.CancelCommandIndex = 1;

            IUICommand msgDlgCommand = await msgdlg.ShowAsync();

            if (msgDlgCommand.Label == "OK")
                uniformGrid.Children.Remove(command.Id as TimeZoneClock);
        }
    }
}
