/* Represents an undirected graph.
 * Also contains the vertex class
 * These are not quite traditional graph theory graphs, because they also have
 * cartesian coordinates, and can do some math to ensure planarity is preserved
 * (that is, planarity in the existant layout, not being isomorphic to a
 * planar)
 *
 * Each vertex also contains a 'colour' and a 'score', which are just integers
 * but may be useful for various algorithms
 *
 * fixme: this isn't a terribly *efficient* setup - Vertices don't know about
 * their neighbors, because the 'edge' class handles that instead. This makes
 * walking the tree O(n^2) or so, which is crappy. However, this implementation
 * is *simple* and will do well for small-to-medium graphs, I suspect
 */

#ifndef _GRAPH_H_
#define _GRAPH_H_

#include <list>

using std::list;

class Vertex
{
  public:
    Vertex(int x, int y, int z, int r, int colour = 0, int score = 0);

    int x;
    int y;
    int z;
    int r;
    int colour;
    int score;

    list<Vertex*> neighbors;
};


class Graph
{
 public:
    Graph(bool planar);
    virtual ~Graph();

    list<Vertex*> get_vertices() const { return vertices; }
    list<Vertex*> get_colour(int colour);

    bool point_in_vertex(int x, int y, int z);
    Vertex * vertex_at(int x, int y, int z);
    virtual bool add_vertex(int x, int y, int z, int r, int colour = 0,
			    int score = 0, Vertex* src=NULL);
    void remove_vertex(Vertex* target);

    bool is_planar() const { return planar; }
    void set_planar(bool planar) { this->planar = planar; }

 protected:
    list<Vertex*> vertices;

 private:
    bool vertex_would_overlap(int x, int y, int z, int r);
    bool crosses_edge(Vertex* a, Vertex* b);
    bool planar;
};

#endif