package Graph;

/**
 * Represents a graph using an adjacency matrix, a square matrix used to represent a finite graph.
 * The elements of the matrix indicate whether pairs of vertices are adjacent or not in the graph.
 * <p>
 * This implementation allows for the representation of undirected graphs by marking both symmetric
 * entries in the matrix for each edge. It does not support weighted edges or directed edges.
 */
public class AdjacencyMatrix {

    /**
     * The adjacency matrix, where each cell (i, j) represents the presence (true) or absence (false)
     * of an edge between vertices i and j.
     */
    private boolean adjMatrix[][];

    /**
     * The number of vertices in the graph.
     */
    private int vertexCount;

    /**
     * Initializes a new adjacency matrix to represent a graph with a specified number of vertices.
     * Initially, all cells in the matrix are set to false, indicating no edges between any vertices.
     *
     * @param vertexCount The number of vertices in the graph. This determines the dimensions of the matrix.
     */
    public AdjacencyMatrix(int vertexCount) {
        this.vertexCount = vertexCount;
        adjMatrix = new boolean[vertexCount][vertexCount];
    }

    /**
     * Adds an undirected edge between the specified pair of vertices in the graph. After calling this method,
     * the adjacency matrix will reflect the presence of the edge in both directions, i.e., (i, j) and (j, i).
     *
     * @param i The first vertex of the edge.
     * @param j The second vertex of the edge. If i equals j, this method does nothing, as self-loops are not supported.
     */
    public void addEdge(int i, int j) {
        adjMatrix[i][j] = true;
        adjMatrix[j][i] = true;
    }

    /**
     * Generates a string representation of the adjacency matrix, where each row represents a vertex and each
     * cell in a row represents the presence (1) or absence (0) of an edge to other vertices.
     *
     * @return A string representation of the adjacency matrix, with rows separated by newlines.
     */
    public String toString() {
        StringBuilder s = new StringBuilder();
        for (int i = 0; i < vertexCount; i++) {
            s.append(i + ": ");
            for (boolean j : adjMatrix[i]) {
                s.append((j ? 1 : 0) + " ");
            }
            s.append("\n");
        }
        return s.toString();
    }

    /**
     * Provides access to the raw adjacency matrix.
     *
     * @return The adjacency matrix as a 2D array of booleans.
     */
    public boolean[][] getMatrix() { return adjMatrix; }
}
