#ifndef __COMMUNICATION_H_
#define __COMMUNICATION_H_

#include "Messages.h"
#include "SgEngine.h"
#include <mpi.h>

class Communication : public Messages {
  private:
    SgEngine * const engine;
    size_t bufferSize;
    MessagePayloadType *bufferIn, *bufferOut;
    int localSolutionsReceived;

    int getNeighbor( int distance ) const;
    static bool isMessageWaiting( MPI_Status *mpiStatus );

    template<MessageType code>
    void processMessage( int source );

    template<MessageType code>
    void sendMessage() ;

  public:
    Communication( SgEngine *engine );
    ~Communication();

    void checkMessages();
    void sendMessage( MessageType messageType );
    void solveBegin();
    void solveEnd();

    static void programStart( int *argc, char ***argv, int *myRank, int *myP );
    static void programTerminate();
};

#endif /* __COMMUNICATION_H_ */
