// -*- C++ -*-
//
//  This file is part of Siena, a wide-area event notification system.
//  See http://www.cs.colorado.edu/serl/siena/
//
//  Author: Antonio Carzaniga <carzanig@cs.colorado.edu>
//  See the file AUTHORS for full details. 
//
//  Copyright (C) 1998-2002 University of Colorado
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
//  USA, or send email to serl@cs.colorado.edu.
//
//
// $Id: SimpleGraph.cc,v 1.1 2002/06/12 16:13:42 carzanig Exp carzanig $
//
#include "SimpleGraph.h"

Node & Node::operator = (const Node &n) {
    x = n.x;
    y = n.y;
    image = n.image;
    return *this;
}

inline Node::Node(const Node &n):image(n.image) {
    x = n.x; y = n.y;
}
// inline Node::Node(): x(0), y(0), image(NULL) {}
inline Node::Node(const Image *i, int a, int b): image(i) {
    x = a; y = b;
}

Edge::Edge(NodesTable::iterator s, NodesTable::iterator t):
    source(s), target(t) {};

bool Edge::operator < (const Edge &x) const {
    return (*source).first < (*x.source).first
	|| ((*source).first == (*x.source).first 
	    && (*target).first < (*x.target).first);
}

bool Edge::operator == (const Edge &x) const {
    return (*source).first == (*x.source).first
	&& (*target).first == (*x.target).first;
}

Edge & Edge::operator = (const Edge &x) {
    source = x.source;
    target = x.target;
    return *this;
}

void SGraph::clear() {
    nodes.clear();
    edges.clear();
}

SGraph::n_iterator SGraph::add_node(const string & name, const Image * img,
				    int x, int y) {
    pair<NodesTable::iterator, bool> r;
    r = nodes.insert(NodesTable::value_type(name, Node(img, x, y)));
    return r.first;
}

bool SGraph::connect(const string & name1, const string & name2) {
    SGraph::n_iterator n1;
    SGraph::n_iterator n2;
    if ((n1 = nodes.find(name1)) != nodes.end()
	&& (n2 = nodes.find(name2)) != nodes.end()) {
	return connect(n1, n2);
    } else {
	return false;
    }
}

bool SGraph::connect(SGraph::n_iterator n1, SGraph::n_iterator n2) {
    return edges.insert(Edge(n1,n2)).second;
}

bool SGraph::remove_node(n_iterator n) {
    for(e_iterator i = edges.begin(); i != edges.end();) 
	if (n == (*i).source || n == (*i).target) {
	    edges.erase(i++);
	} else {
	    ++i;
	}
    nodes.erase(n);
    return true;
}

bool SGraph::remove_node(const string & n) {
    n_iterator ni = nodes.find(n);
    if (ni == nodes.end()) return false;
    return remove_node(ni);
}

bool SGraph::disconnect(const string & name1, const string & name2) {
    SGraph::n_iterator n1;
    SGraph::n_iterator n2;
    if ((n1 = nodes.find(name1)) != nodes.end()
	&& (n2 = nodes.find(name2)) != nodes.end()) {
	return 	edges.erase(Edge(n1,n2));
    } else {
	return false;
    }
}

SGraph::n_iterator SGraph::find_node(const Point & p) {
    n_iterator ni;
    GdkRectangle r;
    for(ni = nodes.begin(); ni != nodes.end(); ++ni) {
 	(*ni).second.image->get_rectangle((*ni).second, &r);
	if (p.x >= r.x && p.x < r.x+r.width && 
	    p.y >= r.y && p.y < r.y+r.height) 
	    return ni;
    }
    return ni;
}
