using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
using C1.Xaml.Chart;

namespace FlappyChart
{
    public class Walls
    {
        const double WALL_THICKNESS = 40;
        ObservableCollection<Point> ptsBottom = new ObservableCollection<Point>();
        ObservableCollection<Point> ptsTop = new ObservableCollection<Point>();
        Random rnd = new Random();
        XYDataSeries dsBottom, dsTop;

        C1Chart chart;

        public Walls(C1Chart chart)
        {
            this.chart = chart;

            dsBottom = new XYDataSeries()
            {
                ItemsSource = ptsBottom,
                XValueBinding = new Binding() { Path = new PropertyPath("X") },
                ValueBinding = new Binding() { Path = new PropertyPath("Y") },
                ConnectionStrokeThickness = WALL_THICKNESS
            };
            
            dsTop = new XYDataSeries()
            {
                ItemsSource = ptsTop,
                XValueBinding = new Binding() { Path = new PropertyPath("X") },
                ValueBinding = new Binding() { Path = new PropertyPath("Y") },
                ConnectionStrokeThickness = WALL_THICKNESS
            };

            if (GameOptions.UseDirectX)
            {
                dsBottom.RenderMode = RenderMode.Direct2D;
                dsTop.RenderMode = RenderMode.Direct2D;
            }
            chart.Data.Children.Add(dsBottom);
            chart.Data.Children.Add(dsTop);
        }

        public void CreateNewLevel(int nsteps)
        {
            ptsBottom.Clear();
            ptsTop.Clear();

            for (int i = 1; i <= nsteps; i++)
            {
                var x = i;
                var y = -600 + rnd.NextDouble() * 1200;

                ptsBottom.Add(new Point(x, -2000));
                ptsBottom.Add(new Point(x, y - 400));
                ptsBottom.Add(new Point(x, -2000));

                ptsTop.Add(new Point(x, 2000));
                ptsTop.Add(new Point(x, y + 400));
                ptsTop.Add(new Point(x, 2000));
            }
        }

        public bool Overlap(Bird bird)
        {
            return Overlap(bird.DataPoint, bird.Diameter);
        }

        bool Overlap(Point pt, double diameter)
        {
            int i = 3 * (int)Math.Round(pt.X - 1) + 1;
            if (i >= 0 && i < ptsTop.Count)
            {
                pt = chart.View.PointFromData(pt);
                var pt1 = chart.View.PointFromData(ptsTop[i]);
                var pt2 = chart.View.PointFromData(ptsBottom[i]);

                var d = (WALL_THICKNESS + diameter) * 0.5;
                if (pt.X >= (pt1.X - d) && pt.X <= (pt1.X + d))
                {
                    if (pt.Y <= pt1.Y || pt.Y >= pt2.Y)
                        return true;
                    else
                    {
                        // rounded edges of wall
                        var dd = d*d;
                        var dx = (pt.X - pt1.X);
                        var dy = (pt.Y - pt1.Y);
                        var d1 = dx * dx + dy * dy;
                        if (d1 <= dd)
                            return true;
                        dx = (pt.X - pt2.X);
                        dy = (pt.Y - pt2.Y);
                        d1 = dx * dx + dy * dy;
                        if (d1 <= dd)
                            return true;
                    }
                }
            }

            return false;
        }
    }
}
