//******************************
//
// Filename = RobotAPI.h
// Author = Michael Wales
//
// Version History:
//  0.0   Complete listing of original design
//  0.1   Full support for CHANGE_ORIENTATION, CHANGE_SPEED, STATUS_CHECK, and CURRENT_STATUS commands
//
//******************************

#include<semaphore.h>

#ifndef _ROBOTAPI_H_
#define _ROBOTAPI_H_


#define MAX_CONNECTIONS 5

class RobotAPI;
class RobotAPIRobot;
class RobotAPIController;
class RobotCommandReceiver;
class RobotCommand;
class PointList;
class XYPoint;
class TesterClass;
class ThreadWait;



//***********************//
// FUNCTION DECLERATIONS //
//***********************//

void* listenForData(void* RobotAPIObject);
void* waitForNewConnections(void* RobotAPIControllerObject);
void robotWait(int MicroSeconds);
void* sendNullCommand (void* RobotAPIObject);


//********************//
// CLASS DECLERATIONS //
//********************//

class XYPoint
   {
   public:
   
   int X;
   int Y;
   XYPoint* NextPoint;
   
   };
   
class PointList
   {
   private:
   
   int MaxSize;
   XYPoint TheList[50];
   int NumOfPoints;
   
   public:
   
   void addPoint(int X, int Y);
   void pathToString(char* Path);
   void printList(void);
   PointList(int Size);
   };
   
class RobotCommandReceiver
   {
   public:
    
   virtual void receiveCommand(char InstructionCode, RobotCommand* NewCommand);
   };
   
class RobotAPI
   {
   friend void* listenForData (void* RobotAPIObject);
   friend void* sendNullCommand (void* RobotAPIObject);
   friend void* safetyOverride (void* RobotAPIObject);
   
   private:
   
   sem_t SendCommandLock;
   
   protected:
   
   int SocketFD;
   int PortNumber;
   TesterClass* MessageReceiver;
   int ConnectionOK;
   int CommunicationSockets[MAX_CONNECTIONS];
   int ServerSocket;
   
   int getSocketFD (void);
   void setSocketFD (int NewFD);
   int sendCommandTo(RobotCommand CommandToExecute, int SFD);
   void startSafetyOverride (void);
   
   
   public:
   
   RobotAPI();
   int sendCommand(RobotCommand CommandToExecute);
   void setPort(int PortNum);
   void setReceiver(TesterClass* InterfaceToAPI);
   };
   
class RobotAPIRobot : public RobotAPI
   {
   public:
   
   int establishConnection(char* IPAddress);
   };
   
class RobotAPIController : public RobotAPI
   {
   friend void* waitForNewConnections (void* RobotAPIControllerObject);
   friend void* listenOnSecondaryConnection (void* RobotAPIControllerObject);
   
   public:
   
   int establishConnection(void);
   // int sendCommand(RobotCommand CommandToExecute);
   };
   
class RobotCommand
   {
   public:
   
   char CommandName[30];
   
   // Simple command parameter
   int Value;
   int ValueB;
   int ValueC;
   
   // GOTO_XY command parameters
   int XCoordinate;
   int YCoordinate;
   
   // FOLLOW_PATH command parameters
   // PointList Path;
   
   void copyCommand (RobotCommand Source);
   };
   
class ConfigSys
   {
   public:
   
   void loadConfiguration(void);
   
   char ServerIP[40];
   int HorizontalArea;
   int PortNumber;
   };
   
class TesterClass
{
   public:
		
   int ErrorFlag;
   RobotCommand Command;
   RobotAPIController APIC;
   int runMe(void);
   void changeOrientation(int);
   void changeSpeed(int);
   void statusCheck();
   void steerMotor(int);
   void receiveCommand(char , RobotCommand *);
};
   
#endif
