/*
 * Distance.h
 *
 *  Created on: 20-may-2010
 *      Author: Pedrete
 */

#ifndef DISTANCE_H_
#define DISTANCE_H_

#include <omnetpp.h>
#include "FindModule.h"
#include "ExtendedAddress.h"
#include "ExtendedConstSpeedMobility.h"

class Distance {

public:

	static double getDistanceByMacAddr(int macSrcAddr, int macDstAddr)
	{
		ExtendedConstSpeedMobility* srcMobility = FindModule<ExtendedConstSpeedMobility*>::findSubModule(simulation.getModule(macSrcAddr)->getParentModule());
		ExtendedConstSpeedMobility* dstMobility = FindModule<ExtendedConstSpeedMobility*>::findSubModule(simulation.getModule(macDstAddr)->getParentModule());

		double d = srcMobility->getMove().getPositionAt(simTime()).distance(dstMobility->getMove().getPositionAt(simTime()));
		EV << "Distance between node[" << simulation.getModule(macSrcAddr)->getParentModule()->getIndex() << "] - node[" << simulation.getModule(macDstAddr)->getParentModule()->getIndex() << "] = " << d << endl;

		return d;
	}

public:

	static double getDistanceByNetwAddr(int netwSrcAddr, int netwDstAddr)
	{
		ExtendedConstSpeedMobility* srcMobility = FindModule<ExtendedConstSpeedMobility*>::findSubModule(simulation.getModule(netwSrcAddr)->getParentModule());
		ExtendedConstSpeedMobility* dstMobility = FindModule<ExtendedConstSpeedMobility*>::findSubModule(simulation.getModule(netwDstAddr)->getParentModule());

		double d = srcMobility->getMove().getPositionAt(simTime()).distance(dstMobility->getMove().getPositionAt(simTime()));
		EV << "Distance between node[" << simulation.getModule(netwSrcAddr)->getParentModule()->getIndex() << "] - node[" << simulation.getModule(netwDstAddr)->getParentModule()->getIndex() << "] = " << d << endl;

		return d;
	}

public:

	static double getDistanceBSByMacAddr(int macSrcAddr)
	{
		ExtendedConstSpeedMobility* srcMobility = FindModule<ExtendedConstSpeedMobility*>::findSubModule(simulation.getModule(macSrcAddr)->getParentModule());
		ExtendedConstSpeedMobility* bsMobility  = FindModule<ExtendedConstSpeedMobility*>::findSubModule(simulation.getSystemModule()->getSubmodule("baseStation"));

		double d = srcMobility->getMove().getPositionAt(simTime()).distance(bsMobility->getMove().getPositionAt(simTime()));
		EV << "Distance between node[" << simulation.getModule(macSrcAddr)->getParentModule()->getIndex() << "] - BS = " << d << endl;

		return d;
	}

public:

	static double getAverageDistanceMacAddr(int macSrcAddr)
	{
		ExtendedConstSpeedMobility* srcMobility = FindModule<ExtendedConstSpeedMobility*>::findSubModule(simulation.getModule(macSrcAddr)->getParentModule());
		ExtendedConstSpeedMobility* dst;

		double averageDistance = 0;
		int numNodes = simulation.getSystemModule()->par("numNodes");

		for(int i=0; i<numNodes; i++)
		{
			dst = FindModule<ExtendedConstSpeedMobility*>::findSubModule(simulation.getSystemModule()->getSubmodule("node", i));
			averageDistance += srcMobility->getMove().getPositionAt(simTime()).distance(dst->getMove().getPositionAt(simTime()));
		}

		averageDistance = averageDistance/numNodes;

		EV << "Average distance from node[" << simulation.getModule(macSrcAddr)->getParentModule()->getIndex() << "] = " << averageDistance << endl;

		return averageDistance;
	}
};

#endif /* DISTANCE_H_ */
