private void CleanupExistingConnection(CoordPair cp)
        {
            Connection forwardConn;
            Connection reverseConn;
            if (m_connections.TryGetValue(cp, out forwardConn))
            {
                if (forwardConn != Connection.None &&
                    m_connections.TryGetValue(cp.Reverse, out reverseConn))
                {
                    if (forwardConn != reverseConn)
                    {
                        HashSet<String> srcQualifiers = m_qualifiers[cp.SourceCoord];
                        HashSet<String> dstQualifiers = m_qualifiers[cp.DestCoord];

                        // testing to see if both sets of qualifiers are the same
                        int targetSize = Math.Max(srcQualifiers.Count, dstQualifiers.Count);
                        int count = 0;
                        IEnumerable<String> intersect = srcQualifiers.Intersect(dstQualifiers);
                        foreach (String s in intersect)
                        {
                            ++count;
                        }

                        if (targetSize == count)
                        {
                            // qualifiers are the same, so no short circuit - connect them
                            this.ConnectOneWay(cp.DestCoord, cp.SourceCoord, forwardConn);
                        }
                        else
                        {
                            // would cause a short circuit, delete the connection
                            this.ConnectOneWay(cp.SourceCoord, cp.DestCoord, Connection.None);
                        }
                    }
                }
            }
        }
 public Connection? GetConnection(Point sourceCoord, Point destCoord)
 {
     CoordPair cp = new CoordPair(sourceCoord, destCoord);
     Connection conn;
     if (m_connections.TryGetValue(cp, out conn))
     {
         return conn;
     }
     return null;
 }
        public void ConnectOneWay(Point sourceCoord, Point destCoord, Connection connection)
        {
            if (!m_qualifiers.ContainsKey(sourceCoord))
            {
                throw new InvalidOperationException("Cannot connect an unknown screen to something else");
            }

            CoordPair cp = new CoordPair(sourceCoord, destCoord);
            CoordPair reverse = cp.Reverse;

            // undo hash from connection being overwritten
            Connection oldValue;
            if (m_connections.TryGetValue(cp, out oldValue))
            {
                m_hashCode ^= getConnectionHashCode(cp.SourceCoord, cp.DestCoord, oldValue);
            }

            m_connections[cp] = connection;
            m_hashCode ^= getConnectionHashCode(cp.SourceCoord, cp.DestCoord, oldValue);

            if (m_openConnections.TryGetValue(reverse, out oldValue))
            {
                //if (oldValue == connection)
                //{
                    // this could be circumventing the ordering.
                    // to be safe, remove both directions of the connection.
                    m_openConnections.Remove(reverse);
                    m_connections.Remove(reverse);
                    m_hashCode ^= getConnectionHashCode(reverse.SourceCoord, reverse.DestCoord, oldValue);

                    m_connections.Remove(cp);
                    m_hashCode ^= getConnectionHashCode(cp.SourceCoord, cp.DestCoord, oldValue);
                //}
                //else
                //{
                //    throw new InvalidOperationException("Not currently supported to have parallel connections of different types");
                //}
            }
            else if (connection != Connection.None && !m_connections.ContainsKey(reverse))
            {
                m_openConnections.Add(cp, connection);
            }
        }
        public void ConnectTwoWay(Point sourceCoord, Point destCoord, Connection connection)
        {
            if (!m_qualifiers.ContainsKey(sourceCoord) ||
                !m_qualifiers.ContainsKey(destCoord))
            {
                throw new InvalidOperationException("Cannot connect an unknown screen to something else");
            }

            if (connection != Connection.None)
            {
                m_qualifiers[destCoord].UnionWith(m_qualifiers[sourceCoord]);
            }

            CoordPair forward = new CoordPair(sourceCoord, destCoord);
            CoordPair reverse = forward.Reverse;

            // undo hash from connections being overwritten
            Connection oldValue;
            if (m_connections.TryGetValue(forward, out oldValue))
            {
                m_hashCode ^= getConnectionHashCode(forward.SourceCoord, forward.DestCoord, oldValue);
            }
            if (m_connections.TryGetValue(reverse, out oldValue))
            {
                m_hashCode ^= getConnectionHashCode(reverse.SourceCoord, reverse.DestCoord, oldValue);
            }

            m_connections[forward] = connection;
            m_connections[reverse] = connection;
            m_hashCode ^= getConnectionHashCode(forward.SourceCoord, forward.DestCoord, connection);
            m_hashCode ^= getConnectionHashCode(reverse.SourceCoord, reverse.DestCoord, connection);

            m_openConnections.Remove(forward);
            m_openConnections.Remove(reverse);
        }
        public void AddScreen(ScreenConstructionParameters scp, string missionNodeID)
        {
            Point location = scp.Location;
            if (m_screenParameters.ContainsKey(location))
            {
                throw new InvalidOperationException("SpaceImpl already has that screen");
            }
            m_screenParameters.Add(location, scp);
            m_qualifiers.Add(location, new HashSet<String>());
            m_qualifiers[location].Add(missionNodeID);

            m_hashCode ^= getAreaHashCode(location);

            Point north = DirectionUtils.Move(location, Direction.Up);
            Point south = DirectionUtils.Move(location, Direction.Down);
            Point west = DirectionUtils.Move(location, Direction.Left);
            Point east = DirectionUtils.Move(location, Direction.Right);

            CoordPair fromNorth = new CoordPair(north, location);
            CoordPair fromSouth = new CoordPair(south, location);
            CoordPair fromWest = new CoordPair(west, location);
            CoordPair fromEast = new CoordPair(east, location);

            // checks for non-wall connections into this area.  those need to
            // be dealt with, preferably by: seeing if the old connection would cause a short
            // circuit, if so delete it, otherwise add it to this one.
            CleanupExistingConnection(fromNorth);
            CleanupExistingConnection(fromSouth);
            CleanupExistingConnection(fromWest);
            CleanupExistingConnection(fromEast);

            // TODO - figure out whether to add Wall connections adjacent to screen or not
            //throw new NotImplementedException();
        }