#include "Node.h"

using namespace std;

typedef pair<Node*, int> Neighbor;

/* Default constructor*/
Node::Node():
	ID(0),
	layerNum (0),
	name(""),
    position(0),
    value(0)
	{}

/*Customized Constructor*/
Node::Node(int id, int layer):
	ID (id),
	layerNum (layer),
	name(""),
	value(0),
    position(id),
    positionChanged(false)
	{}
	
Node::Node(int id, int layer, string nm):
	ID (id),
	layerNum (layer),
	name(nm),
	value(0),
    position(id),
    positionChanged(false)
	{}

/*add a neighbor*/
void Node::addNeighbor(Neighbor neighbor)
{
	Node::neighbors.Append(neighbor);
}

/*compare with another Node*/
bool Node::compareTo(Node& other)
{
	bool result = false;
	if(ID == other.ID && layerNum == other.layerNum)
        result = true;
	return result;
}

/*set position*/
void Node::setPosition(int pos)
{       if(position != pos) positionChanged = true;
	position = pos;
}

bool Node::hasNeighbor(Node* node)
{
   bool result = false;
   const ListElement<Neighbor> * finger = neighbors.Head();
   while (finger != NULL){
   	   Neighbor nb = finger->Datum();
   	   Node* n = nb.first;
   	   if(compareTo(*n)){
   	   	 result = true;
   	   	 break;
   	   }
   	   finger = finger->Next();
   }
   return result;
}

Neighbor
Node::findNeighbor(Node* node)
{
   Neighbor result(NULL,0);
   if(node <= 0) return result;
   //if(node->name == "0") return result;
   //cerr<<"SS::fn Node to be found = "<<endl;
   //cerr<<node->name << endl;
   const ListElement<Neighbor> * finger = neighbors.Head();
   while (finger != NULL){
   	   Neighbor nb = finger->Datum();
   	   Node* n = nb.first;
   	   if(n != 0 && node != 0){
	   	   //cerr<<"SS::fn Node n = "<<n<<endl;
   		   if(n->name == node->name ){
   	   		 result = nb;
   	   		// cerr<<" result = "<<nb.first->name<<" "<<nb.second<<endl;
   	   		 break;
   	   		}
   	   }
   	   else{
   	   }
   	   finger = finger->Next();
   }
   return result;
}

/*set position based on barycenter heuristic*/
void Node::setPositionBary()
{
	//cerr<<"inside node pos bary"<<endl;
	int length = neighbors.size;
	//cerr<<"NOde::spb. num nebors "<<length<<endl;
	int i=0;
	int weights =0;
	int sum =0;
	int mean =0;
	const ListElement<Neighbor>* temp = neighbors.Head();
	while(i < length){
		int weight;
		if(layerNum == 1) 
		     weight = 1;
        Neighbor nb = temp->Datum();		     
		Node* node = nb.first;
		if(node->layerNum == 1 )
		    weight = nb.second;
		weights = weights+weight;
		sum = sum+weight*node->position;
		temp = temp->Next();
		i++;
	}
	if(length != 0 && weights != 0)
	   mean = sum/weights;
    int old = position;
    position = mean;
    if(old != position)
       positionChanged = true;
    else
       positionChanged = false;
    //cerr<<"leaving node pos bary"<<endl;
}
bool Node::operator ==(Node& other)
{
    return compareTo(other);
}

void Node::setValue(int val){
	value = val;
}

int Node::getValue(){
	return value;
}
