class Graph
{
public:
    Graph();
    Graph(const Graph &g);
    ~Graph();
    void FreeMemory();

    //
    // File IO
    //
    void SaveToFile(const String &filename) const;
    void LoadFromFile(const String &filename);

    void LoadFromImageClusters(const Bitmap &bmp, const Grid<UINT> &clusterIDs);
    
    //
    // Traversal
    //
    void EnumerateAllWalks(UINT length, const Node &start, Vector<Walk*> &walks) const;

    //
    // Accessors
    //
    __forceinline const Vector<Node>& nodes() const
    {
        return _nodes;
    }
    __forceinline Vector<Node>& nodes()
    {
        return _nodes;
    }
    __forceinline const Vector<Edge>& edges() const
    {
        return _edges;
    }
    __forceinline Vector<Edge>& edges()
    {
        return _edges;
    }
    __forceinline String& Name()
    {
        return _name;
    }
    __forceinline const String& Name() const
    {
        return _name;
    }

    //
    // Static members
    //
    static void LoadGraphsFromFile(const String &filename, Vector<Graph*> &graphs);

private:
    void Finalize();
    Edge* FindEdge(UINT n0, UINT n1);

    Vector<Node> _nodes;
    Vector<Edge> _edges;
    String _name;
};