public void PolygonAsCircleUnitCircleTest()
        {
            Polygon       circle         = Polygon.AsCircle(1, new Vector(0, 0), 4);
            List <Vector> expectedPoints = new List <Vector>(new Vector[] { new Vector(1, 0), new Vector(0, 1), new Vector(-1, 0), new Vector(0, -1) });

            CollectionAssert.AreEqual(expectedPoints, circle.Points);
        }
        public void PolygonAsCircleAreaTest()
        {
            Polygon circle       = Polygon.AsCircle(4, new Vector(5, 5), 360);
            double  area         = ClipperUtility.GetArea(circle);
            double  expectedArea = Math.PI * 4 * 4; // PI * r * r

            Assert.AreEqual(expectedArea, area, .01);
        }
        public static void Run()
        {
            Logger.SetLevel(Logger.Level.Debug);

            string[] allInfoLines = File.ReadAllLines(Config.CsvStudyInfoFilePath);

            var infoSelections = (from line in allInfoLines.Skip(1)
                                  let data = line.Split(';')
                                             select new
            {
                PartId = data[0],
                StartOffset = Helper.ConvertToLong(data[2]),
                StudyType = data[1]
            }).Distinct();

            string[] allLines = File.ReadAllLines(Config.CsvFilePath);

            // select
            var selections = (from line in allLines.Skip(1)
                              let data = line.Split(';')
                                         select new
            {
                PartId = data[1],
                Game = data[5],
                StudyType = data[2]
            }).Distinct();

            // for each selection
            if (selections.Count() != 32)
            {
                Logger.Warn("Expecting 32 different conditions for participants");
            }


            foreach (var selection in selections)
            {
                var query = from line in allLines.Skip(1)
                            let data = line.Split(';')
                                       where data[5] == selection.Game && data[1] == selection.PartId && data[2] == selection.StudyType
                                       &&
                                       infoSelections
                                       .First(infoSelection => infoSelection.PartId == selection.PartId &&
                                              infoSelection.StudyType == selection.StudyType).StartOffset < Helper.ConvertToLong(data[9])
                                       select new
                {
                    PartId    = Helper.ConvertToInteger(data[1]),
                    Timestamp = Helper.ConvertToLong(data[9]),
                    Game      = data[5],
                    StudyType = data[2],
                    Rotation  = Helper.ConvertToDouble(data[8]),
                    PositionX = Helper.ConvertToDouble(data[11]),
                    PositionY = Helper.ConvertToDouble(data[12])
                };

                //var minOffsetTime =
                //    infoSelections.First(select => select.PartId == selection.PartId && select.StudyType == selection.StudyType).StartOffset;

                // BASIC STEPS FOR FIRST 100 ENTRIES
                //i = 0;
                //foreach (var row in query)
                //{
                //    Logger.Debug($"Part = {row.PartId}, Study type = {row.StudyType}, Game = {row.Game}, Rotation = {row.Rotation}, Position = {row.PositionX}, {row.PositionY}");
                //    i++;
                //    if (i > 100) break;
                //}

                // USED AREA
                var radius         = .3f;
                var circleSubsteps = 32;
                var usedPlayArea   = new PolygonList();
                foreach (var row in query)
                {
                    //if (row.Timestamp < minOffsetTime) continue;

                    var position = new Vector(row.PositionX, row.PositionY);
                    position.RotateCounter(-row.Rotation / 180 * Math.PI);
                    var positionPolygon = Polygon.AsCircle(radius, position, circleSubsteps);
                    usedPlayArea = ClipperUtility.Union(usedPlayArea, positionPolygon);
                }

                var usedArea = ClipperUtility.GetArea(usedPlayArea);
                Logger.Debug($"{selection.PartId};{selection.Game};{selection.StudyType};{usedArea}");

                // DURATION, MIN/MAX TIME
                //var min = double.MaxValue;
                //var max = double.MinValue;
                //foreach (var row in query)
                //{
                //    if (row.Timestamp < minOffsetTime) continue;

                //    if (row.Timestamp < min) min = row.Timestamp;
                //    if (max < row.Timestamp) max = row.Timestamp;
                //}

                //Logger.Debug($"{selection.PartId};{selection.StudyType};{min};{max};0;{max-min}");
            }



            //i = 0;
            //foreach (var row in query)
            //{
            //    Logger.Debug($"Part = {row.PartId}, Study type = {row.StudyType}, Game = {row.Game}, Rotation = {row.Rotation}, Position = {row.PositionX}, {row.PositionY}");
            //    i++;
            //    if (i > 100) break;
            //}



            Console.ReadKey();
        }
        public static void Run()
        {
            Logger.SetLevel(Logger.Level.Debug);

            string gameName = "Space";

            string[] dataLines = File.ReadAllLines(@"C:\Users\Max\Desktop\Study\single\max2\2017-09-17 18-10-17 - VS User Study - space-single.csv");

            var outfilePath = Config.CsvStudyInfoFileFolder + Config.PathSeperator + $"{gameName}Single.csv";

            File.Delete(outfilePath);
            File.AppendAllText(outfilePath, "PX;PY\n");

            var selections = from line in dataLines.Skip(1)
                             let data = line.Split(';')
                                        select new
            {
                Timestamp = data[0],
                PosX      = Helper.ConvertToDouble(data[2]),
                PosY      = Helper.ConvertToDouble(data[3])
            };

            Logger.Debug("Starting point generation");

            StringBuilder sb = new StringBuilder();

            foreach (var selection in selections)
            {
                var radius          = .3f;
                var circleSubsteps  = 16;
                var numCircles      = 5;
                var subradiusLength = .3f / 5;



                var position = new Vector(selection.PosX, selection.PosY);

                for (int circleNum = 0; circleNum < numCircles; circleNum++)
                {
                    var positionPolygon = Polygon.AsCircle(subradiusLength * circleNum, position, circleSubsteps);
                    foreach (var point in positionPolygon.Points)
                    {
                        sb.AppendLine($"{point.X};{point.Z}".Replace(",", "."));
                    }
                }
            }

            File.AppendAllText(outfilePath, sb.ToString());

            Logger.Debug("Done");


            //i = 0;
            //foreach (var row in query)
            //{
            //    Logger.Debug($"Part = {row.PartId}, Study type = {row.StudyType}, Game = {row.Game}, Rotation = {row.Rotation}, Position = {row.PositionX}, {row.PositionY}");
            //    i++;
            //    if (i > 100) break;
            //}



            Console.ReadKey();
        }
        public static void Run()
        {
            Logger.SetLevel(Logger.Level.Debug);

            string[] allInfoLines = File.ReadAllLines(Config.CsvStudyInfoFilePath);

            var infoSelections = (from line in allInfoLines.Skip(1)
                                  let data = line.Split(';')
                                             select new
            {
                PartId = data[0],
                StartOffset = Helper.ConvertToLong(data[2]),
                StudyType = data[1]
            }).Distinct();

            string[] allLines = File.ReadAllLines(Config.CsvFilePath);

            string gameId = "B";

            // select
            var selections = (from line in allLines.Skip(1)
                              let data = line.Split(';')
                                         let game = data[5]
                                                    where
                                                    game.Equals(gameId)
                                                    select new
            {
                Game = game,
                StudyType = data[2]
            }).Distinct();

            // for each selection
            if (selections.Count() != 8)
            {
                Logger.Warn("Expecting 32 different conditions for participants");
            }

            var outfilePath = Config.CsvStudyInfoFileFolder + Config.PathSeperator + $"testOffsetted{gameId}.csv";

            File.Delete(outfilePath);
            File.AppendAllText(outfilePath, "StudyId;Game;StudyType;PX;PY;genPX;genPY\n");
            foreach (var selection in selections)
            {
                // should probably use time interpolation
                //var query = (from line in allLines.Skip(1)
                //    let data = line.Split(';')
                //    let timestamp = Helper.ConvertToLong(data[9])
                //    let timestampMinOffset = infoSelections
                //        .First(infoSelection => infoSelection.StudyType == selection.StudyType).StartOffset
                //    where
                //    data[5] == selection.Game && data[2] == selection.StudyType && timestampMinOffset < timestamp
                //    select new
                //    {
                //        PartId = Helper.ConvertToInteger(data[1]),
                //        //Timestamp = timestamp,
                //        Game = data[5],
                //        StudyType = data[2],
                //        Rotation = Helper.ConvertToDouble(data[8]),
                //        //PositionX = Helper.ConvertToDouble(data[11]),
                //        //PositionY = Helper.ConvertToDouble(data[12])
                //    }).Distinct();

                //foreach (var rotationInfo in query)
                //{
                //    Logger.Debug($"{rotationInfo}");
                //}

                // BUILD POINT HEATMAPS
                var query = from line in allLines.Skip(1)
                            let data = line.Split(';')
                                       let timestamp = Helper.ConvertToLong(data[9])
                                                       let timestampMinOffset = infoSelections
                                                                                .First(infoSelection => infoSelection.StudyType == selection.StudyType).StartOffset
                                                                                where
                                                                                data[5] == selection.Game && data[2] == selection.StudyType && timestampMinOffset < timestamp
                                                                                select new
                {
                    PartId    = Helper.ConvertToInteger(data[1]),
                    Timestamp = timestamp,
                    Game      = data[5],
                    StudyType = data[2],
                    StudyId   = Helper.ConvertToInteger(data[0]),
                    Rotation  = Helper.ConvertToDouble(data[8]),
                    PositionX = Helper.ConvertToDouble(data[11]),
                    PositionY = Helper.ConvertToDouble(data[12])
                };
                var radius          = .3f;
                var circleSubsteps  = 16;
                var numCircles      = 5;
                var subradiusLength = .3f / 5;

                StringBuilder sb = new StringBuilder();
                foreach (var row in query)
                {
                    //if (row.Timestamp < minOffsetTime) continue;

                    var position = new Vector(row.PositionX, row.PositionY);
                    var degrees  = -row.Rotation;
                    if (row.Game == "W" && row.StudyId > 2)
                    {
                        degrees += 90;
                    }
                    else if (row.Game == "S" && row.StudyId < 3)
                    {
                        degrees -= 90;
                    }
                    else if (row.Game == "B" && row.StudyId < 2)
                    {
                        //degrees -= 90;
                    }
                    position = position.RotateCounter(degrees / 180 * Math.PI);

                    if (row.StudyType == "Ctrl")
                    {
                        position.X += 4;
                    }

                    for (int circleNum = 0; circleNum < numCircles; circleNum++)
                    {
                        var positionPolygon = Polygon.AsCircle(subradiusLength * circleNum, position, circleSubsteps);
                        foreach (var point in positionPolygon.Points)
                        {
                            sb.AppendLine($"{row.StudyId};{row.Game};{row.StudyType};{point.X};{point.Z};{position.X};{position.Z}".Replace(",", "."));
                        }
                    }
                }
                File.AppendAllText(outfilePath, sb.ToString());

                Logger.Debug($"{selection.Game} and {selection.StudyType} completed point generation");
            }

            Logger.Debug("Done");


            //i = 0;
            //foreach (var row in query)
            //{
            //    Logger.Debug($"Part = {row.PartId}, Study type = {row.StudyType}, Game = {row.Game}, Rotation = {row.Rotation}, Position = {row.PositionX}, {row.PositionY}");
            //    i++;
            //    if (i > 100) break;
            //}



            Console.ReadKey();
        }