/**------------------------------------------------------------------------
* @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: Marcos Da Silva and Diego Macrini
* 
* $Log: SGDistMeasurer.h,v $
* Revision 1.1  2002/06/10 18:42:12  dmac
* New class added.
*
*
*-----------------------------------------------------------------------*/

#ifndef __SG_DIST_MEASURER_H__
#define __SG_DIST_MEASURER_H__

#include "ShockGraph.h"

namespace dml {

typedef DistMeasurerT<ShockGraph, SGNode> SGDistMeasurer;

class SGDistMeasurer1: public SGDistMeasurer
{
	// The following integers will be the relative weights
	// that will be given to the 1st and 2nd level of matching.
	double w1, w2;
	
	virtual double CompDistance() const;
	
public:
	SGDistMeasurer1() { w1 = .7; w2 = 1 - w1; }	
	void SetWeights(double level1Weight, double level2Weight);
	
private:
	double NodeDistanceLevel2(leda_node a, leda_node b) const;
	
	double rule1(leda_node a, leda_node b) const;
	double rule2(leda_node a, leda_node b) const;
	double rule3(leda_node a, leda_node b) const;
	double rule4(leda_node a, leda_node b) const;
	double rule5_6(leda_node a, leda_node b) const;
	
	double NodeDistanceLevel1() const;
	
	double ElongationDiff() const;
	double SweepContrastDiff() const;
	double TaperDiff() const;
	double AccelerationDiff() const;
	double BendDiff() const;
	
	double AverageRadius(const SGNode *u) const;
	double Length(const SGNode *u) const;
	double Elongation(const SGNode *u) const;
	double SweepContrast(const SGNode *u) const;
	double Acceleration(const SGNode *u) const;
	double Bend(const SGNode *u) const;
	double Taper(const SGNode *u) const;
};

class SGDistMeasurer2: public SGDistMeasurer
{	
	virtual double CompDistance() const;

	//int NeighborsCount(leda_node v, int nNodeType) const;
	//NODE_ROLE NodeRole(leda_node v) const;
	//double ComputeScale(leda_node u, const ShockGraph& from, leda_node v) const;
};

class SGDistMeasurer3: public SGDistMeasurer
{	
	virtual double CompDistance() const;
	void LogResults(const ModelFit& m1, const ModelFit& m2,
		POINTS g1Pts, POINTS g2Pts, bool bReverseOrder) const;
};

} //namespace dml

#endif //__SG_DIST_MEASURER_H__
