#include <iostream>
#include <ogdf/basic/Graph.h>
#include <ogdf/planarlayout/PlanarStraightLayout.h>
#include <ogdf/basic/CombinatorialEmbedding.h>
#include <ogdf/basic/GridLayout.h>
 
int main() {
    // Create a graph
    ogdf::Graph graph;
    auto graphAttributes = ogdf::GraphAttributes(graph);
    // Add nodes to the graph
    //ogdf::node v0 = graph.newNode();
    ogdf::node v1 = graph.newNode();
    ogdf::node v2 = graph.newNode();
    ogdf::node v3 = graph.newNode();
    ogdf::node v4 = graph.newNode();
    ogdf::node v5 = graph.newNode();
    ogdf::node v6 = graph.newNode();
    ogdf::node v7 = graph.newNode();
 
    // Add edges to the graph
    graph.newEdge(v1,v2);
    graph.newEdge(v1,v3);
    graph.newEdge(v1,v4);
    graph.newEdge(v2,v5);
    graph.newEdge(v1,v5);
    graph.newEdge(v4,v6);
    graph.newEdge(v3,v6);
    graph.newEdge(v6,v7);
    graph.newEdge(v3,v7);
    graph.newEdge(v4,v7);
    graph.newEdge(v1,v7);
 
    ogdf::PlanarStraightLayout layout;
    layout.call(graphAttributes);
    ogdf::CombinatorialEmbedding combEmbending = ogdf::CombinatorialEmbedding(graph);
    combEmbending.computeFaces();
 
    auto elem = combEmbending.faces;
    std::vector<std::vector<ogdf::node>> allFaces;
    for (auto &x : elem) {
        auto first = x->firstAdj();
        std::vector <ogdf::node> all;
        for (auto smth : x->entries) {
            auto y = smth;
            all.push_back(y->theNode());
            //std::cout << y->isSource() << ' ';
        }
        allFaces.push_back(all);
    }
 
    std::cout << "SEE\n";
    for (auto i : allFaces) {
        for (auto j : i) std::cout << j->index() << " ";
        std::cout << '\n';
    }
    std::cout << '\n';
 
    // Output the coordinates of each node
    std::vector<std::string> arr;
    for (ogdf::node n : graph.nodes) {
        ogdf::DPoint pos = graphAttributes.point(n);
        std::cout << "Node " << n->index() << " Position: (" << pos.m_x << ", " << pos.m_y << ")" << std::endl;
        arr.push_back(std::to_string(pos.m_x) + " " + std::to_string(pos.m_y));
    }
    for (auto &e: graph.edges) {
        auto nodes = e->nodes();
        auto point1 = graphAttributes.point(nodes[0]);
        auto point2 = graphAttributes.point(nodes[1]);
        std::cout << point1.m_x << " " << point1.m_y << " " << point2.m_x << " " << point2.m_y << '\n';
    }
    for (auto i : arr)
        std::cout << i << '\n';
    return 0;
}