public int NextRight(int rightIndex, List <AdventureLandLibrary.Geometry.LineD> portals)
        {
            var curPoint = portals[rightIndex].P1;

            if (rightIndex < portals.Count - 1)
            {
                int nextIndex = rightIndex + 1;
                AdventureLandLibrary.Geometry.PointD nextPoint = portals[nextIndex].P1;

                //while (curPoint.X == nextPoint.X && curPoint.Y == nextPoint.Y && nextIndex < portals.Count - 1)
                //{
                //    nextIndex++;
                //    nextPoint = portals[nextIndex].P2;
                //}

                return(nextIndex);
            }
            else
            {
                return(rightIndex);
            }
        }
        public List <AdventureLandLibrary.Geometry.Point> FunnelSmooth(List <AdventureLandLibrary.Geometry.GraphNode> path, AdventureLandLibrary.Geometry.Point startPoint, AdventureLandLibrary.Geometry.Point endPoint)
        {
            if (path.Count > 2)
            {
                var offsetEndpoint = new AdventureLandLibrary.Geometry.Point(endPoint.X + currentMap.OffsetX, endPoint.Y + currentMap.OffsetY);

                List <AdventureLandLibrary.Geometry.Point> newPath = new List <AdventureLandLibrary.Geometry.Point>();

                List <AdventureLandLibrary.Geometry.LineD> portals = new List <AdventureLandLibrary.Geometry.LineD>();

                for (var i = 0; i < path.Count - 1; i++)
                {
                    portals.Add(path[i].GetPortal(path[i + 1]));
                }

                var ending = path[path.Count - 1].GetNonPortal(path[path.Count - 2], offsetEndpoint);

                portals.AddRange(ending);

                var portalsToDelete = new List <AdventureLandLibrary.Geometry.LineD>();

                for (var i = 0; i < portals.Count; i++)
                {
                    var portal = portals[i];

                    var p1Link = portals.Where(p => (p.P1.X == portal.P1.X && p.P1.Y == portal.P1.Y) || (p.P2.X == portal.P1.X && p.P2.Y == portal.P1.Y)).ToList();
                    var p2Link = portals.Where(p => (p.P1.X == portal.P2.X && p.P1.Y == portal.P2.Y) || (p.P2.X == portal.P2.X && p.P2.Y == portal.P2.Y)).ToList();

                    if ((p1Link.Count == 1 || p2Link.Count == 1) && (i != 0 && i != portals.Count - 1))
                    {
                        //portalsToDelete.Add(portal);
                    }
                }

                foreach (var portal in portalsToDelete)
                {
                    portals.Remove(portal);
                }

                AdventureLandLibrary.Geometry.PointD currentNode = new AdventureLandLibrary.Geometry.PointD(startPoint.X + currentMap.OffsetX, startPoint.Y + currentMap.OffsetY);

                newPath.Add(new AdventureLandLibrary.Geometry.Point((int)currentNode.X - currentMap.OffsetX, (int)currentNode.Y - currentMap.OffsetY));

                int funnelLeftIndex  = 1;
                int funnelRightIndex = 1;

                int curFunnelLeftIndex  = 1;
                int curFunnelRightIndex = 1;

                AdventureLandLibrary.Geometry.LineD funnelLeft  = new AdventureLandLibrary.Geometry.LineD(currentNode, portals[0].P2);
                AdventureLandLibrary.Geometry.LineD funnelRight = new AdventureLandLibrary.Geometry.LineD(currentNode, portals[0].P1);

                DrawLine(funnelLeft, Brushes.Cyan, 2);
                DrawLine(funnelRight, Brushes.Purple, 2);

                int leftSide  = 0;
                int rightSide = 1;

                AdventureLandLibrary.Geometry.PointD lastPoint = new AdventureLandLibrary.Geometry.PointD(offsetEndpoint.X, offsetEndpoint.Y);

                int count = 0;
                while (funnelLeftIndex < portals.Count && funnelRightIndex < portals.Count && !(funnelLeft.P2.X == lastPoint.X && funnelLeft.P2.Y == lastPoint.Y) && !(funnelRight.P2.X == lastPoint.X && funnelRight.P2.Y == lastPoint.Y))
                {
                    var prevLeftPoint = portals[funnelLeftIndex].P2;

                    if (leftSide == 0 && funnelLeftIndex > 0)
                    {
                        prevLeftPoint = portals[funnelLeftIndex - 1].P2;
                    }

                    var prevRightPoint = portals[funnelRightIndex].P1;

                    if (rightSide == 0 && funnelRightIndex > 0)
                    {
                        prevRightPoint = portals[funnelRightIndex - 1].P1;
                    }

                    var newFunnelLeftIndex  = funnelLeftIndex + leftSide;
                    var newFunnelRightIndex = funnelRightIndex + rightSide;

                    if (newFunnelLeftIndex > portals.Count - 1)
                    {
                        newFunnelLeftIndex = portals.Count - 1;
                    }

                    if (newFunnelRightIndex > portals.Count - 1)
                    {
                        newFunnelRightIndex = portals.Count - 1;
                    }

                    curFunnelLeftIndex  = curFunnelLeftIndex + leftSide;
                    curFunnelRightIndex = curFunnelRightIndex + rightSide;

                    if (curFunnelLeftIndex > portals.Count - 1)
                    {
                        curFunnelLeftIndex = portals.Count - 1;
                    }

                    if (curFunnelRightIndex > portals.Count - 1)
                    {
                        curFunnelRightIndex = portals.Count - 1;
                    }

                    var actualLeftPoint  = portals[newFunnelLeftIndex].P2;
                    var actualRightPoint = portals[newFunnelRightIndex].P1;

                    var leftPoint = portals[curFunnelLeftIndex].P2;

                    var rightPoint = portals[curFunnelRightIndex].P1;

                    var insideFunnel = false;

                    var dirLeftLeft        = funnelLeft.Direction(leftPoint);
                    var dirRightRight      = funnelRight.Direction(rightPoint);
                    var leftIsRightOfLeft  = funnelLeft.Direction(leftPoint) <= 0;
                    var rightIsLeftOfRight = funnelRight.Direction(rightPoint) >= 0;

                    var dirLeftRight       = funnelRight.Direction(leftPoint);
                    var dirRightLeft       = funnelLeft.Direction(rightPoint);
                    var leftIsLeftOfRight  = funnelRight.Direction(leftPoint) >= 0;
                    var rightIsRightOfLeft = funnelLeft.Direction(rightPoint) <= 0;

                    if (leftIsRightOfLeft && rightIsLeftOfRight && leftIsLeftOfRight && rightIsRightOfLeft)
                    {
                        insideFunnel = true;
                    }

                    if (!insideFunnel)
                    {
                        if (!leftIsLeftOfRight)
                        {
                            currentNode = new AdventureLandLibrary.Geometry.PointD(portals[funnelRightIndex].P1.X, portals[funnelRightIndex].P1.Y);

                            newPath.Add(new AdventureLandLibrary.Geometry.Point((int)currentNode.X - currentMap.OffsetX, (int)currentNode.Y - currentMap.OffsetY));
                            //funnelLeftIndex = newFunnelLeftIndex;
                            //funnelRightIndex = newFunnelLeftIndex;
                            var minIndex = Math.Min(newFunnelLeftIndex, newFunnelRightIndex);

                            var newFRight = NextRight(minIndex, portals);
                            var newFLeft  = NextLeft(minIndex, portals);

                            var maxPortal = Math.Max(newFRight, newFLeft);

                            funnelLeftIndex     = maxPortal;
                            funnelRightIndex    = maxPortal;
                            funnelLeft          = new AdventureLandLibrary.Geometry.LineD(currentNode, portals[maxPortal].P2);
                            funnelRight         = new AdventureLandLibrary.Geometry.LineD(currentNode, portals[maxPortal].P1);
                            curFunnelLeftIndex  = maxPortal;
                            curFunnelRightIndex = maxPortal;
                            DrawLine(funnelLeft, Brushes.Cyan, 3);
                            DrawLine(funnelRight, Brushes.Purple, 3);
                        }
                        else if (!rightIsRightOfLeft)
                        {
                            currentNode = new AdventureLandLibrary.Geometry.PointD(portals[funnelLeftIndex].P2.X, portals[funnelLeftIndex].P2.Y);

                            newPath.Add(new AdventureLandLibrary.Geometry.Point((int)currentNode.X - currentMap.OffsetX, (int)currentNode.Y - currentMap.OffsetY));

                            //funnelLeftIndex = newFunnelRightIndex;
                            //funnelRightIndex = newFunnelRightIndex;
                            //curFunnelLeftIndex = funnelLeftIndex;
                            //curFunnelRightIndex = funnelRightIndex;

                            var minIndex = Math.Min(newFunnelLeftIndex, newFunnelRightIndex);

                            var newFRight = NextRight(minIndex, portals);
                            var newFLeft  = NextLeft(minIndex, portals);

                            var maxPortal = Math.Max(newFRight, newFLeft);

                            funnelLeftIndex     = maxPortal;
                            funnelRightIndex    = maxPortal;
                            funnelLeft          = new AdventureLandLibrary.Geometry.LineD(currentNode, portals[maxPortal].P2);
                            funnelRight         = new AdventureLandLibrary.Geometry.LineD(currentNode, portals[maxPortal].P1);
                            curFunnelLeftIndex  = maxPortal;
                            curFunnelRightIndex = maxPortal;
                            DrawLine(funnelLeft, Brushes.Cyan, 3);
                            DrawLine(funnelRight, Brushes.Purple, 3);
                        }
                        else if (rightIsLeftOfRight)
                        {
                            funnelRight = new AdventureLandLibrary.Geometry.LineD(currentNode, rightPoint);
                            //funnelRightIndex = newFunnelRightIndex;
                            //curFunnelRightIndex = newFunnelRightIndex;
                            //DrawLine(funnelLeft, Brushes.Cyan, 3);
                            //DrawLine(funnelRight, Brushes.Purple, 3);
                        }
                        else if (leftIsRightOfLeft)
                        {
                            funnelLeft = new AdventureLandLibrary.Geometry.LineD(currentNode, leftPoint);
                            //funnelLeftIndex = newFunnelLeftIndex;
                            //curFunnelLeftIndex = newFunnelRightIndex;
                            DrawLine(funnelLeft, Brushes.Cyan, 3);
                            DrawLine(funnelRight, Brushes.Purple, 3);
                        }
                        //else if (!rightIsLeftOfRight)
                        //{
                        //    currentNode = new AdventureLandLibrary.Geometry.PointD(prevRightPoint.X, prevRightPoint.Y);

                        //    newPath.Add(new AdventureLandLibrary.Geometry.Point((int)currentNode.X - currentMap.OffsetX, (int)currentNode.Y - currentMap.OffsetY));
                        //    funnelLeft = new AdventureLandLibrary.Geometry.LineD(currentNode, leftPoint);
                        //    funnelRight = new AdventureLandLibrary.Geometry.LineD(currentNode, rightPoint);
                        //    DrawLine(funnelLeft, Brushes.Cyan, 2);
                        //    DrawLine(funnelRight, Brushes.Purple, 2);
                        //}
                        //else if (!leftIsRightOfLeft)
                        //{
                        //    currentNode = new AdventureLandLibrary.Geometry.PointD(prevLeftPoint.X, prevLeftPoint.Y);

                        //    newPath.Add(new AdventureLandLibrary.Geometry.Point((int)currentNode.X - currentMap.OffsetX, (int)currentNode.Y - currentMap.OffsetY));
                        //    funnelLeft = new AdventureLandLibrary.Geometry.LineD(currentNode, leftPoint);
                        //    funnelRight = new AdventureLandLibrary.Geometry.LineD(currentNode, rightPoint);
                        //    DrawLine(funnelLeft, Brushes.Cyan, 2);
                        //    DrawLine(funnelRight, Brushes.Purple, 2);
                        //}
                    }
                    else
                    {
                        var newfunnelLeft  = new AdventureLandLibrary.Geometry.LineD(currentNode, leftPoint);
                        var newfunnelRight = new AdventureLandLibrary.Geometry.LineD(currentNode, rightPoint);

                        funnelLeftIndex     = newFunnelLeftIndex;
                        funnelRightIndex    = newFunnelRightIndex;
                        funnelLeft          = newfunnelLeft;
                        funnelRight         = newfunnelRight;
                        curFunnelLeftIndex  = funnelLeftIndex;
                        curFunnelRightIndex = funnelRightIndex;

                        //DrawLine(funnelLeft, Brushes.Cyan);
                        //DrawLine(funnelRight, Brushes.Purple);
                    }
                    leftSide++;
                    rightSide++;

                    if (leftSide > 1)
                    {
                        leftSide = 0;
                    }

                    if (rightSide > 1)
                    {
                        rightSide = 0;
                    }
                    count++;
                }

                newPath.Add(new AdventureLandLibrary.Geometry.Point(endPoint.X, endPoint.Y));
                return(newPath);
            }
            else
            {
                List <AdventureLandLibrary.Geometry.Point> newPath = new List <AdventureLandLibrary.Geometry.Point>();

                newPath.Add(startPoint);
                newPath.Add(endPoint);

                return(newPath);
            }
        }