// 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: 31-Jul-1996
// 

#ifndef Attribute_h
#define Attribute_h

#include <LINK/basic/general.h>
/////////////#include <LINK/interface/interface.h>
#include <LINK/basic/List.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 <class Item>
class AttributeElementOps {
public:
	ostream& displayItem(ostream& os,  const Item& i) const;
};

//***********************************************************************
// This following specializations of this class allow attributes to be
// saved in such a way that the parser will recognize the type of value
// upon reloading the graph.  The method definitions are found in 
// graphTemplate.cc
//***********************************************************************
/*
class AttributeElementOps<String> {
public:
	ostream& displayItem(ostream& os,  const String& i) const;
};

class AttributeElementOps<float> {
public:
	ostream& displayItem(ostream& os,  const float& i) const;
};

class AttributeElementOps<double> {
public:
	ostream& displayItem(ostream& os,  const double& i) const;
};
*/
//***********************************************************************


//
// 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)	{ return _value = v; }
    ostream&		display(ostream& stream) const;

private:
    Item		_value;
};

template <class Item> int newAttribute(Graph*, String name, const Item&);
template <class Item> int setAttribute(GraphObject*, String name, const 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_TEMPLATE
#include <LINK/graph/Attribute.cc>
#endif


#endif
