internal static void ExtractNodesAndConnections(string art, IDictionary<char, TaskNode> nodes, Flow f)
{
char[,] artChars = ExtractMatrix(art);
f.Art = artChars;
List<PositionedTask> tasks = GetTasks(artChars, nodes);
List<PositionedConnection> connections = new List<PositionedConnection>();
foreach (var task in tasks)
{
f.AddNode(task.task, task.pos);
}
int totalUsed = 0;
foreach (var task in tasks)
{
PositionedConnection conn = FindConnectionEnd(task, artChars);
if (conn != null)
{
while (ExpandConnection(conn, artChars)) { };
Position startPos = conn.track[conn.track.Count-1];
char start = artChars[startPos.x, startPos.y];
conn.startPoint = new PositionedTask() { task = nodes[start], pos = startPos };
int outNr = GetStreamNumber(conn, artChars);
BoundedBlockingQueue stream = f.ConnectNodes(conn.startPoint.task, conn.endPoint.task, outNr);
stream.InPoint = conn.track[1];
connections.Add(conn);
totalUsed += conn.track.Count - 1;
}
}
foreach (Position p in GetJoinPosition(artChars))
{
PositionedConnection joinedWith = connections.Where((PositionedConnection c)=> c.track.Contains(p)).Single();
List<PositionedConnection> conns = FindConnectionJoin(p, artChars);
foreach (var conn in conns)
{
conn.endPoint = joinedWith.endPoint;
while (ExpandConnection(conn, artChars)) { };
Position startPos = conn.track[conn.track.Count - 1];
char start = artChars[startPos.x, startPos.y];
conn.startPoint = new PositionedTask() { task = nodes[start], pos = startPos };
int outNr = GetStreamNumber(conn, artChars);
f.ConnectNodeByJoin(conn.startPoint.task, conn.endPoint.task, outNr);
connections.Add(conn);
totalUsed += conn.track.Count - 1; // both the end and begin point are already counted
}
}
// after finding all connections, the total number of +, |, -, digits and letters should sum to the
// total tracks + nr of tasks
int usedSpots = art.ToCharArray().Count(c => { return "1234567890abcdefghijklmnopqrstuvwxyz-+#|<>^V".Contains(c); });
if (usedSpots != totalUsed + tasks.Count)
{
throw new InvalidOperationException("loose ends!");
}
}