/*
 * BaseActionController.h
 *
 *  Created on: 29 Mar 2017
 *      Author: lenka
 */

#ifndef SRC_EPUCK_ACTIONCONTROL_BASEACTIONCONTROLLER_H_
#define SRC_EPUCK_ACTIONCONTROL_BASEACTIONCONTROLLER_H_

#define DEBUG_WORKSITE_PROCESSING 0
#define USE_REMOTE_REPORTING 0

#include <vector>
#include <stdint.h>
#include <fstream>

#include "../../../cpp_common/infoEventReport.h"

class Robot;
class PathPlanner;
class EPuckBoardController;
class Vector2D;
class IPCInterface;


class BaseActionController {

public:

	struct WorksiteInfo {
		int id;
		int posX; // believed position, doesn't have to be accurate
		int posY;

		WorksiteInfo() {
			id = 0;
			posX = -9999;
			posY = -9999;
		}
		WorksiteInfo(int id_, int x_, int y_) {
			id = id_;
			posX = x_;
			posY = y_;
		}
	};



	enum STATE {
		STATE_RESTING = 0,
		STATE_SCOUTING,
		STATE_PROCESSING_WORKSITE,
		STATE_GOING_TO_WORKSITE,
		STATE_RETURN_TO_BASE,
		STATE_RETURN_TO_BASE_UNSUCCESSFUL,
		STATE_RETURN_TO_BASE_UNSUCCESSFUL_BLIND,
		STATE_UNLOADING_RESOURCE,
		STATE_BEE_RECRUITER_WAGGLE_DANCING,
		STATE_BEE_OBSERVING,
		STATE_WATITING_FOR_SERVER
	};


	BaseActionController(Robot* robot_, PathPlanner* pathPlanner_, EPuckBoardController* epuckBoardController_);
	virtual ~BaseActionController();

	virtual STATE ProcessCurrentState(uint64_t timeStamp_);

	Vector2D* GetCurrentNavigationVector() { return currentNavigationVector; }

	bool isCommunicating;

protected:


	Robot* robot;
	PathPlanner* pathPlanner;
	EPuckBoardController* epuckBoardController;


	int randomWalkTimeStep;
	int resourceRequestsCounter;
	int timeGoingToWorksite;

	int timeTillNextScoutAllowed;

	int timeGlobalTimeTheSame;
	int lastGlobalTime;

	double totalResourceCollected;
	double rewardReceived;


	int timeSinceRecruited;
	int recruitedWorksiteId;
	int recruitedWorksiteX;
	int recruitedWorksiteY;
	int recruiterId;

	STATE currentState;
	Vector2D* currentNavigationVector;
	WorksiteInfo targetWorksiteInfo;

	std::ofstream outputFileInfoEvents;

	void SendReportsToServer();
	void NewInfoEventReport(InfoEventReport::TYPE type_, int worksiteId_, int recruiterId_);
	void NewInfoEventReport(int globalTime_, InfoEventReport::TYPE type_, int worksiteId_, int recruiterId_);

	virtual void Scout();
	void ReturnToBase();
	void GoToWorksite();
	virtual void ProcessWorksite();

	virtual void OnWorksiteScouted(int worksiteId_);
	void OnRecruitedToWorksite(int worksiteId_, int worksiteX_, int worksiteY_, int recruiterId_);

	void CalculateWheelVelocitiesForRandomWalk();
	bool GetIsAtWorksite();
	virtual void SetState(STATE state_);
	void AbandonWorksite();
	void OnWorksiteReached();
	void OnUnableToReachWorksite();

	void ProcessRecruitmentSignals();
	virtual void OnUnloadResourceDone();
	virtual void OnWorksiteProcessingDone();



private:

	//-- reporting stuff
	InfoEventReport emptyInfoEventReport;
	std::vector<InfoEventReport> infoEventReports;
	int reportCopiesSent;
	bool didStartEarningReward;
	bool didReportReportTaskStartedEvent;
	bool didReportWorksiteReachedEvent;

};

#endif /* SRC_EPUCK_ACTIONCONTROL_BASEACTIONCONTROLLER_H_ */
