using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace U.Graph
{
    public class SubGraph
    {
        private int n;
        private bool[] nodeClosed;  // open or close
        private bool[,] arcClosed;  // node x node, open or close

        public SubGraph(int n)
        {
            this.n = n;
            this.nodeClosed = new bool[n];
            this.arcClosed = new bool[n, n];
        }


        public void closeNode(int nodeIndex, Graph graph)
        {
            nodeClosed[nodeIndex] = true;
            Node vertex = graph.getNode(nodeIndex);
            int[] outEdgeIndices = vertex.getOutArcIndices();
            int[] inEdgeIndices = vertex.getInArcIndices();
            foreach (int e in outEdgeIndices)
            {
                int v = graph.getArc(e).getToIndex();
                closeArc(nodeIndex, v);
                closeArc(v, nodeIndex);
            }
            foreach (int e in inEdgeIndices)
            {
                int v = graph.getArc(e).getFromIndex();
                closeArc(nodeIndex, v);
                closeArc(v, nodeIndex);
            }
        }
        public void closeArc(int fromIndex, int toIndex) { arcClosed[fromIndex, toIndex] = true; }
        public void closeNodes(List<int> vertexIndices, Graph graph) { foreach (int vertexIndex in vertexIndices) { closeNode(vertexIndex, graph); } }
        public void closePath(List<int> pathAsNodeIndices)
        {
            for (int i = 1; i < pathAsNodeIndices.Count; i++)
            {
                int fromIndex = pathAsNodeIndices[i - 1];
                int toIndex = pathAsNodeIndices[i];
                closeArc(fromIndex, toIndex);
            }
        }

        public bool isNodeClosed(int vertexIndex) { return nodeClosed[vertexIndex]; }
        public bool isArcClosed(int fromIndex, int toIndex) { return arcClosed[fromIndex, toIndex]; }
        public void restore() { this.nodeClosed = new bool[n]; ; this.arcClosed = new bool[n, n]; ; }

        // COMMON
        public SubGraph clone()
        {
            SubGraph subGraph = new SubGraph(this.n);
            for (int i = 0; i < this.n; i++)
            {
                if (this.nodeClosed[i]) { subGraph.nodeClosed[i] = true; }
                for (int j = 0; j < this.n; j++) { if (this.arcClosed[i, j]) { subGraph.arcClosed[i, j] = true; } }
            }
            return subGraph;
        }

    }
}
