//         double GetAverageOverlap(List<Tuple<int, int, double, double>> proximityEdgesWithDistance,
//                                         Point[] positions, Rectangle[] rectangles) {
//            double overlap = 0;
//            int counter = 0;
//            foreach (Tuple<int, int, double, double> tuple in proximityEdgesWithDistance) {
//                int nodeId1 = tuple.Item1;
//                int nodeId2 = tuple.Item2;
//                Point point1 = positions[nodeId1];
//                Point point2 = positions[nodeId2];
//
//                if (nodeBoxes == null) throw new ArgumentNullException("nodeBoxes");
//                if (nodeBoxes.Length <= nodeId1) return 0;
//                if (nodeBoxes.Length <= nodeId2) return 0;
//                double box1Width = nodeBoxes[nodeId1].Width;
//                double box1Height = nodeBoxes[nodeId1].Height;
//                double box2Width = nodeBoxes[nodeId2].Width;
//                double box2Height = nodeBoxes[nodeId2].Height;
//
//                //Gansner et. al Scaling factor of distance
//                double tw = (box1Width/2 + box2Width/2)/Math.Abs(point1.X - point2.X);
//                double th = (box1Height/2 + box2Height/2)/Math.Abs(point1.Y - point2.Y);
//                double t = Math.Max(Math.Min(tw, th), 1);
//
//                if (t == 1) continue; // no overlap between the bounding boxes
//
//                double distance = (t - 1)*(point1 - point2).Length;
//                overlap += distance;
//                counter++;
//            }
//
//            overlap /= counter;
//            return overlap;
//        }

        /// <summary>
        /// For debugging only
        /// </summary>
        /// <param name="currentIteration"></param>
        /// <param name="nodeSizes"></param>
        /// <param name="nodePositions"></param>
        /// <param name="newPositions"></param>
        /// <param name="proximityEdgesWithDistance"></param>
        /// <param name="finalGridVectors"></param>
        static void ShowCurrentMovementVectors(int currentIteration, Size[] nodeSizes,
                                               Point[] nodePositions, List <Point> newPositions,
                                               List <Tuple <int, int, double, double> > proximityEdgesWithDistance,
                                               Point[] finalGridVectors)
        {
#if DEBUG && !SILVERLIGHT && !SHARPKIT
            if (DebugMode && currentIteration % 1 == 0)
            {
                List <DebugCurve> curveList = new List <DebugCurve>();
                var nodeBoxes = new Rectangle[nodeSizes.Length];
                for (int i = 0; i < nodeBoxes.Length; i++)
                {
                    nodeBoxes[i] = new Rectangle(nodeSizes[i], nodePositions[i]);
                }
                var nodeCurves =
                    nodeBoxes.Select(
                        v =>
                        new DebugCurve(220, 1, "black", Curve.PolylineAroundClosedCurve(CurveFactory.CreateRectangle(v))));
                curveList.AddRange(nodeCurves);
                var vectors = nodePositions.Select(
                    (p, i) =>
                    new DebugCurve(220, 2, "red", new Polyline(p, newPositions[i]))).ToList();

                foreach (Tuple <int, int, double, double> tuple in proximityEdgesWithDistance)
                {
                    if (tuple.Item3 > 0)
                    {
                        curveList.Add(new DebugCurve(220, 1, "gray",
                                                     new Polyline(nodePositions[tuple.Item1],
                                                                  nodePositions[tuple.Item2])));
                    }
                }
                curveList.AddRange(vectors);
                if (finalGridVectors != null)
                {
                    var gridFlowVectors = nodePositions.Select((p, i) =>
                                                               new DebugCurve(220, 2, "blue",
                                                                              new Polyline(p, p + finalGridVectors[i])))
                                          .ToList();
                    curveList.AddRange(gridFlowVectors);
                }

                LayoutAlgorithmSettings.ShowDebugCurves(curveList.ToArray());
            }
#endif
        }
 /// <summary>
 /// Shows the current state of the algorithm for debug purposes.
 /// </summary>
 /// <param name="treeEdges"></param>
 /// <param name="proximityEdges"></param>
 /// <param name="nodeSizes"></param>
 /// <param name="nodePos"></param>
 /// <param name="rootId"></param>
     void ShowAndMoveBoxesRemoveLater(List<Tuple<int, int, double, double, double>> treeEdges,
         List<Tuple<int, int, double, double, double>> proximityEdges, Size[] nodeSizes, Point[] nodePos, int rootId) {
         var l = new List<DebugCurve>();
         foreach (var tuple in proximityEdges)
             l.Add(new DebugCurve(100, 0.5, "black", new LineSegment(nodePos[tuple.Item1], nodePos[tuple.Item2])));
         //just for debug
         var nodeBoxes = new Rectangle[nodeSizes.Length];
         for (int i = 0; i < nodePos.Length; i++)
             nodeBoxes[i] = new Rectangle(nodeSizes[i], nodePos[i]);
         l.AddRange(nodeBoxes.Select(b => new DebugCurve(100, 0.3, "green", b.Perimeter())));
         if (treeEdges != null)
             l.AddRange(
                 treeEdges.Select(
                     e =>
                         new DebugCurve(200, GetEdgeWidth(e), "red",
                             new LineSegment(nodePos[e.Item1], nodePos[e.Item2]))));
         if (rootId >= 0)
             l.Add(new DebugCurve(100, 10, "blue", CurveFactory.CreateOctagon(30, 30, nodePos[rootId])));
         LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(l);
     }
