using System;
using System.Collections.Generic;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Documents;
using Windows.UI.Xaml.Media;

namespace SilasMarner
{
    public sealed partial class MainPage : Page
    {
        double fractionRead;

        public MainPage()
        {
            this.InitializeComponent();

            // Zapisz i ponownie załaduje wartość ułamka
            IPropertySet propertySet = ApplicationData.Current.LocalSettings.Values;

            Application.Current.Suspending += (sender, args) =>
                {
                    propertySet["FractionRead"] = fractionRead;
                };

            if (propertySet.ContainsKey("FractionRead"))
                fractionRead = (double)propertySet["FractionRead"];
        }

        async void OnFlipViewSizeChanged(object sender, SizeChangedEventArgs args)
        {
            // Pobranie rozmiaru FlipView
            Size containerSize = args.NewSize;

            // Aktualna wartość jest modyfikowana w naszym procesie, więc zapisujemy ją
            double saveFractionRead = fractionRead;

            // Przy pierwszym uruchomieniu programu
            if (flipView.Items.Count == 0)
            {
                // Załadowanie zasobu książki
                IList<string> bookLines = 
                    await PathIO.ReadLinesAsync("ms-appx:///Books/pg550.txt",
                                                UnicodeEncoding.Utf8);

                // Tworzenie RichTextBlock
                RichTextBlock richTextBlock = new RichTextBlock
                {
                    FontSize = 22,
                    Foreground = new SolidColorBrush(Colors.Black)
                };

                // Tworzenie akapitów
                Paragraph paragraph = new Paragraph();
                paragraph.Margin = new Thickness(12);
                richTextBlock.Blocks.Add(paragraph);

                foreach (string line in bookLines)
                {
                    // Koniec akapitu, tworzenie nowego obiektu Paragraph
                    if (line.Length == 0)
                    {
                        paragraph = new Paragraph();
                        paragraph.Margin = new Thickness(12);
                        richTextBlock.Blocks.Add(paragraph);
                    }
                    // Kontynuacja akapitu
                    else
                    {
                        string textLine = line;
                        char lastChar = line[line.Length - 1];

                        if (lastChar != ' ')
                            textLine += ' ';

                        if (line[0] == ' ')
                            paragraph.Inlines.Add(new LineBreak());

                        paragraph.Inlines.Add(new Run { Text = textLine });
                    }
                }

                // Ustawienie takiej samej wielkosći RichTextBlock jak FlipView
                flipView.Items.Add(richTextBlock);
                richTextBlock.Measure(containerSize);

                // Generowanie elementów RichTextBlockOverflow
                if (richTextBlock.HasOverflowContent)
                {
                    // Dodanie pierwszego
                    RichTextBlockOverflow richTextBlockOverflow = new RichTextBlockOverflow();
                    richTextBlock.OverflowContentTarget = richTextBlockOverflow;
                    flipView.Items.Add(richTextBlockOverflow);
                    richTextBlockOverflow.Measure(containerSize);

                    // Dodanie kolejnych
                    while (richTextBlockOverflow.HasOverflowContent)
                    {
                        RichTextBlockOverflow newRichTextBlockOverflow = new RichTextBlockOverflow();
                        richTextBlockOverflow.OverflowContentTarget = newRichTextBlockOverflow;
                        richTextBlockOverflow = newRichTextBlockOverflow;
                        flipView.Items.Add(richTextBlockOverflow);
                        richTextBlockOverflow.Measure(containerSize);
                    }
                }
            }
            // Kolejne zdarzenia SizeChanged
            else
            {
                // Zmiana wielkości wszystkich elementów w FlipView
                foreach (object obj in flipView.Items)
                {
                    (obj as FrameworkElement).Measure(containerSize);
                }

                // Generowanie nowych elementów RichTextBlockOverflow w razie potrzeby
                while ((flipView.Items[flipView.Items.Count - 1] 
                                    as RichTextBlockOverflow).HasOverflowContent)
                {
                    RichTextBlockOverflow richTextBlockOverflow = 
                            flipView.Items[flipView.Items.Count - 1] as RichTextBlockOverflow;
                    RichTextBlockOverflow newRichTextBlockOverflow = new RichTextBlockOverflow();
                    richTextBlockOverflow.OverflowContentTarget = newRichTextBlockOverflow;
                    richTextBlockOverflow = newRichTextBlockOverflow;
                    flipView.Items.Add(richTextBlockOverflow);
                    richTextBlockOverflow.Measure(args.NewSize);
                }
                // Usunięcie nadmiarowych elementów RichTextBlockOverflow
                while (!(flipView.Items[flipView.Items.Count - 2] 
                                    as RichTextBlockOverflow).HasOverflowContent)
                {
                    flipView.Items.RemoveAt(flipView.Items.Count - 1);
                }
            }
            
            // Inicjalizacja nagłówka i elementu Slider
            int count = flipView.Items.Count;
            pageNumber.Text = "1";              // prawdopodobnie zostanie wkrótce zmodyfikowana
            pageCount.Text = count.ToString();
            pageSlider.Minimum = 1;
            pageSlider.Maximum = flipView.Items.Count;
            pageSlider.Value = 1;               // prawdopodobnie zostanie wkrótce zmodyfikowana

            // Przejście do wyliczonej strony
            fractionRead = saveFractionRead;
            flipView.SelectedIndex = (int)Math.Min(count - 1, fractionRead * count);
        }

        void OnFlipViewSelectionChanged(object sender, SelectionChangedEventArgs args)
        {
            int pageNum = flipView.SelectedIndex + 1;
            pageNumber.Text = pageNum.ToString();
            fractionRead = (pageNum - 1.0) / flipView.Items.Count;
            pageSlider.Value = pageNum;
        }

        void OnPageSliderValueChanged(object sender, RangeBaseValueChangedEventArgs args)
        {
            flipView.SelectedIndex = Math.Min(flipView.Items.Count, (int)args.NewValue) - 1;
        }
    }
}
