using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CategoryTheory;
using DiagramUI.Labels;
using DiagramUI.Interfaces;
using MathGraph;
namespace DiagramUI
{
/// <summary>
/// Performer of static operations
/// </summary>
public static class StaticPerformerExtension
{
#region Fields
/// <summary>
/// Log
/// </summary>
private static Action<Exception> log = (Exception e) => { };
/// <summary>
/// Handler of log
/// </summary>
private static IErrorHandler logHandler;
#endregion
#region Public members
/// <summary>
/// Sets strict error handler
/// </summary>
public static void SetStrictErrorHandler()
{
LogHandler = ErrorHandlers.StrictErrorHandler.Singleton;
}
/// <summary>
/// Exception log
/// </summary>
public static IErrorHandler LogHandler
{
get
{
return logHandler;
}
set
{
logHandler = value;
if (value == null)
{
log = (Exception e) => { };
}
else
{
log = (Exception ex) => { logHandler.ShowError(ex); };
}
}
}
/// <summary>
/// Logs exception
/// </summary>
/// <param name="exception">Exception for logging</param>
static public void Log(this Exception exception)
{
log(exception);
}
/// <summary>
/// Gets relative name
/// </summary>
/// <param name="source">Source</param>
/// <param name="target">Target</param>
/// <returns>The relative name</returns>
static public string GetRelativeName(this INamedComponent source, INamedComponent target)
{
return target.GetName(source.Desktop);
}
/// <summary>
/// Gets relative name
/// </summary>
/// <param name="source">Source</param>
/// <param name="target">Target</param>
/// <returns>The relative name</returns>
static public string GetRelativeName(this IAssociatedObject source, IAssociatedObject target)
{
INamedComponent cs = null;
if (source is INamedComponent)
{
cs = source as INamedComponent;
}
else
{
cs = source.Object as INamedComponent;
}
INamedComponent ct = null;
if (target is INamedComponent)
{
ct = target as INamedComponent;
}
else
{
ct = target.Object as INamedComponent;
}
return GetRelativeName(cs, ct);
}
/// <summary>
/// Names of desktop objects
/// </summary>
/// <param name="desktop">Desktop</param>
/// <returns>Names</returns>
public static string[] GetNames(this IDesktop desktop)
{
List<object> l = GetAll(desktop);
List<string> ln = new List<string>();
foreach (object o in l)
{
if (o is INamedComponent)
{
INamedComponent nc = o as INamedComponent;
ln.Add(nc.GetName(desktop));
}
}
return ln.ToArray();
}
/// <summary>
/// Composition of path arrows
/// </summary>
/// <param name="category">Category of arrows</param>
/// <param name="path">The path</param>
/// <returns>The composition</returns>
static public ICategoryArrow Composition(this ICategory category, DigraphPath path)
{
IArrowLabel label = path[0].Object as IArrowLabel;
ICategoryArrow arrow = label.Arrow;
for (int i = 1; i < path.Count; i++)
{
label = path[i].Object as IArrowLabel;
arrow = label.Arrow.Compose(category, arrow);
}
return arrow;
}
/// <summary>
/// Gets all category objects and arrows of collectiob
/// </summary>
/// <param name="collection">Collection</param>
/// <returns>All category objects and arrows</returns>
static public List<object> GetAll(this ICollection<object> collection)
{
List<object> l = new List<object>();
ForEach<ICategoryObject>(collection, (ICategoryObject o) => { if (!l.Contains(o)) { l.Add(o); } });
ForEach<ICategoryArrow>(collection, (ICategoryArrow o) => { if (!l.Contains(o)) { l.Add(o); } });
return l;
}
/// <summary>
/// Gets all category objects and arrows of desktop
/// </summary>
/// <param name="d">Desktop</param>
/// <returns>All category objects and arrows</returns>
static public List<object> GetAll(this IDesktop d)
{
List<object> l = new List<object>();
IList<ICategoryObject> objs = d.CategoryObjects;
IList<ICategoryArrow> arrs = d.CategoryArrows;
foreach (object o in objs)
{
if (!l.Contains(o))
{
l.Add(o);
}
}
foreach (object o in arrs)
{
if (!l.Contains(o))
{
l.Add(o);
}
}
return l;
}
/// <summary>
/// Gets all category objects and arrows of collection
/// </summary>
/// <param name="collection">Desktop</param>
/// <returns>All category objects and arrows</returns>
static public List<object> GetAll(this IComponentCollection collection)
{
return GetAll(collection.AllComponents);
}
/// <summary>
/// Gets all aliases of desktop
/// </summary>
/// <param name="desktop">The desktop</param>
/// <returns>Dictionary "alias - value"</returns>
static public Dictionary<string, object> GetAllAliases(this IDesktop desktop)
{
List<object> l = GetAll(desktop);
Dictionary<string, object> d = new Dictionary<string, object>();
foreach (object o in l)
{
if (!(o is IAlias))
{
continue;
}
IAssociatedObject ao = o as IAssociatedObject;
INamedComponent nc = ao.Object as INamedComponent;
string name = nc.GetName(desktop);
IAlias al = o as IAlias;
IList<string> an = al.AliasNames;
foreach (string nam in an)
{
string n = name + "." + nam;
if (d.ContainsKey(n))
{
throw new Exception("Double alias");
}
d[n] = al[nam];
}
}
return d;
}
/// <summary>
/// Sets all aliases of desktop
/// </summary>
/// <param name="desktop">The desktop</param>
/// <param name="aliases">Dictionary of aliases</param>
public static void SetAliases(this IDesktop desktop, Dictionary<string, object> aliases)
{
List<object> l = GetAll(desktop);
foreach (object o in l)
{
if (!(o is IAlias))
{
continue;
}
IAssociatedObject ao = o as IAssociatedObject;
INamedComponent nc = ao.Object as INamedComponent;
string name = nc.GetName(desktop);
IAlias al = o as IAlias;
IList<string> an = al.AliasNames;
foreach (string nam in an)
{
string n = name + "." + nam;
if (aliases.ContainsKey(n))
{
al[nam] = aliases[n];
}
}
}
}
/// <summary>
/// Disposes desktop
/// </summary>
/// <param name="desktop">Desktop to dispose</param>
public static void Dispose(this IDesktop desktop)
{
Remove(desktop);
ICollection<object> c = desktop.AllComponents;
foreach (object o in c)
{
DisposeAssociatedObject(o);
}
}
/// <summary>
/// Disposes desktop
/// </summary>
/// <param name="desktop">Desktop to dispose</param>
public static void DisposeDesktop(this IDesktop desktop)
{
desktop.Dispose();
}
/// <summary>
/// Disposes desktop
/// </summary>
/// <param name="desktop">The desktop for disposing</param>
public static void Remove(this IDesktop desktop)
{
IList<ICategoryArrow> arrs = desktop.CategoryArrows;
foreach (ICategoryArrow arr in arrs)
{
RemoveObject(arr);
}
IList<ICategoryObject> objs = desktop.CategoryObjects;
foreach (ICategoryObject ob in objs)
{
RemoveObject(ob);
}
}
/// <summary>
/// Removes object
/// </summary>
/// <param name="o">The object to remove</param>
public static void RemoveObject(object o)
{
if (o == null)
{
return;
}
if (o is IChildrenObject)
{
IChildrenObject ch = o as IChildrenObject;
IAssociatedObject[] aoa = ch.Children;
if (aoa != null)
{
foreach (IAssociatedObject ao in aoa)
{
RemoveObject(ao);
}
}
}
if (o is IRemovableObject)
{
IRemovableObject ro = o as IRemovableObject;
ro.RemoveObject();
}
if (o is IObjectLabel)
{
IObjectLabel ol = o as IObjectLabel;
RemoveObject(ol.Object);
}
if (o is IArrowLabel)
{
IArrowLabel al = o as IArrowLabel;
RemoveObject(al.Arrow);
}
if (o is IDisposable)
{
IDisposable d = o as IDisposable;
d.Dispose();
}
}
/// <summary>
/// Performs action for each collection objects
/// </summary>
/// <typeparam name="T">Type of object</typeparam>
/// <param name="collection">The collection</param>
/// <param name="action">The action</param>
public static void ForEach<T>(this ICollection<object> collection, Action<T> action) where T : class
{
foreach (object o in collection)
{
if (o is T)
{
Execute<T>(o as T, action);
continue;
}
if (o is IObjectLabel)
{
IObjectLabel l = o as IObjectLabel;
object obj = l.Object;
Execute<T>(obj, action);
}
if (o is IArrowLabel)
{
IArrowLabel l = o as IArrowLabel;
object obj = l.Arrow;
Execute<T>(obj, action);
}
}
}
/// <summary>
/// Performs action for each collection objects
/// </summary>
/// <typeparam name="T">Type of object</typeparam>
/// <param name="collection">The collection</param>
/// <param name="action">The action</param>
public static void ForEach<T>(this IComponentCollection collection, Action<T> action) where T : class
{
ICollection<object> c = collection.AllComponents;
ForEach<T>(c, action);
}
/// <summary>
/// Executes action
/// </summary>
/// <typeparam name="T">Type of variable</typeparam>
/// <param name="obj">object</param>
/// <param name="action">Action</param>
public static void Execute<T>(object obj, Action<T> action) where T : class
{
if (obj == null)
{
return;
}
if (obj is T)
{
T t = obj as T;
action(t);
}
if (obj is IChildrenObject)
{
IChildrenObject ch = obj as IChildrenObject;
IAssociatedObject[] ob = ch.Children;
foreach (object o in ob)
{
Execute<T>(o, action);
}
}
}
/// <summary>
/// Performs action for each desktop objects
/// </summary>
/// <typeparam name="T">Type of object</typeparam>
/// <param name="obj">Base object</param>
/// <param name="action">The action</param>
public static void ForEach<T>(this ICategoryObject obj, Action<T> action) where T : class
{
IDesktop d = GetRootDesktop(obj);
ForEach<T>(d, action);
}
/// <summary>
/// Gets root desktop
/// </summary>
/// <param name="obj">Object</param>
/// <returns>Root desktop</returns>
public static IDesktop GetRootDesktop(this ICategoryObject obj)
{
object o = obj.Object;
INamedComponent nc = o as INamedComponent;
nc = nc.Root;
return nc.Desktop;
}
/// <summary>
/// Gets root desktop
/// </summary>
/// <param name="arr">Arrow</param>
/// <returns>Root desktop</returns>
public static IDesktop GetRootDesktop(this ICategoryArrow arr)
{
object o = arr.Object;
INamedComponent nc = o as INamedComponent;
nc = nc.Root;
return nc.Desktop;
}
/// <summary>
/// Gets Named Component
/// </summary>
/// <param name="obj">Associated object</param>
/// <returns>Named Component</returns>
public static INamedComponent GetNamedComponent(this IAssociatedObject obj)
{
if (obj is INamedComponent)
{
return obj as INamedComponent;
}
object o = obj.Object;
if (o is INamedComponent)
{
return o as INamedComponent;
}
return null;
}
/// <summary>
/// Gets category object
/// </summary>
/// <param name="obj">Prototype</param>
/// <returns>The object</returns>
public static ICategoryObject GetCategoryObject(this IAssociatedObject obj)
{
object o = GetObject(obj);
if (o is ICategoryObject)
{
return o as ICategoryObject;
}
return null;
}
/// <summary>
/// Gets category arrow
/// </summary>
/// <param name="obj">Prototype</param>
/// <returns>The arrow</returns>
public static ICategoryArrow GetCategoryArrow(this IAssociatedObject obj)
{
object o = GetObject(obj);
if (o is ICategoryArrow)
{
return o as ICategoryArrow;
}
return null;
}
/// <summary>
/// Adds object label to desktop
/// </summary>
/// <param name="desktop">The desktop</param>
/// <param name="label">The label</param>
/// <param name="categoryObject">The object</param>
/// <param name="associated">The "assoicated" sign</param>
public static void AddObjectLabel(this IDesktop desktop, IObjectLabel label, ICategoryObject categoryObject, bool associated)
{
label.Object = categoryObject;
categoryObject.Object = label;
List<IObjectLabel> l = new List<IObjectLabel>();
l.Add(label);
List<IArrowLabel> la = new List<IArrowLabel>();
desktop.Copy(l, la, associated);
}
/// <summary>
/// Gets object name
/// </summary>
/// <param name="ao">Object</param>
/// <returns>The name</returns>
public static string GetObjectName(this IAssociatedObject ao)
{
object o = ao.Object;
if (!(o is INamedComponent))
{
throw new Exception();
}
INamedComponent nc = o as INamedComponent;
return nc.Name + "";
}
/// <summary>
/// Sets value of alias variable
/// </summary>
/// <param name="desktop">Desktop</param>
/// <param name="alias">The alias name</param>
/// <param name="val">The alias value</param>
static public void SetAliasValue(this IDesktop desktop, string alias, object val)
{
int n = alias.LastIndexOf('.');
string cName = alias.Substring(0, n);
INamedComponent c = desktop[cName];
string alName = alias.Substring(n + 1);
IAlias al = null;
if (c is IObjectLabel)
{
IObjectLabel ol = c as IObjectLabel;
al = ol.Object as IAlias;
}
if (c is IArrowLabel)
{
IArrowLabel ar = c as IArrowLabel;
al = ar.Arrow as IAlias;
}
al[alName] = val;
}
/// <summary>
/// Gets alias value
/// </summary>
/// <param name="desktop">Desktop</param>
/// <param name="alias">The alias name</param>
/// <returns>The alias value</returns>
static public object GetAliasValue(this IDesktop desktop, string alias)
{
int n = alias.IndexOf('.');
string cName = alias.Substring(0, n);
INamedComponent c = desktop[cName];
string alName = alias.Substring(n + 1);
IAlias al = null;
if (c is IObjectLabel)
{
IObjectLabel ol = c as IObjectLabel;
al = ol.Object as IAlias;
}
if (c is IArrowLabel)
{
IArrowLabel ar = c as IArrowLabel;
al = ar.Arrow as IAlias;
}
return al[alName];
}
/// <summary>
/// Gets arrow label from desktop
/// </summary>
/// <param name="desktop">The desktop</param>
/// <param name="name">Arrow name</param>
/// <returns>The arrow label</returns>
static public IArrowLabel GetArrowLabel(this IDesktop desktop, string name)
{
object o = desktop[name];
if (o == null)
{
return null;
}
if (!(o is IArrowLabel))
{
return null;
}
return o as IArrowLabel;
}
/// <summary>
/// Gets associated object of desktop component
/// </summary>
/// <param name="desktop">Desktop</param>
/// <param name="name">Component name</param>
/// <returns>Associated object</returns>
public static object GetAssociatedObject(this IDesktop desktop, string name)
{
INamedComponent comp = desktop[name];
if (comp is IObjectLabel)
{
IObjectLabel lab = comp as IObjectLabel;
return lab.Object;
}
if (comp is IArrowLabel)
{
IArrowLabel lab = comp as IArrowLabel;
return lab.Arrow;
}
return null;
}
/// <summary>
/// Gets associated object that implements the interface
/// </summary>
/// <param name="desktop">Desktop</param>
/// <param name="name">Name of object</param>
/// <returns>The object</returns>
public static T GetAssociatedObject<T>(this IDesktop desktop, string name) where T : class
{
object obj = GetAssociatedObject(desktop, name);
if (!(obj is IAssociatedObject))
{
return null;
}
IAssociatedObject ao = obj as IAssociatedObject;
return CategoryOperations.GetObject<T>(ao);
}
/// <summary>
/// Gets relative object
/// </summary>
/// <typeparam name="T">Type of relative object</typeparam>
/// <param name="obj">This object</param>
/// <param name="name">Object name</param>
/// <returns>Relative object</returns>
public static T GetRelativeObject<T>(this ICategoryObject obj, string name) where T : class
{
IAssociatedObject ao = obj as IAssociatedObject;
INamedComponent nc = ao.Object as INamedComponent;
IDesktop d = nc.Desktop;
return GetAssociatedObject<T>(d, name);
}
/// <summary>
/// Gets source arrows of object
/// </summary>
/// <typeparam name="T">Arrow type</typeparam>
/// <param name="obj">The object</param>
/// <returns>The arrows</returns>
public static T[] GetSourceArrows<T>(this ICategoryObject obj) where T : class
{
List<T> l = new List<T>();
IDesktop d = obj.GetRootDesktop();
ICollection<ICategoryArrow> arr = d.CategoryArrows;
foreach (ICategoryArrow a in arr)
{
ICategoryObject o = a.Source;
if (o == obj)
{
if (a is T)
{
l.Add(a as T);
}
}
}
return l.ToArray();
}
/// <summary>
/// Gets target arrows of object
/// </summary>
/// <typeparam name="T">Arrow type</typeparam>
/// <param name="obj">The object</param>
/// <returns>The arrows</returns>
public static T[] GetTargetArrows<T>(this ICategoryObject obj) where T : class
{
List<T> l = new List<T>();
IDesktop d = obj.GetRootDesktop();
ICollection<ICategoryArrow> arr = d.CategoryArrows;
foreach (ICategoryArrow a in arr)
{
ICategoryObject o = a.Target;
if (o == obj)
{
if (a is T)
{
l.Add(a as T);
}
}
}
return l.ToArray();
}
/// <summary>
/// Push
/// </summary>
/// <param name="collection">collection</param>
public static void Push(this IComponentCollection collection)
{
ICollection<object> coll = collection.AllComponents;
foreach (object o in coll)
{
if (o is IStack)
{
IStack stack = o as IStack;
stack.Push();
}
}
}
/// <summary>
/// Pop
/// </summary>
/// <param name="collection">collection</param>
public static void Pop(this IComponentCollection collection)
{
ICollection<object> coll = collection.AllComponents;
foreach (object o in coll)
{
if (o is IStack)
{
IStack stack = o as IStack;
stack.Pop();
}
}
}
/// <summary>
/// Throws exception linked with object
/// </summary>
/// <param name="o">The linked object</param>
/// <param name="message">Exception message</param>
public static void Throw(this object o, string message)
{
o.Throw(new Exception(message));
}
/// <summary>
/// Throws exception linked with object
/// </summary>
/// <param name="o">The linked object</param>
/// <param name="exception">The parent exception</param>
public static void Throw(this object o, Exception exception)
{
if ((exception is DiagramException) | (exception is AssociatedException))
{
throw exception;
}
if (o == null)
{
throw exception;
}
if (o is INamedComponent)
{
INamedComponent n = o as INamedComponent;
throw new DiagramException(exception, n);
}
if (o is IAssociatedObject)
{
IAssociatedObject ass = o as IAssociatedObject;
object ob = ass.Object;
if (ob is INamedComponent)
{
INamedComponent nc = ob as INamedComponent;
throw new DiagramException(exception, nc);
}
}
throw exception;
}
/// <summary>
/// Gets object
/// </summary>
/// <param name="collection">Collection</param>
/// <param name="name">Name</param>
/// <returns>The object</returns>
public static object GetObject(this IComponentCollection collection, string name)
{
ICollection<object> c = collection.AllComponents;
foreach (object o in c)
{
string n = GetName(o, collection);
if (n != null)
{
if (n.Equals(name))
{
return o;
}
}
}
return null;
}
/// <summary>
/// Gets object
/// </summary>
/// <typeparam name="T">Object type</typeparam>
/// <param name="o">Object</param>
/// <returns>The object</returns>
public static T GetObject<T>(this object o) where T : class
{
T t = null;
/// if o is T
if (o is T)
{
// returns o as T
t = o as T;
}
else if (o is IAssociatedObject)
{
t = CategoryOperations.GetObject<T>(o as IAssociatedObject);
}
else if (o is IObjectLabel)
{
IObjectLabel ol = o as IObjectLabel;
t = CategoryOperations.GetObject<T>(ol.Object);
}
else if (o is IArrowLabel)
{
IArrowLabel al = o as IArrowLabel;
t = CategoryOperations.GetObject<T>(al.Arrow);
}
return t;
}
/// <summary>
/// Gets object
/// </summary>
/// <typeparam name="T">Type</typeparam>
/// <param name="collection">Collection</param>
/// <param name="name">Name</param>
/// <returns>The object</returns>
public static T GetObject<T>(this IComponentCollection collection, string name) where T : class
{
return GetObject<T>(GetObject(collection, name));
}
/// <summary>
/// Gets all names of collection
/// </summary>
/// <typeparam name="T">Type</typeparam>
/// <param name="collection">The collection</param>
/// <returns>List of names</returns>
public static List<string> GetAllNames<T>(this IComponentCollection collection) where T : class
{
ICollection<object> c = collection.AllComponents;
List<string> l = new List<string>();
string n = null;
foreach (object o in c)
{
n = GetName(o, collection);
if (n == null)
{
continue;
}
T t = GetObject<T>(o);
if (t != null)
{
l.Add(n);
}
}
return l;
}
/// <summary>
/// Gets all names of collection
/// </summary>
/// <typeparam name="T">Type</typeparam>
/// <param name="collection">The collection</param>
/// <returns>List of names</returns>
public static List<T> GetAll<T>(this IComponentCollection collection) where T : class
{
ICollection<object> c = collection.AllComponents;
List<T> l = new List<T>();
string n = null;
foreach (object o in c)
{
T t = GetObject<T>(o);
if (t != null)
{
if (!l.Contains(t))
{
l.Add(t);
}
}
}
return l;
}
/// <summary>
/// Gets mame of object
/// </summary>
/// <param name="o">The object</param>
/// <param name="collection">The collection</param>
/// <returns>The name</returns>
public static string GetName(this object o, IComponentCollection collection)
{
INamedComponent nc = null;
if (o is INamedComponent)
{
nc = o as INamedComponent;
}
else if (o is IAssociatedObject)
{
IAssociatedObject ao = o as IAssociatedObject;
object ob = ao.Object;
if (ob is INamedComponent)
{
nc = ob as INamedComponent;
}
}
if (nc == null)
{
return null;
}
IDesktop d = collection.Desktop;
if (d == null)
{
return null;
}
return nc.GetName(d);
}
/// <summary>
/// Gets named component of associated object
/// </summary>
/// <param name="obj">The object</param>
/// <returns>Rhe desktop</returns>
public static INamedComponent GetComponent(this IAssociatedObject obj)
{
INamedComponent nc = null;
if (obj is INamedComponent)
{
nc = obj as INamedComponent;
}
else
{
object o = obj.Object;
if (o is INamedComponent)
{
nc = o as INamedComponent;
}
}
return nc;
}
/// <summary>
/// Gets desktop of associated object
/// </summary>
/// <param name="obj">The object</param>
/// <returns>Rhe desktop</returns>
public static IDesktop GetDesktop(this IAssociatedObject obj)
{
INamedComponent nc = GetNamedComponent(obj);
if (nc == null)
{
return null;
}
return nc.Desktop;
}
/// <summary>
/// Gets root desktop of associated object
/// </summary>
/// <param name="obj">The object</param>
/// <returns>Rhe desktop</returns>
public static IDesktop GetRootDesktop(this IAssociatedObject obj)
{
IDesktop d = GetDesktop(obj);
if (d == null)
{
return null;
}
return d.Root;
}
#endregion
#region Private and Internal members
/// <summary>
/// Disposes associated object
/// </summary>
/// <param name="obj">Object to dispose</param>
static internal void DisposeAssociatedObject(object obj)
{
if (obj is IAssociatedObject)
{
IAssociatedObject ao = obj as IAssociatedObject;
object ob = ao.Object;
if (ob is IDisposable)
{
IDisposable d = ob as IDisposable;
d.Dispose();
}
}
RemoveObject(obj);
}
/// <summary>
/// Gets object or arrow
/// </summary>
/// <param name="obj">Prototype</param>
/// <returns>Object or arrow</returns>
private static object GetObject(IAssociatedObject obj)
{
if (!(obj is INamedComponent))
{
return obj;
}
INamedComponent nc = obj as INamedComponent;
if (nc is IObjectLabel)
{
IObjectLabel l = nc as IObjectLabel;
return l.Object;
}
if (nc is IArrowLabel)
{
IArrowLabel l = nc as IArrowLabel;
return l.Arrow;
}
return null;
}
#endregion
}
}