// Copyright (C) 1996 DIMACS Center, Rutgers, The State University of New Jersey
// Author(s): Jonathan Berry
// 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: 7-Aug-1997
// 
#ifndef Attribute_h
#define Attribute_h
#include <string.h>
#include <LINK/basic/general.h>
/////////////#include <LINK/interface/interface.h>
#include <LINK/basic/List.h>
#include <LINK/graph/AttributeElementOps.h>
//#include <LINK/graph/Graph.h>
class GraphObject;
class Graph;
//
// The static flag will allow the programmer to specify which values
// are deleted when the attribute is deleted.  This feature does not
// work yet, so all dynamically allocated attribute values are 
// currently leaked. - JWB
//
//
// abstract super class for Attribute
//
class AttributeBase {
public:
    AttributeBase(String n=0, Graph *g=0) : _name(n), _graph(g) {}
    //AttributeBase(String n=0, Graph *g=0, int static_flag=LINK_STATIC) 
    //			: _name(n), _graph(g), _static_flag(static_flag) {}
    virtual ~AttributeBase() {}
    String			name()  	  { return _name; }
    //int			static_flag()  	  { return _static_flag; }
    //void			static_flag(int i){ _static_flag = i; }
    virtual AttributeBase*	copy() = 0;	// copy of this attr
    virtual ostream&		display(ostream& stream) const = 0;
    int                         operator<(const AttributeBase& attr) const
                                { return (strcmp(_name, attr._name) < 0); }
    int                         operator==(const AttributeBase& attr) const
                                { return (strcmp(_name, attr._name) == 0); }
    friend ostream&		operator<<(ostream& str, 
					   const AttributeBase& attr)
				{ attr.display(str);  return str; }
    friend class Graph;
    //friend class HyperGraph;
protected:
    //int		_static_flag;
    String		_name;
    Graph*		_graph;
	
};

//***********************************************************************
//
// template Attribute
//
template <class Item>
class Attribute : public AttributeBase, public AttributeElementOps<Item> {
public:
    Attribute(Graph* g, String n, const Item& v);
    Attribute(String n, const Item& v);
    //Attribute(Graph* g, String n, const Item& v, int static_flag=LINK_STATIC);
    //Attribute(String n, const Item& v, int static_flag=LINK_STATIC);
    virtual ~Attribute();
    AttributeBase*	copy();
    Item		value()			{ return _value; }
    Item		value(const Item& v);
    ostream&		display(ostream& stream) const;
private:
    Item		_value;
};
template <class Item> int newAttribute(Graph*, String name, Item);
template <class Item> int setAttribute(GraphObject*, String name, Item);
template <class Item> int getAttribute(GraphObject*, String name, Item&);
//template <class Item> int newAttribute(Graph*, String name, const Item&,
//				      	int static_flag=LINK_STATIC);
//template <class Item> int setAttribute(GraphObject*, String name, const Item&,
//					int static_flag=LINK_STATIC);
//template <class Item> int getAttribute(GraphObject*, String name, Item&);
int  resetAttribute(Graph*, String name);
int  deleteAttribute(Graph*, String name);
int  deleteAttribute(GraphObject*, String name);
void printAttribute(Graph*, String name, AttrCategory);
void displayAttribute(Graph*, String name, AttrCategory);
//#ifdef DEFINE_Attribute_TEMPLATE
#include <LINK/graph/Attribute.cpp>
//#endif

#endif
