using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using Microsoft.Msagl.Core.DataStructures;
using Microsoft.Msagl.Core.Geometry;
using Microsoft.Msagl.Core.Geometry.Curves;
using Microsoft.Msagl.Core.Layout;
using Microsoft.Msagl.DebugHelpers;
using Microsoft.Msagl.Prototype.Ranking;
namespace Microsoft.Msagl.Layout.LargeGraphLayout {
///
/// data for large graph browsing
///
public class LgData {
readonly List _connectedComponents = new List();
internal Dictionary GeometryNodesToLgNodeInfos;
internal readonly Dictionary GeometryEdgesToLgEdgeInfos = new Dictionary();
readonly Set _selectedEdges=new Set();
Set _selectedNodeInfos = new Set();
readonly List _levels = new List();
internal readonly List SkeletonLevels = new List();
///
/// the list of levels
///
public IList Levels { get { return _levels; } }
internal LgData(GeometryGraph mainGeomGraph) {
this.mainGeomGraph = mainGeomGraph;
}
#region Level class
#endregion end of Level class
internal void AddConnectedGeomGraph(GeometryGraph geomGraph) {
_connectedComponents.Add(geomGraph);
}
internal IEnumerable ConnectedGeometryGraphs {
get { return _connectedComponents; }
}
///
/// LgNodeInfos sorted by their importance
///
public List SortedLgNodeInfos { get; set; }
///
/// the last indices of nodes on levels, the indices point to SortedLgNodeInfos
///
public List LevelNodeCounts { get; set; }
/*
static void showdeletelater(ICurve curve, LinkedList> samples, Point middleValue) {
var l = new List();
l.Add(new DebugCurve(100, 1, "black", curve));
foreach (var sample in samples)
l.Add(new DebugCurve( 0.1, "red", new Ellipse(1, 1, sample.Item2)));
l.Add(new DebugCurve(1, "blue", new Ellipse(3, 3, middleValue)));
LayoutAlgorithmSettings.ShowDebugCurves(l.ToArray());
}
*/
internal LgLevel GetCurrentLevelByScale(double zoomLevel) {
return this._levels[GetLevelIndexByScale(zoomLevel)];
}
internal LgLevel AddLevel() {
int zoomLevel = (int) Math.Pow(2, _levels.Count());
var level = new LgLevel(zoomLevel, mainGeomGraph);
_levels.Add(level);
return level;
}
GeometryGraph mainGeomGraph; //needed for statistice only
// public void ExtractRailsFromRouting(EdgeCollection edges, int levelZoom) {
// var level = AddLevel(levelZoom);
// level.CreateRailTree(edges);
//
//
//
// Console.WriteLine("segs={0} rail count = {1}",
// edges.Sum(
// e =>
// ((e.Curve is Curve) ? ((Curve) e.Curve).Segments.Count : 1) +
// (e.EdgeGeometry.SourceArrowhead != null ? 1 : 0) +
// (e.EdgeGeometry.TargetArrowhead != null ? 1 : 0)), level.Rails.Count());
// }
// void UpdateEdgeGeometriesByLevel(int levelIndex, Rail rail) {
// var edgeInfo = rail.EdgeInfo;
// var edgeGeomsByLevels = edgeInfo.EdgeGeometriesByLevels;
// if (edgeGeomsByLevels == null)
// edgeInfo.EdgeGeometriesByLevels = edgeGeomsByLevels = new List();
//
// EdgePartialGeometryOnLevel edgePartialGeom;
// if (edgeInfo.EdgeGeometriesByLevels.Count < levelIndex + 1)
// edgeGeomsByLevels.Add(edgePartialGeom = new EdgePartialGeometryOnLevel());
// else
// edgePartialGeom = edgeGeomsByLevels[levelIndex];
//
// var geom = rail.Geometry;
// var edgeGeometry = edgeInfo.Edge.EdgeGeometry;
// var arrowhead = geom as Arrowhead;
// if (arrowhead != null) {
// if (arrowhead == edgeGeometry.SourceArrowhead) {
// edgePartialGeom.SourceArrowhead = arrowhead;
// } else {
// Debug.Assert(arrowhead == edgeGeometry.TargetArrowhead);
// edgePartialGeom.TargetArrowhead = arrowhead;
// }
// } else {
// if (edgePartialGeom.ConnectedPiecesOfCurve == null)
// edgePartialGeom.ConnectedPiecesOfCurve = new List();
// edgePartialGeom.ConnectedPiecesOfCurve.Add((ICurve) geom);
// }
// }
internal int GetLevelIndexByScale(double scale) {
if (scale <= 1) return 0;
//var last = _levels.Last().ZoomLevel;
//if (scale >= last) return _levels.Count - 1;
var z = Math.Log(scale, 2);
int ret = (int)Math.Ceiling(z);
if (z >= _levels.Last().ZoomLevel) return _levels.Count - 1;
Debug.Assert(0 <= ret && ret < _levels.Count);
return ret;
}
/*
void RemoveRailsOfPassingEdgesFromLowerLevelsAndReduceHighlights(List passingEdges) {
var dimmedRails = new Set();
foreach (var edge in passingEdges) {
for (int i = levels.Count - 1; i >= 0; i--) {
var level = levels[i];
DiminishHighlightAndCollectDimmedRailOnLevel(edge, level, dimmedRails);
}
}
RemoveDimmedRailsFromLowerLevels(dimmedRails);
foreach (var edge in passingEdges) {
var ei = GeometryEdgesToLgEdgeInfos[edge];
for (int i = 0; i level.ZoomLevel) {
Set railsOfEdgeOnLevel;
if (level._railsOfEdges.TryGetValue(edge, out railsOfEdgeOnLevel))
if (railsOfEdgeOnLevel.Any(dimmedRails.Contains))
level._railsOfEdges.Remove(edge);
}
else break;
}
}
}
*/
// #if DEBUG && !SHARPKIT
// static void ShowDimmedRails(Set dimmedRails) {
// var l = new List();
// foreach (var r in dimmedRails) {
// var s = r.ToString();
// string color =
// s.StartsWith("15") ? "green" : (s.StartsWith("1384") ? "red" : "blue");
// l.Add(new DebugHelpers.DebugCurve(100, 1, color, r.Geometry as ICurve));
//
// }
// LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(l);
// }
// #endif
// void RemoveDimmedRailsFromLowerLevels(Set dimmedRails) {
// foreach(var rail in dimmedRails)
// RemoveDimmedRailFromLowerLevels(rail);
// }
//
// void RemoveDimmedRailFromLowerLevels(Rail rail) {
// Debug.Assert(rail.IsHighlighted==0);
// for (int i = 0; i < levels.Count; i++) {
// var level = levels[i];
// if (level.ZoomLevel < rail.ZoomLevel) {
// //the rail does not belong to this level
// var railTuple = rail.PointTuple();
// var rect = new Rectangle(railTuple.Item1, railTuple.Item2);
// level._railTree.Remove(rect, rail);
// }
// else break;
// }
//
// }
// static void DiminishHighlightAndCollectDimmedRailOnLevel(Edge edge, Level level, Set dimmedRails) {
// Set railsOfEdge;
// if (!level._railsOfEdges.TryGetValue(edge, out railsOfEdge)) return;
// foreach (var rail in railsOfEdge) {
// if (rail.IsHighlighted == 0) continue;
// rail.IsHighlighted--;
// if (rail.IsHighlighted == 0)
// dimmedRails.Insert(rail);
// }
// }
internal void SelectEdges(List passingEdges) {
SelectedEdges.InsertRange(passingEdges);
for (int i = _levels.Count - 1; i >= 0; i--)
SelectEdgesOnLevel(i, passingEdges);
}
internal void SelectEdges(List passingEdges, int currentLayer)
{
SelectedEdges.InsertRange(passingEdges);
foreach (Edge edge in passingEdges)
{
for (int i = 0; i <= currentLayer; i++)
{
Set railsOfEdge;
if (_levels[i]._railsOfEdges.TryGetValue(edge, out railsOfEdge))
{
var passingEdge = new List();
passingEdge.Add(edge);
SelectEdgesOnLevel(i, passingEdge);
}
}
}
}
public Set SelectedEdges {
get { return _selectedEdges; } }
internal Set SelectedNodeInfos {
get { return _selectedNodeInfos; }
private set { _selectedNodeInfos = value; }
}
void SelectEdgesOnLevel(int i, List edges) {
var level = _levels[i];
var railsToHighlight = new Set();
foreach (var edge in edges) {
Set railsOfEdge;
//Added the following two lines and commented out the third line
level._railsOfEdges.TryGetValue(edge, out railsOfEdge);
// if (railsOfEdge== null ||railsOfEdge.Count ==0)
{
var edgeInfo = GeometryEdgesToLgEdgeInfos[edge];
int edgeLevelIndex = (int) Math.Min(Math.Log(edgeInfo.ZoomLevel, 2), _levels.Count - 1);
edgeLevelIndex = _levels.Count - 1 ;
//if (railsOfEdge == null)
{
if (_levels[edgeLevelIndex]._railsOfEdges.ContainsKey(edge) == false) continue; //jyoti is it a bug?
railsOfEdge = _levels[edgeLevelIndex]._railsOfEdges[edge];
TransferHighlightedRails(level, edge, railsOfEdge);
railsToHighlight.InsertRange(railsOfEdge);
}
}
//else
// railsToHighlight.InsertRange(railsOfEdge);
foreach (Rail r in railsOfEdge)
{
if(r.Color==null) r.Color = new List