#include "LeaderElection.hxx"
#include "CatomWorld.hxx"
#include "CatomSim.hxx"
#include <limits.h>
#include "Network.hxx"

CODE_MODULE_DECLARATION( LeaderElection, LeaderElection );

MailboxID leaderElectionMessagingBox = "leaderElectionMessagingBox";

using namespace std;

LeaderElection::LeaderElection(catomID _hostCatom)
:CodeModule(_hostCatom) {
	isLeader = rand() % 2;
}

void LeaderElection::simulationStart() {
  worldPtr->catomHash[hostCatom]->C.mailboxManager.registerHandler(leaderElectionMessagingBox,
		this,
		(msgHandlerPtr)&LeaderElection::leaderMsgHandler);
	//worldPtr->catomHash[hostCatom]->alpha = 180;
}

void LeaderElection::newTick() {
  //Catom *thisCatom = &(worldPtr->catomHash[hostCatom]->C);
  // CODE HERE
}

void LeaderElection::endTick() {
	Catom *thisCatom = &(worldPtr->catomHash[hostCatom]->C);
  Feature* featureMap = thisCatom->getFeatureMap();
	if (isLeader) {
		for (featureID fid = 1; fid <= NUM_FEATURES; fid++)
	   { //send to all neighbors
				LeaderElectionMessage* msg = new LeaderElectionMessage(leaderElectionMessagingBox, 1,hostCatom);
				featureMap[fid].getNetworkAdapter()->sendMessage(msg);
	   }
		worldPtr->catomHash[hostCatom]->red = 255;
	}
	else {
		worldPtr->catomHash[hostCatom]->red = 128;
	}
}

bool LeaderElection::leaderMsgHandler(LeaderElectionMessage* msg) {
	if (isLeader) {
		if (msg->leaderID > hostCatom) {
			isLeader = false;
		}
	}
	if (msg->hopsLeft > 1) {
		Catom *thisCatom = &(worldPtr->catomHash[hostCatom]->C);
	  Feature* featureMap = thisCatom->getFeatureMap();
		for (featureID fid = 1; fid <= NUM_FEATURES; fid++)
		   { //send to all neighbors
					LeaderElectionMessage* msg2 = new LeaderElectionMessage(leaderElectionMessagingBox, msg->hopsLeft -1,msg->leaderID);
					featureMap[fid].getNetworkAdapter()->sendMessage(msg2);
		   }
	}
  return false;
}
