
#ifndef IOSTREAM_H
#include <iostream>
#endif

#ifndef ELOLMESSAGE_H
#include <ethlolmsg.h>
#endif

#include "../../../cpp_common/constants.h"

#include <IPCInterface.h>


using namespace std;

IPCInterface::~IPCInterface(){}

IPCInterface::IPCInterface(string IPAddress,int Port){
	this->hostIpAddress = IPAddress;
	this->hostPortNo = Port;

	resourceRequestData[0] = 0; resourceRequestData[1] = 0; resourceRequestData[2] = 0;
	currentSenderID = 0;
}

void IPCInterface::InitializeServer(){
	cout << "Init IPC Server Process" << endl;
	ipc.SetCallback(ServerConnection, (void*)this);
	ipc.Start(hostIpAddress.c_str(), hostPortNo, true);
}


void IPCInterface::SendRobotPosition(const char* addr, int X, int Y, int A, int worksite1Id, int worksite1X, int worksite1Y, int portionId, int resourceReceived, int resourceLeft, int globalTime) {
	int DataArray[10];
	DataArray[0] = X;
	DataArray[1] = Y;
	DataArray[2] = A;
	DataArray[3] = worksite1Id;
	DataArray[4] = worksite1X;
	DataArray[5] = worksite1Y;
	DataArray[6] = portionId;
	DataArray[7] = resourceReceived;
	DataArray[8] = resourceLeft;
	DataArray[9] = globalTime;


	std::cout << "send vicon data to " << addr << " t=" << DataArray[9];
	std::cout << " X=" << DataArray[0] << " Y=" << DataArray[1] << " A=" << DataArray[2];
	std::cout	<< " W1ID=" << DataArray[3] << " W1X=" << DataArray[4] << " W1Y=" << DataArray[5];
	std::cout << " portionId= " << DataArray[6] << " resource=" << DataArray[7] << " left=" << DataArray[8];
	std::cout<< std::endl;


	ipc.SendData(inet_addr(addr),IPC::VICON_DATA, (uint8_t*)DataArray, sizeof(int)*10);
}

void IPCInterface::SendRobotCommunication(const char* addr, int worksiteId, int worksiteX, int worksiteY, int recruiterId) {
	int DataArray[4];
	DataArray[0] = worksiteId;
	DataArray[1] = worksiteX;
	DataArray[2] = worksiteY;
	DataArray[3] = recruiterId;

	std::cout << "send comm data to " << addr <<
	std::cout << " : wId = " << DataArray[0] << " wX=" << DataArray[1] << " wY=" << DataArray[2] << " recruiterId=" << DataArray[3];
	std::cout<< std::endl;


	ipc.SendData(inet_addr(addr),IPC::ROBOT_COMM, (uint8_t*)DataArray, sizeof(int)*4);

}


/** 
    Server Callback : This Function is exectured every
    time the server receives a msg
 */
void IPCInterface::ServerConnection(const ELolMessage*msg, void *conn, void *ptr){

  IPCInterface *classpointer = (IPCInterface*)ptr;
  IPC::Connection * connectionpointer = (IPC::Connection*)conn;

  // We retrieve the last byte from the Sender's IP Address
  classpointer->currentSenderID = (connectionpointer->addr.sin_addr.s_addr >> (24) & 0xFF);

  switch(msg->command) {
  	  case IPC::RESOURCE_REQUEST: {
  		  memcpy(classpointer->resourceRequestData,msg->data,msg->length);

  		  //-- put the sender id to the front
  		  classpointer->resourceRequestData[2] = classpointer->resourceRequestData[1];
  		  classpointer->resourceRequestData[1] = classpointer->resourceRequestData[0];
  		  classpointer->resourceRequestData[0] = connectionpointer->addr.sin_addr.s_addr >> (24) & 0xFF;
  	  } break;

  	  case IPC::INFO_EVENT_REPORT: {
  		  memcpy(classpointer->infoEventReportData,msg->data,msg->length);

  		  //-- put the sender id to the front
  		  classpointer->infoEventReportData[4] = classpointer->infoEventReportData[3];
  		  classpointer->infoEventReportData[3] = classpointer->infoEventReportData[2];
  		  classpointer->infoEventReportData[2] = classpointer->infoEventReportData[1];
  		  classpointer->infoEventReportData[1] = classpointer->infoEventReportData[0];
  		  classpointer->infoEventReportData[0] = connectionpointer->addr.sin_addr.s_addr >> (24) & 0xFF;
  	  } break;

  	  case IPC::ROBOT_COMM: {
  		  memcpy(classpointer->robotCommData,msg->data,msg->length);

  		  //-- put the sender id to the front
  		  classpointer->robotCommData[3] = classpointer->robotCommData[2];
  		  classpointer->robotCommData[2] = classpointer->robotCommData[1];
  		  classpointer->robotCommData[1] = classpointer->robotCommData[0];
  		  classpointer->robotCommData[0] = connectionpointer->addr.sin_addr.s_addr >> (24) & 0xFF;
  	  } break;
      
  	  default:
  		  break;
    }
}


int* IPCInterface::GetResourceRequestArray(){
	return resourceRequestData;
}

int* IPCInterface::GetInfoEventReportArray(){
	return infoEventReportData;
}

int* IPCInterface::GetRobotCommDataArray(){
	return robotCommData;
}

int* IPCInterface::GetCurrentSenderID(){
	return &currentSenderID;
}