//         double GetAverageOverlap(List<Tuple<int, int, double, double>> proximityEdgesWithDistance,
//                                         Point[] positions, Rectangle[] rectangles) {
//            double overlap = 0;
//            int counter = 0;
//            foreach (Tuple<int, int, double, double> tuple in proximityEdgesWithDistance) {
//                int nodeId1 = tuple.Item1;
//                int nodeId2 = tuple.Item2;
//                Point point1 = positions[nodeId1];
//                Point point2 = positions[nodeId2];
//
//                if (nodeBoxes == null) throw new ArgumentNullException("nodeBoxes");
//                if (nodeBoxes.Length <= nodeId1) return 0;
//                if (nodeBoxes.Length <= nodeId2) return 0;
//                double box1Width = nodeBoxes[nodeId1].Width;
//                double box1Height = nodeBoxes[nodeId1].Height;
//                double box2Width = nodeBoxes[nodeId2].Width;
//                double box2Height = nodeBoxes[nodeId2].Height;
//
//                //Gansner et. al Scaling factor of distance
//                double tw = (box1Width/2 + box2Width/2)/Math.Abs(point1.X - point2.X);
//                double th = (box1Height/2 + box2Height/2)/Math.Abs(point1.Y - point2.Y);
//                double t = Math.Max(Math.Min(tw, th), 1);
//
//                if (t == 1) continue; // no overlap between the bounding boxes
//
//                double distance = (t - 1)*(point1 - point2).Length;
//                overlap += distance;
//                counter++;
//            }
//
//            overlap /= counter;
//            return overlap;
//        }

        /// <summary>
        /// For debugging only
        /// </summary>
        /// <param name="currentIteration"></param>
        /// <param name="nodeSizes"></param>
        /// <param name="nodePositions"></param>
        /// <param name="newPositions"></param>
        /// <param name="proximityEdgesWithDistance"></param>
        /// <param name="finalGridVectors"></param>
         static void ShowCurrentMovementVectors(int currentIteration, Size[] nodeSizes,
                                                       Point[] nodePositions, List<Point> newPositions,
                                                       List<Tuple<int, int, double, double>> proximityEdgesWithDistance,
                                                       Point[] finalGridVectors) {
#if DEBUG && ! SILVERLIGHT && !SHARPKIT
            if (DebugMode && currentIteration%1 == 0) {
                List<DebugCurve> curveList = new List<DebugCurve>();
                var nodeBoxes = new Rectangle[nodeSizes.Length];
                for(int i=0;i<nodeBoxes.Length;i++)
                    nodeBoxes[i]=new Rectangle(nodeSizes[i], nodePositions[i]);
                var nodeCurves =
                    nodeBoxes.Select(
                        v =>
                        new DebugCurve(220, 1, "black", Curve.PolylineAroundClosedCurve(CurveFactory.CreateRectangle(v))));
                curveList.AddRange(nodeCurves);
                var vectors = nodePositions.Select(
                    (p, i) =>
                    new DebugCurve(220, 2, "red", new Polyline(p, newPositions[i]))).ToList();

                foreach (Tuple<int, int, double, double> tuple in proximityEdgesWithDistance) {
                    if (tuple.Item3 > 0) {
                        curveList.Add(new DebugCurve(220, 1, "gray",
                                                     new Polyline(nodePositions[tuple.Item1],
                                                                  nodePositions[tuple.Item2])));
                    }
                }
                curveList.AddRange(vectors);
                if (finalGridVectors != null) {
                    var gridFlowVectors = nodePositions.Select((p, i) =>
                                                               new DebugCurve(220, 2, "blue",
                                                                              new Polyline(p, p + finalGridVectors[i])))
                                                       .ToList();
                    curveList.AddRange(gridFlowVectors);
                }

                LayoutAlgorithmSettings.ShowDebugCurves(curveList.ToArray());
            }
#endif
        }