#ifndef REQUEST_H
#define REQUEST_H

#include "stdmpi.h"

#include "Result.h"
#include "HashTableBuffer.h"

#define REQUEST_TYPE_UNDEFINED                               0

#define REQUEST_TYPE_ROOT_MASTER_LOGON_INVITATION            1
#define REQUEST_TYPE_ROOT_MASTER_LOGOFF_INVITATION           2
#define REQUEST_TYPE_ROOT_MASTER_SHUTDOWN                    3
#define REQUEST_TYPE_ROOT_MASTER_IDLE_INVITATION             4
#define REQUEST_TYPE_ROOT_MASTER_SYNC_POSITION               5
#define REQUEST_TYPE_ROOT_MASTER_SUPPORT_SEARCH              6
#define REQUEST_TYPE_ROOT_MASTER_STOP_REMOTE_SEARCH          7
#define REQUEST_TYPE_ROOT_MASTER_NEW_GAME                    8
#define REQUEST_TYPE_ROOT_MASTER_SET_OPTION                  9
#define REQUEST_TYPE_ROOT_MASTER_REMOTE_TEST                10

#define REQUEST_TYPE_ROOT_MASTER_MACHINE_INFO               11

#define REQUEST_TYPE_NON_ROOT_MASTER_SYNC_AFTER_BROADCAST   12

#define REQUEST_TYPE_SLAVE_TRY_TO_GET_WORK                  13

#define REQUEST_TYPE_MASTER_STOP                            14

#define REQUEST_TYPE_SLAVE_PROCESS_SEARCH_RESULT            15

#define REQUEST_TYPE_MASTER_UPDATE_SEARCH_WINDOW            16

#define REQUEST_TYPE_HASH_TABLE_REPLICATION                 17
#define REQUEST_TYPE_HASH_TABLE_BROADCAST_BUFFER            18

#define REQUEST_TYPE_HISTORY_TABLE_REPLICATION              19
#define REQUEST_TYPE_HISTORY_TABLE_BROADCAST_BUFFER         20

#define REQUEST_TYPE_HIST_TOT_TABLE_REPLICATION             21
#define REQUEST_TYPE_HIST_TOT_TABLE_BROADCAST_BUFFER        22

#define MAX_REQUEST_PARAMETER_BUFFER_SIZE     8192

#define MAX_REQUEST_SYNC_POSITION_LENGTH      8000
#define MAX_REQUEST_OPTION_NAME_LENGTH        1024
#define MAX_REQUEST_OPTION_VALUE_LENGTH       1024
#define MAX_REQUEST_GO_COMMANDS_LENGTH        1024

#define MAX_REQUEST_TYPE_TO_STRING              64

typedef struct tRequest
{
  struct tRequest*  pNext;

  struct tRequest*  pBroadcastRequest;
  int               nReferenceCount;
  BOOL              bPreventDestruct;

  int               nSourceId;
  int               nDestId;
  char              pParameterBuffer[MAX_REQUEST_PARAMETER_BUFFER_SIZE];
  MPI_Request       mpiRequest;
  int               nPosition;

  BOOL              bSendSuppressed;

  BOOL              bDispatchedFirst;
  BOOL              bDelayedDispatch;

  int               nType;
  char              szTypeToString  [MAX_REQUEST_TYPE_TO_STRING + 1];

  char*             psSyncPosition; // kh 07.02.08 uci position
  int               nSyncPositionId;

  char*             psOptionName;   // kh 07.02.08 uci setoption name
  char*             psOptionValue;  // kh 07.02.08 uci setoption value

  char*             psGoCommands;   // kh 10.08.06 rather local (temp only) data, but helpful for debug purposes

  int               nBestMove;
  int               nBestValue;
  int               nFlags;
  int               nDepth;
  int               nMaxDepth;
               
  int               nPVLength;
  uint16            PV[MAX_PV_LENGTH];
  uint16*           pPV;

// kh 12.10.06 no longer used
//int               nPonderMove;

  BOOL              bPonderMoveOk;
  double            dTime;
  double            dSpeed;
  double            dCPU;
  sint64            nNodes;
  uint64            nTransUsed;

  sint64            nWorkId;

  int               nStackIndex;
  int               nMoveListIndex;

  int               nAlpha;
  int               nBeta;

  int               nHistoryTableSize;
  uint16            HistoryTable[HistorySize];

  int               nHistTotTableSize;
  uint16            HistTotTable[HistorySize];

  int               nHistHitTableSize;
  uint16            HistHitTable[HistorySize];

  struct tHashTableBuffer*  pHashTableBuffer;

} Request;

Request* Request_Construct(Request* pThis);

void Request_Destruct(Request* pThis);

int Request_Send(Request* pThis);

int Request_SendBroadcastBuffer(Request* pThis);

BOOL Request_IsSendPending(Request* pThis);

int Request_InitRootMasterLogonInvitation(Request* pThis);

int Request_InitRootMasterLogoffInvitation(Request* pThis);

int Request_InitRootMasterShutdown(Request* pThis);

int Request_InitRootMasterIdleInvitation(Request* pThis);

int Request_InitRootMasterSyncPosition(Request* pThis, char* psSyncPosition);

int Request_InitRootMasterSupportSearch(Request* pThis);

int Request_InitRootMasterStopRemoteSearch(Request* pThis);

int Request_InitRootMasterNewGame(Request* pThis);

int Request_InitRootMasterSetOption(Request* pThis, char* szOptionName, char* szOptionValue);

int Request_InitNonRootMasterSyncAfterBroadcast(Request* pThis);

int Request_InitRootMasterRemoteTest(Request* pThis, char* szGoCommands);

int Request_InitRootMasterMachineInfo(Request* pThis);

int Request_InitSlaveTryToGetWork(Request*  pThis,
                                  int       nSlaveSyncPositionId);

int Request_InitMasterStop(Request* pThis,
                           sint64   nWorkId);

int Request_InitMasterUpdateSearchWindow(Request* pThis,
                                         sint64   nWorkId,
                                         int      nAlpha,
                                         int      nBeta);

int Request_InitSlaveProcessSearchResult(Request* pThis,
                                         sint64   nWorkId,
                                         int      nStackIndex,
                                         int      nMoveListIndex,
                                         int      nBestMove,
                                         int      nBestValue,
                                         int      nFlags,
                                         int      nDepth,
                                         int      nMaxDepth,
                                         int      nPVLength,
                                         uint16   PV[],
                                         BOOL     bPonderMoveOk,
                                         double   dTime,
                                         double   dSpeed,
                                         double   dCPU,
                                         sint64   nNodes,
                                         uint64   nTransUsed);

int Request_InitHashTableReplication(Request*                  pThis,
                                     struct tHashTableBuffer*  pHashTableBuffer);

int Request_InitHashTableBroadcastBuffer(Request*                  pThis,
                                         struct tHashTableBuffer*  pHashTableBuffer);

int Request_InitHistoryTableReplication(Request*  pThis,
                                        Request*  pHistoryTableBroadcastBuffer);

int Request_InitHistoryTableBroadcastBuffer(Request* pThis);

int Request_InitHistTotTableReplication(Request*  pThis,
                                        Request*  pHistTotTableBroadcastBuffer);

int Request_InitHistTotTableBroadcastBuffer(Request* pThis);

int Request_GetParameterFromBuffer(Request* pThis);
#endif
