/* This software is distributed under the Lesser General Public License */
#ifndef GT_ATTRIBUTE_BASE_H
#define GT_ATTRIBUTE_BASE_H

//
// Attribute_Base.h
//
// This file defines the classes
//   GT_Attribute_Base
//
//------------------------------------------ CVS
//
// CVS Headers -- The following headers are generated by the CVS
// version control system. Note that especially the attribute
// Author is not necessarily the author of the code.
//
// $source: /home/br/CVS/graphlet/src/gt_base/Attributes.h,v $
// $Author: himsolt $
// $Revision: 1.3 $
// $Date: 1999/03/05 20:42:54 $
// $Locker:  $
// $State: Exp $
//
//------------------------------------------ CVS
//
// (C) University of Passau 1995-1999, Graphlet Project
//


//////////////////////////////////////////
//
// GT_Attribute_Base
//
//////////////////////////////////////////


class GT_List_of_Attributes;


class GT_Attribute_Base
{
    GT_BASE_CLASS (GT_Attribute_Base);

protected:
    int the_flags;
    GT_Key the_key;
	
public:
    enum {
	the_is_safe = (1 << 0),
	the_is_complex = (the_is_safe << 1),
	the_is_int     = (the_is_complex << 1),
	the_is_double  = (the_is_int << 1),
	the_is_string  = (the_is_double << 1),
	the_is_list    = (the_is_string << 1)
    } Attribute_Flag;
	
public:

    GT_Attribute_Base (const GT_Key key, const int flags);
    virtual ~GT_Attribute_Base();
	
    inline GT_Key key() const;
    
    static void print (ostream& out, const GT_Key& k);
    virtual void print (ostream& out) const;

    // virtual copy constructor
    void copy (const GT_Attribute_Base* from, GT_Copy type);
    virtual GT_Attribute_Base* clone (GT_Copy type) const = 0;

    // Flags
    inline bool safe() const; // compatibility only; use is_safe
    void set_safe();

    inline bool is_safe() const;
    inline bool is_complex() const;
    inline bool is_int() const;
    inline bool is_double() const;
    inline bool is_string() const;
    inline bool is_list() const;

    // Value extraction
    virtual bool value_int (int& i) const;
    virtual bool value_double (double& d) const;
    virtual bool value_string (string& s) const;
    virtual bool value_list (GT_List_of_Attributes*& l) const;
    virtual bool value_list (const GT_List_of_Attributes*&x) const;

    // Printing optimization: print only if you must
    virtual bool do_print () const;
};

ostream& operator<< (ostream &out, const GT_Attribute_Base* v);



//////////////////////////////////////////
//
// Inline Definitions
//
//////////////////////////////////////////


inline GT_Key GT_Attribute_Base::key() const
{
    return the_key;
};


inline bool GT_Attribute_Base::safe() const
{
    return (the_flags & the_is_safe) ? true : false ;
}


inline bool GT_Attribute_Base::is_safe() const
{
    return (the_flags & the_is_safe) ? true : false ;
}


inline bool GT_Attribute_Base::is_complex() const {
    return (the_flags & the_is_complex) ? true : false ;
}


inline bool GT_Attribute_Base::is_int() const {
    return (the_flags & the_is_int) ? true : false ;
}


inline bool GT_Attribute_Base::is_double() const {
    return (the_flags & the_is_double) ? true : false ;
}


inline bool GT_Attribute_Base::is_string() const {
    return (the_flags & the_is_string) ? true : false ;
}


inline bool GT_Attribute_Base::is_list() const {
    return (the_flags & the_is_list) ? true : false ;
}



//////////////////////////////////////////
//
// Printing Attributes
//
//////////////////////////////////////////


extern void GT_print (ostream&, const int);
extern void GT_print (ostream&, const double);

extern void GT_print (ostream&, const string& s);
extern void GT_print (ostream&, const GT_Key key); // Treated as string

template<class T> void GT_print (ostream& out, const GT_Key key, const T& t)
{
    GT_Attribute_Base::print (out, key);
    GT_print (out, t);
}

#endif
