/**------------------------------------------------------------------------
 * @file
 *
 * Copyright 2001 by the University of Toronto (UT).
 *
 *                       All Rights Reserved
 * 
 * Permission to copy and modify this software and its documentation 
 * only for internal use in your organization is hereby granted, 
 * provided that this notice is retained thereon and on all copies.  
 * UT makes no representations as to the suitability and operability 
 * of this software for any purpose.  It is provided "as is" without 
 * express or implied warranty.
 *
 * UT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
 * SHALL UT BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
 * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 *
 * No other rights, including for example, the right to redistribute 
 * this software and its documentation or the right to prepare 
 * derivative works, are granted unless specifically provided in a 
 * separate license agreement.
 *
 * Author: Diego Macrini (dmac@cs.toronto.edu)
 * 
 * $Log: DAGNode.h,v $
 * Revision 1.3  2002/06/10 18:39:14  dmac
 * MAss and dfs index attributes added.
 *
 * Revision 1.2  2002/05/16 22:49:28  dmac
 * Several bugs fixed and a new DAG-derived class added
 *
 * Revision 1.1.1.1  2002/03/10 07:38:07  dmac
 * Imported sources
 *
 *
 *-----------------------------------------------------------------------*/

#ifndef __DAGNODE_H__
#define __DAGNODE_H__

#include <LEDA/core/string.h>
#include <LEDA/graphics/color.h>
#include "SmartArray.h"
#include "SmartPtr.h"
#include "TSV.h"
#include "DMLString.h"
#include "LEDA_issues.h"

typedef dml::String NODE_LABEL;

#define NODE_LBL_DEFAULT_VAL "DLV"

namespace dml {

/*! 
	\brief This class represents a node of an object of class DAG.

	DAGNode is an abstract class intended to provide the basic functionality of 
	a DAG node and to specify which functions must be overloaded (the pure virtual ones).

	At this moment, many functions that could belong to the DAGNode class, such as
	NodeDistance() and so on, are implemented in the DAG class. The reason for this 
	is that some of these functions require information about the neighbours of the 
	node, and that information is contained in the DAG class. However, if a node had 
	a member variable of type leda_node that links it to the associated node in the graph,
	all the above functions could be implemented in the DAGNode class. Remember that given
	a leda_node v, we can retrieve the graph it belongs to by calling graph_of(v). 
	A drawback of this approach would be that we introduce some risk of inconsistency
	because when we move a node from one graph to another, we need to change the
	value of its reference to the leda_node accordingly.

	/see DAG and DAGNodePtr.

*/

class DAGNode
{
	NODE_LABEL			nodeLbl;		//!< Node's label.
	TSV					childrenTSV;	//!< Adj. node's eigen labels.
	double				eigenLbl;		//!< Node's eigen label.

	// Derived values
	double				tsvNorm;		//!< Node TSV's norm
	int					nMass;			//!< Node mass
	int					nLevel;			//!< Node level in the hierarchical structure
	int					nDFSIndex;		//!< Index relative to a depth-first search

	bool				bVisited;		//!< Useful variable for some algorithms
	double 				dAssignedSimilarity; //!< Assigned similarity when matching. Needed for display purpose only

public:
	typedef int label_type;

	DAGNode(NODE_LABEL lbl = NODE_LBL_DEFAULT_VAL);

	DAGNode(const DAGNode& rhs) { DAGNode::operator=(rhs); }

	// Pure virtual functions
	virtual DAGNode* CreateObject() const = 0;	//!< This function is required by the SmartPtr class.

	// Virtual functions
	virtual ~DAGNode() { }					//!< Necessary virtual destructor.
	virtual DAGNode& operator=(const DAGNode& rhs);
	virtual void Clear();
	virtual std::istream& Read(std::istream& is);
	virtual std::ostream& Write(std::ostream& os) const;
	virtual void Print(std::ostream& os = std::cout) const;

	virtual NODE_LABEL GetLblForGraph() const;
	virtual leda_color GetColorForGraph() const;
	virtual int GetShapeForGraph() const;

	virtual void ComputeDerivedValues();

	/// Similarity function for two nodes. 
	//virtual double operator-(const DAGNode& node) = 0;

	// Non-virtual functions

	void Set(NODE_LABEL nl, double el)		{ nodeLbl = nl; eigenLbl = el; }

	void SetNodeLbl(NODE_LABEL lbl)			{ nodeLbl = lbl; }
	NODE_LABEL GetNodeLbl() const			{ return nodeLbl; }

	void SetEigenLbl(double lbl)			{ eigenLbl = lbl; }
	double GetEigenLbl() const				{ return eigenLbl; }

	void SetMass(int m)						{ nMass = m; }
	void SetLevel(int l)					{ nLevel = l; }
	void SetDFSIndex(int i)				   	{ nDFSIndex = i; }

	void SetVisited(bool bVal = true) 		{ bVisited = bVal; }

	//! Sets the node's TSV assosiated with its adjacent nodes.
	void SetChildrenTSV(const TSV& tsv) { childrenTSV = tsv; }

	TSV GetTSV(int nDim) const;
	const TSV& GetTSV()	const				{ return childrenTSV; }
	TSV& GetTSV()							{ return childrenTSV; }

	double GetTSVNorm()	const				{ /*ASSERT(tsvNorm >= 0);*/ return tsvNorm; }
	int GetMass() const						{ return nMass; }
	int GetLevel() const					{ return nLevel; }
	int GetDFSIndex() const					{ return nDFSIndex; }

	bool Visited() const 					{ return bVisited; }
	void SetSimilarity(double s) 			{ dAssignedSimilarity = s; }
	double GetSimilarity() const 			{ return dAssignedSimilarity; }
	
	
	friend std::ostream& operator<<(std::ostream &os, const DAGNode& node) { return node.Write(os); }
	friend std::istream& operator>>(std::istream &is, DAGNode& node)		 { return node.Read(is); }
};

} //namespace dml

//! /see template<class T> SmartPtr.
typedef SmartPtr<dml::DAGNode> DAGNodePtr;

#endif //__DAGNODE_H__
