using System.Collections.Generic;
using System.Linq;
using Windows.Devices.Input;
using Windows.UI.Input;
using Windows.UI.Input.Inking;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;

namespace SimpleInking
{
    public sealed partial class MainPage : Page
    {
        InkManager inkManager = new InkManager();
        bool hasPen;

        public MainPage()
        {
            this.InitializeComponent();

            // Sprawdzenie, czy wśród urządzeń wejściowych jest pióro
            foreach (PointerDevice device in PointerDevice.GetPointerDevices())
                hasPen |= device.PointerDeviceType == PointerDeviceType.Pen;
        }

        protected override void OnPointerPressed(PointerRoutedEventArgs args)
        {
            if (args.Pointer.PointerDeviceType == PointerDeviceType.Pen || !hasPen)
            {
                PointerPoint pointerPoint = args.GetCurrentPoint(this);
                inkManager.ProcessPointerDown(pointerPoint);
            }
            base.OnPointerPressed(args);
        }

        protected override void OnPointerMoved(PointerRoutedEventArgs args)
        {
            if ((args.Pointer.PointerDeviceType == PointerDeviceType.Pen || !hasPen) &&
                args.Pointer.IsInContact)
            {
                IEnumerable<PointerPoint> points = args.GetIntermediatePoints(this).Reverse();

                foreach (PointerPoint point in points)
                    inkManager.ProcessPointerUpdate(point);
            }
            base.OnPointerMoved(args);
        }

        protected override void OnPointerReleased(PointerRoutedEventArgs args)
        {
            if (args.Pointer.PointerDeviceType != PointerDeviceType.Pen && hasPen)
                return;

            inkManager.ProcessPointerUp(args.GetCurrentPoint(this));

            // Rysowanie ostatniego obiektu InkStroke
            IReadOnlyList<InkStroke> inkStrokes = inkManager.GetStrokes();
            InkStroke inkStroke = inkStrokes[inkStrokes.Count - 1];

            // Tworzenie SolidColorBrush używanego we wszystkich segmentach pociągnięcia piórem
            Brush brush = new SolidColorBrush(inkStroke.DrawingAttributes.Color);

            // Pobranie segmentów
            IReadOnlyList<InkStrokeRenderingSegment> inkSegments = inkStroke.GetRenderingSegments();

            // Zwróć uwagę, że pętla zaczyna się od 1
            for (int i = 1; i < inkSegments.Count; i++)
            {
                InkStrokeRenderingSegment inkSegment = inkSegments[i];

                // Tworzenie BezierSegment od tego punktu
                BezierSegment bezierSegment = new BezierSegment
                {
                    Point1 = inkSegment.BezierControlPoint1,
                    Point2 = inkSegment.BezierControlPoint2,
                    Point3 = inkSegment.Position
                };

                // Tworzenie PathFigure zaczynającej się na poprzedniej pozycji
                PathFigure pathFigure = new PathFigure
                {
                    StartPoint = inkSegments[i - 1].Position,
                    IsClosed = false,
                    IsFilled = false
                };
                pathFigure.Segments.Add(bezierSegment);

                // Tworzenie PathGeometry z tym obiektem PathFigure
                PathGeometry pathGeometry = new PathGeometry();
                pathGeometry.Figures.Add(pathFigure);

                // Tworzenie Path z tym PathGeometry
                Path path = new Path
                {
                    Stroke = brush,
                    StrokeThickness = inkStroke.DrawingAttributes.Size.Width *
                                        inkSegment.Pressure,
                    StrokeStartLineCap = PenLineCap.Round,
                    StrokeEndLineCap = PenLineCap.Round,
                    Data = pathGeometry
                };

                // Dodanie do Grid
                contentGrid.Children.Add(path);
            }
            base.OnPointerReleased(args);
        }
    }
}
