using System; using System.Collections.Generic; using System.Linq; using QuickGraph; namespace GraphSharp { internal class GraphHideHelper : ISoftMutableGraph where TEdge : IEdge { private readonly IMutableBidirectionalGraph graph; #region Helper Types protected class HiddenCollection { public List hiddenVertices = new List(); public List hiddenEdges = new List(); } #endregion #region Properties, fields, events private readonly List hiddenVertices = new List(); private readonly List hiddenEdges = new List(); private readonly IDictionary hiddenCollections = new Dictionary(); private readonly IDictionary> hiddenEdgesOf = new Dictionary>(); public event EdgeAction EdgeHidden; public event EdgeAction EdgeUnhidden; public event VertexAction VertexHidden; public event VertexAction VertexUnhidden; #endregion public GraphHideHelper( IMutableBidirectionalGraph managedGraph ) { graph = managedGraph; } #region Event handlers, helper methods /// /// Returns every edge connected with the vertex v. /// /// The vertex. /// Edges, adjacent to the vertex v. protected IEnumerable EdgesFor( TVertex v ) { return graph.InEdges( v ).Concat( graph.OutEdges( v ) ); } protected HiddenCollection GetHiddenCollection( string tag ) { HiddenCollection h; if ( !hiddenCollections.TryGetValue( tag, out h ) ) { h = new HiddenCollection(); hiddenCollections[tag] = h; } return h; } protected void OnEdgeHidden( TEdge e ) { if ( EdgeHidden != null ) EdgeHidden( e ); } protected void OnEdgeUnhidden( TEdge e ) { if ( EdgeUnhidden != null ) EdgeUnhidden( e ); } protected void OnVertexHidden( TVertex v ) { if ( VertexHidden != null ) VertexHidden( v ); } protected void OnVertexUnhidden( TVertex v ) { if ( VertexUnhidden != null ) VertexUnhidden( v ); } #endregion #region ISoftMutableGraph Members public IEnumerable HiddenVertices { get { return hiddenVertices; } } public IEnumerable HiddenEdges { get { return hiddenEdges; } } /// /// Hides the vertex v. /// /// The vertex to hide. public bool HideVertex( TVertex v ) { if ( graph.ContainsVertex( v ) && !hiddenVertices.Contains( v ) ) { HideEdges( EdgesFor( v ) ); //hide the vertex graph.RemoveVertex( v ); hiddenVertices.Add( v ); OnVertexHidden( v ); return true; } return false; } /// /// Hides a lot of vertices. /// /// The vertices to hide. public void HideVertices( IEnumerable vertices ) { var verticesToHide = new List( vertices ); foreach ( TVertex v in verticesToHide ) { HideVertex( v ); } } public bool HideVertex( TVertex v, string tag ) { HiddenCollection h = GetHiddenCollection( tag ); var eeh = new EdgeAction( e => h.hiddenEdges.Add( e ) ); var veh = new VertexAction( vertex => h.hiddenVertices.Add( vertex ) ); EdgeHidden += eeh; VertexHidden += veh; bool ret = HideVertex( v ); EdgeHidden -= eeh; VertexHidden -= veh; return ret; } public void HideVertices( IEnumerable vertices, string tag ) { foreach ( TVertex v in vertices ) { HideVertex( v, tag ); } } public void HideVerticesIf( Func predicate, string tag ) { var verticesToHide = new List(); foreach ( var v in graph.Vertices ) { if ( predicate( v ) ) verticesToHide.Add( v ); } HideVertices( verticesToHide, tag ); } public bool IsHiddenVertex( TVertex v ) { return ( !graph.ContainsVertex( v ) && hiddenVertices.Contains( v ) ); } public bool UnhideVertex( TVertex v ) { //if v not hidden, it's an error if ( !IsHiddenVertex( v ) ) return false; //unhide the vertex graph.AddVertex( v ); hiddenVertices.Remove( v ); OnVertexUnhidden( v ); return true; } public void UnhideVertexAndEdges( TVertex v ) { UnhideVertex( v ); List hiddenEdgesList; hiddenEdgesOf.TryGetValue( v, out hiddenEdgesList ); if ( hiddenEdgesList != null ) UnhideEdges( hiddenEdgesList ); } public bool HideEdge( TEdge e ) { if ( graph.ContainsEdge( e ) && !hiddenEdges.Contains( e ) ) { graph.RemoveEdge( e ); hiddenEdges.Add( e ); GetHiddenEdgeListOf( e.Source ).Add( e ); GetHiddenEdgeListOf( e.Target ).Add( e ); OnEdgeHidden( e ); return true; } return false; } private List GetHiddenEdgeListOf( TVertex v ) { List hiddenEdgeList; hiddenEdgesOf.TryGetValue( v, out hiddenEdgeList ); if ( hiddenEdgeList == null ) { hiddenEdgeList = new List(); hiddenEdgesOf[v] = hiddenEdgeList; } return hiddenEdgeList; } public IEnumerable HiddenEdgesOf( TVertex v ) { return GetHiddenEdgeListOf( v ); } public int HiddenEdgeCountOf( TVertex v ) { return GetHiddenEdgeListOf( v ).Count; } public bool HideEdge( TEdge e, string tag ) { var h = GetHiddenCollection( tag ); var eeh = new EdgeAction( edge => h.hiddenEdges.Add( edge ) ); EdgeHidden += eeh; bool ret = HideEdge( e ); EdgeHidden -= eeh; return ret; } public void HideEdges( IEnumerable edges ) { var edgesToHide = new List( edges ); foreach ( var e in edgesToHide ) { HideEdge( e ); } } public void HideEdges( IEnumerable edges, string tag ) { var edgesToHide = new List( edges ); foreach ( var e in edgesToHide ) { HideEdge( e, tag ); } } public void HideEdgesIf( Func predicate, string tag ) { var edgesToHide = new List(); foreach ( var e in graph.Edges ) { if ( predicate( e ) ) edgesToHide.Add( e ); } HideEdges( edgesToHide, tag ); } public bool IsHiddenEdge( TEdge e ) { return ( !graph.ContainsEdge( e ) && hiddenEdges.Contains( e ) ); } public bool UnhideEdge( TEdge e ) { if ( IsHiddenVertex( e.Source ) || IsHiddenVertex( e.Target ) || !IsHiddenEdge( e ) ) return false; //unhide the edge graph.AddEdge( e ); hiddenEdges.Remove( e ); GetHiddenEdgeListOf( e.Source ).Remove( e ); GetHiddenEdgeListOf( e.Target ).Remove( e ); OnEdgeUnhidden( e ); return true; } public void UnhideEdgesIf( Func predicate ) { var edgesToUnhide = new List(); foreach ( var e in hiddenEdges ) { if ( predicate( e ) ) edgesToUnhide.Add( e ); } UnhideEdges( edgesToUnhide ); } public void UnhideEdges( IEnumerable edges ) { var edgesToUnhide = new List( edges ); foreach ( var e in edgesToUnhide ) { UnhideEdge( e ); } } public bool Unhide( string tag ) { HiddenCollection h = GetHiddenCollection( tag ); foreach ( TVertex v in h.hiddenVertices ) { UnhideVertex( v ); } foreach ( TEdge e in h.hiddenEdges ) { UnhideEdge( e ); } return hiddenCollections.Remove( tag ); } public bool UnhideAll() { while ( hiddenVertices.Count > 0 ) { UnhideVertex( hiddenVertices[0] ); } while ( hiddenEdges.Count > 0 ) { UnhideEdge( hiddenEdges[0] ); } return true; } public int HiddenVertexCount { get { return hiddenVertices.Count; } } public int HiddenEdgeCount { get { return hiddenEdges.Count; } } #endregion #region IBidirectionalGraph Members public int Degree( TVertex v ) { throw new NotImplementedException(); } public int InDegree( TVertex v ) { throw new NotImplementedException(); } public TEdge InEdge( TVertex v, int index ) { throw new NotImplementedException(); } public IEnumerable InEdges( TVertex v ) { throw new NotImplementedException(); } public bool IsInEdgesEmpty( TVertex v ) { throw new NotImplementedException(); } #endregion #region IIncidenceGraph Members public bool ContainsEdge( TVertex source, TVertex target ) { throw new NotImplementedException(); } public bool TryGetEdge( TVertex source, TVertex target, out TEdge edge ) { throw new NotImplementedException(); } public bool TryGetEdges( TVertex source, TVertex target, out IEnumerable edges ) { throw new NotImplementedException(); } #endregion #region IImplicitGraph Members public bool IsOutEdgesEmpty( TVertex v ) { throw new NotImplementedException(); } public int OutDegree( TVertex v ) { throw new NotImplementedException(); } public TEdge OutEdge( TVertex v, int index ) { throw new NotImplementedException(); } public IEnumerable OutEdges( TVertex v ) { throw new NotImplementedException(); } #endregion #region IGraph Members public bool AllowParallelEdges { get { throw new NotImplementedException(); } } public bool IsDirected { get { throw new NotImplementedException(); } } #endregion #region IVertexSet Members public bool ContainsVertex( TVertex vertex ) { throw new NotImplementedException(); } public bool IsVerticesEmpty { get { throw new NotImplementedException(); } } public int VertexCount { get { throw new NotImplementedException(); } } public IEnumerable Vertices { get { throw new NotImplementedException(); } } #endregion #region IEdgeListGraph Members public bool ContainsEdge( TEdge edge ) { throw new NotImplementedException(); } public int EdgeCount { get { throw new NotImplementedException(); } } public IEnumerable Edges { get { throw new NotImplementedException(); } } public bool IsEdgesEmpty { get { throw new NotImplementedException(); } } #endregion public bool TryGetInEdges( TVertex v, out IEnumerable edges ) { throw new NotImplementedException(); } public bool TryGetOutEdges( TVertex v, out IEnumerable edges ) { throw new NotImplementedException(); } } }