// Copyright (C) 1996 DIMACS Center, Rutgers, The State University of New Jersey
// Author(s): Patricia K. Fasel (Los Alamos Nat. Lab.)

// This software is copyrighted by the DIMACS Center at Rutgers, The State
// University of New Jersey.  IT IS PROVIDED AS IS, AND THE AUTHORS, DIMACS, AND
// RUTGERS, THE STATE UNIVERSITY OF NEW JERSEY  DISCLAIM
// ALL LIABILITY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
// DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

// THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
// IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
// NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
// MODIFICATIONS.

// The authors hereby grant permission to use, copy, modify, distribute,
// and license this software and its documentation for any purpose, provided
// that existing copyright notices are retained in all copies and that this
// notice is included verbatim in any distributions. No written agreement,
// license, or royalty fee is required for any of the authorized uses.
// Modifications to this software may be copyrighted by their authors
// and need not follow the licensing terms described here, provided that
// the new terms are clearly indicated on the first page of each file where
// they apply.

// Last File Update: 31-Jul-1996
// 

#include <iostream.h>
#include <LINK/graph/Attribute.h>
#include <LINK/graph/Graph.h>
#include <LINK/graph/Vertex.h>
#include <LINK/graph/Edge.h>


//
// delete the attribute from the manager
//
int
deleteAttribute(Graph* graph, String name)
{
    AttributeBase* attribute = graph->getAttr(name);
    if (!attribute) {
	error(LINK_DELETE_ATTR_FAIL);
	return LINK_DELETE_ATTR_FAIL;
    }
    delete attribute;
    return LINK_OK;
}


int
deleteAttribute(GraphObject* obj, String name)
{
    obj->deleteAttr(name);
    return LINK_OK;
}


//
// reset the attribute value for all graph objects
//
int
resetAttribute(Graph* graph, String name)
{
    // Remove all changed attributes from vertices and edges on this level
    Vertex** vertices = graph->vertexStart();
    int order = graph->order();
    for (int i = 0; i < order; i++) {
	vertices[i]->deleteAttr(name);
    }
    Edge* edge; 
    const MSet<Edge*>& edges = graph->edges();
    Iterator<Edge*> get_edge(&edges);           
    while (get_edge(edge)) {
	edge->deleteAttr(name);
    }

    // Remove all changed attributes from the subgraphs
    List<Vertex*>* supervs;
    Vertex* super_vertex;
    int ok = 
	getAttribute((GraphObject*) graph, "x_supervertices", supervs);
    if (ok == LINK_OK) {
        Iterator<Vertex*> get_vertex(supervs);
        while (get_vertex(super_vertex)) {

            // get the subgraph attached to the supervertex
            Graph* subgraph;
            getAttribute((GraphObject*) super_vertex, "x_subgraph", subgraph);

            // Remove all changed attributes from GraphObjects of graph
            //cout << "removing from " << *subgraph << endl;
            vertices = subgraph->vertexStart();
            int order = subgraph->order();
            for (int i = 0; i < order; i++) {
                vertices[i]->deleteAttr(name);
                //cout << "removing from vertex " << *vertices[i] << endl;
            }
            Edge *edge;
            const MSet<Edge*>& sub_edges = subgraph->edges();
            Iterator<Edge*> get_sub_edge(&sub_edges);          
            while (get_sub_edge(edge)) {
                edge->deleteAttr(name);
                //cout << "removing from edge " << *edge << endl;
            }
        }
    }
    return LINK_OK;
}


//
// print the requested attribute
// in spirit this is like setAttr() and getAttr() in Attribute.cc, but
// is put here because it isn't templated, and will save code
//
void
printAttribute(Graph* graph, String passed_name, AttrCategory passed_cat)
{
    Vertex** vertices = graph->vertexStart();
    Edge *edge;
    const MSet<Edge*>& edges = graph->edges();
    Iterator<Edge*> get_edge(&edges);           
    cout << "Graph " << graph->name() << endl;
    if (passed_cat == GRAPHATTR || passed_cat == ALLATTR)
	graph->printAttr(passed_name);
    else if (passed_cat == VERTEXATTR || passed_cat == ALLATTR) {
	int order = graph->order();
	for (int i=0; i < order; i++)
	    vertices[i]->printAttr(passed_name);
    } else if (passed_cat == EDGEATTR || passed_cat == ALLATTR) {
	while (get_edge(edge))
	    edge->printAttr(passed_name);
    }
}


//
// output the value of an attribute
//
//ostream&
//operator<<(ostream& stream, AttributeBase* passed_attr)
//{
//    passed_attr->display(stream);
//    return stream;
//}
