//  Beta release only.
//
//  Copyright(c) Ivyware Pty Ltd 2002-13 (all rights reserved)
//               MELBOURNE, VICTORIA, AUSTRALIA, 3130
//
//  Provided no fee is charged (either by the distributer or user)
//  permission to use, copy, modify, and distribute this software and
//  its documentation for any purpose and without fee is hereby granted,
//  provided that the above copyright notice appear in all copies and
//  that both that copyright notice and this permission notice appear
//  in supporting documentation.
//
//  No waranty or suitablity for purpose is implied.
//
//
//  P2Pwin32 prototypes and definitions.
//
//
#pragma   once

#include "P2PmsgKERNEL.h"
#include "P2PeerHub.h"

//
//  P2Pmsg environment
//  NOTES: Manage P2Pmsg environment.  Allocates and recovers
//         resources at startup and shutdown respectively.
//       : P2Pmsg environment must be started prior to P2PmsgHub
//         and P2PmsgPump creation
//       : Normally all P2PmsgHub's and P2PmsgPump's should be
//         destroyed prior to cleanup
P2PmsgKERNEL_EXT BOOL
StartupP2Pmsg ( UINT nMaxHubs = 64 );
P2PmsgKERNEL_EXT void
CleanupP2Pmsg ( );

//
//  P2PmsgHub management
//  NOTES: Manage the creation, operation and life cycle of
//         P2PmsgHub's.  P2P messages are only ever be exchanged 
//         between P2PmsgHub's
//       : Act as containers for P2PmsgPump's
P2PmsgKERNEL_EXT P2PmsgHubID
CreateP2PmsgHub  ( P2PadomSTR strP2Padom, P2PeerHub *pHub
                 , UINT nMaxPumps
                 , DWORD nNumberOfConcurrentThreads );

P2PmsgKERNEL_EXT P2PmsgHubID
GetP2PmsgHubID ( );
P2PmsgKERNEL_EXT P2PmsgHubID
GetP2PmsgHubID ( const P2PeerCon *pCon );
P2PmsgKERNEL_EXT P2PmsgHubID
GetP2PmsgHubContext ( );
                                 
void                                   // P2Padomain management
SetP2PmsgHubAdom ( P2PmsgHubID nHubID, P2PadomSTR strP2Padom );
P2PadomSTR
GetP2PmsgHubAdom ( P2PmsgHubID nHubID = 0 );
                                 
void                                   // P2Paddress management
SetP2PmsgHubAddr ( P2PmsgHubID nHubID, P2PaddrSTR strP2Paddr );
P2PaddrSTR
GetP2PmsgHubAddr ( P2PmsgHubID nHubID = 0 );
P2PaddrSTR
GetP2PmsgHubAddr ( const P2PeerCon *pCon );
UINT P2PmsgKERNEL_EXT
GetP2PmsgHubConCount ( P2PmsgHubID nHubID = 0 );
P2PmsgKERNEL_EXT P2PaddrSTR
GetP2PmsgHubName ( P2PmsgHubID nHubID = 0 );
P2PmsgKERNEL_EXT void
RegisterP2PmsgHub ( P2PeerTarget *pTarget, P2Pri_t nPriority = -127 );

HANDLE
GetIOCP          ( );
HANDLE
CreateP2PmsgHubIOCP ( HANDLE hFile );
void                                   // P2PeerCon management
PostP2PmsgCon    ( P2PmsgHubID nHubID, P2PeerCon *pCon );
void
DropP2PmsgCon    ( P2PeerCon *pCon );
BOOL
EnumP2PmsgCon    ( P2PmsgHubID nHubID, P2PeerCon **pCon );
P2PeerCon*
NextP2PmsgCon    ( DWORD eMsgCon );

P2PmsgKERNEL_EXT bool
P2PmsgHubExists( P2PmsgHubID nHubID );

const P2PsigID P2PsigHub_CLOSE       = 1;
const P2PsigID P2PsigHub_CLOSEONIDLE = 2;
const P2PsigID P2PsigHub_PAUSE       = 3;
const P2PsigID P2PsigHub_WAKEUP      = 4;
P2PmsgKERNEL_EXT BOOL
SignalP2PmsgHub ( P2PmsgHubID nHubID, P2PsigID nSigID );
P2PmsgKERNEL_EXT void
CloseP2PmsgHub ( );

const DWORD P2PmsgHub_IDLE        = (1<<0);
const DWORD P2PmsgHub_CLOSE       = (1<<1);
const DWORD P2PmsgHub_CLOSEONIDLE = (1<<2);
const DWORD P2PmsgHub_USERDEF1    = (1<<16);

//
//  P2PmsgPump management
//  NOTES: Manage the creation, operation and life cycle of
//         P2PmsgPump's.
//       : Act as priority queues for P2Pmsg's 
P2PmsgKERNEL_EXT P2PumpID
CreateP2PmsgPump ( P2PmsgHubID nHubID, LPCTSTR lpszName, P2PeerTarget *pTarget );
P2PmsgKERNEL_EXT BOOL
EnumP2PmsgPump   ( P2PmsgHubID nHubID, P2PumpID& nPumpID );
P2PmsgKERNEL_EXT P2PumpID
GetP2PmsgPumpID  ( );
P2PmsgKERNEL_EXT P2PaddrSTR
SetP2PmsgPumpName( P2PumpID nPumpID, P2PaddrSTR strName );
P2PmsgKERNEL_EXT P2PaddrSTR
GetP2PmsgPumpName( P2PumpID nPumpID = 0 );
P2PmsgKERNEL_EXT P2PaddrSTR
SetP2PmsgPumpFunc( P2PumpID nPumpID, P2PaddrSTR strFunc );

P2PmsgKERNEL_EXT UINT
PostP2Pmsg ( P2PaddrSTR strP2Paddr, UINT nCode, P2Pmsg_t nMsg
           , P2PeerCon *pCon, P2PeerMsg *pMsg, P2PumpID nP2PumpID = 0 );
P2PmsgKERNEL_EXT P2PeerMsg*
PostP2Pmsg ( P2PeerMsg *pMsg, P2PumpID nP2PumpID
           , bool bPrepend = false );
P2PmsgKERNEL_EXT UINT
PostP2Pmsg ( DWORD hPumpID
           , P2Pmsg_t nMsg, WPARAM wParam, LPARAM lParam );

P2PmsgKERNEL_EXT BOOL
RunP2PmsgPump ( );
const DWORD P2PmsgPump_TIMEOUT = 1;
const DWORD P2PmsgPump_MSG     = 2;
const DWORD P2PmsgPump_CON     = 3;
const DWORD P2PmsgPump_IOCP    = 4;
const DWORD P2PmsgPump_SIGNAL  = 5;
const DWORD P2PmsgPump_TIMER   = 6;
P2PmsgKERNEL_EXT DWORD
WaitForP2Pmsg ( DWORD dwMSecs );
P2PmsgKERNEL_EXT DWORD
PumpP2Pmsg ( DWORD dwMSecs, P2PsigID& nSigID );

const P2PsigID P2PsigPump_CLOSE       = 1;
const P2PsigID P2PsigPump_CLOSEONIDLE = 2;
const P2PsigID P2PsigPump_WAKEUP      = 3;
P2PmsgKERNEL_EXT BOOL
SignalP2PmsgPump ( P2PumpID nPumpID, P2PsigID nSigID );

P2PmsgKERNEL_EXT bool
CheckP2PmsgPumpState ( UINT nCode, P2Pmsg_t nMsg );
P2PmsgKERNEL_EXT bool
P2PmsgPumpExists( P2PumpID nPumpID );
P2PmsgKERNEL_EXT bool
IsP2PmsgPumping ( P2PumpID nPumpID = 0 );
P2PmsgKERNEL_EXT void
CloseP2PmsgPump ( );

P2PmsgKERNEL_EXT UINT
GetP2PmsgCount ( P2PumpID nPumpID = 0 );
P2PmsgKERNEL_EXT BOOL
SetP2PmsgEvent ( P2PumpID nPumpID = 0 );
P2PmsgKERNEL_EXT void
FlushP2Pmsg    ( P2PumpID nPumpID = 0 );

//
//  P2PmsgTimer management
//  NOTES: Manage the manufacture, translation, dispatch and
//         life cycle of internal P2PmsgTimer's
//       : Available from P2PeerCon, P2PeerTarget and P2Peerio
//         objects
P2PmsgKERNEL_EXT UINT
SetP2PmsgTimer   ( P2PaddrSTR strP2Paddr, UINT nCode, P2Pmsg_t nMsg
                 , P2PeerCon *pCon, P2PeerMsg *pMsg
                 , P2Pmsecs_t uiTimeout, DWORD nPumpID = 0 );
P2PmsgKERNEL_EXT PITimerID
SetP2PmsgTimer   ( P2PumpID nPumpID, P2Peerio *pP2Peerio
                 , P2Pmsecs_t uMSecDelay, DWORD dwUserKey );
P2PmsgKERNEL_EXT PITimerID
SetP2PmsgTimer   ( P2PumpID nPumpID, P2PeerCon *pCon
                 , P2Pmsecs_t uMSecDelay, DWORD dwUserKey );
P2PmsgKERNEL_EXT PITimerID
SetP2PmsgTimer   ( P2PumpID nPumpID, P2PeerTarget *pTarget
                 , P2Pmsecs_t uMSecDelay, DWORD dwUserKey );
P2PmsgKERNEL_EXT P2Pmsecs_t
NextP2PmsgTimer  ( P2PumpID nPumpID = 0 );
P2PmsgKERNEL_EXT UINT
KillP2PmsgTimer  ( PITimerID nPITimerID, P2PumpID nPumpID = 0 );
P2PmsgKERNEL_EXT void
CancelP2PmsgTimer( PITimerID nPITimerID, bool bCallback = true );

//
//  P2PeerMsg_MAP implementation prototypes
//  NOTES: Referenced from On_P2PeerMsg only
const P2P_MSGMAP_ENTRY* AFXAPI
FindP2PeerMsgEntry ( const P2P_MSGMAP_ENTRY *lpEntry
                   , P2PeerMsg *pMsg
                   , P2Pmsg_t nMsg, UINT nCode, UINT nID );
extern msgRESULT AFXAPI
DispatchP2PeerMsg  ( P2PeerTarget *pTarget, UINT nID, int nCode
                   , P2P_PMSG pfn, void *pvExtra
                   , UINT_PTR nSig
                   , P2P_MSGHANDLERINFO* pHandlerInfo );

//
//  P2PeerSys_MAP implementation prototypes
//  NOTES: Referenced from On_P2PeerSys only
const P2P_SYSMAP_ENTRY* AFXAPI
FindP2PeerSysEntry ( const P2P_SYSMAP_ENTRY *lpEntry
                   , P2Pmsg_t nMsg, UINT nCode );
extern BOOL AFXAPI
DispatchP2PeerSys  ( P2PeerTarget *pTarget, int nCode
                   , P2P_PSYS pfn, void *pvExtra
                   , UINT_PTR nSig
                   , P2P_SYSHANDLERINFO* pHandlerInfo );

//
//  P2PeerCon_MAP implementation prototypes
//  NOTES: Referenced from On_P2PeerCon only
const P2P_CONMAP_ENTRY* AFXAPI
FindP2PeerConEntry ( const P2P_CONMAP_ENTRY *lpEntry
                   , P2Pmsg_t nMsg, UINT nCode
                   , P2PeerCon *pCon, P2PeerMsg *pMsg );
extern conRESULT AFXAPI
DispatchP2PeerCon  ( P2PeerTarget *pTarget
                   , P2PeerCon *pCon, int nCode, P2Pmsg_t nMsg
                   , P2P_PMSG pfn, void *pvExtra
                   , UINT_PTR nSig
                   , P2P_CONHANDLERINFO* pHandlerInfo );

//
//  Processing context
//  NOTES: Manage the pump processing context of objects pumped
//         through the P2PeerCon_MAP, P2PeerSys_MAP and
//         P2PeerMsg_MAP's
mapRESULT
SwapP2PmsgContext  ( P2PeerTarget *pTarget, P2PumpID nPumpID
                   , P2PeerCon *pCon
                   , P2PeerMsg *pMsg
                   , HWND hWnd = 0, UINT nWM_APP = 0 );
mapRESULT
RedirectP2Pmsg ( P2PeerMsg *pMsg );
mapRESULT
RepumpP2Pmsg ( P2PeerMsg *pMsg );

//
//  Windows message loop integration prototypes and definitions
//  NOTES: Usually we delegate to OnP2PeerTarget() within the
//         MFC message map intercepting WM_APP_P2PeerTarget message
//       : Definition sequence is designed to trap use of the
//         message number elsewhere
//       : Usually the WM_APP_P2PeerTarget definition is nominated
//         for message exchange from the P2PeerHub to the CWinApp
//         thread.  Refer FIX-ME() for further details
const DWORD WM_APP_0x1FFF       = WM_APP + 0x1FFF;
const DWORD WM_APP_P2PeerTarget = WM_APP_0x1FFF;
P2PmsgKERNEL_EXT BOOL
CWnd_OnP2PeerTarget ( WPARAM wParam, LPARAM lParam );

///////////////////////////////////////////////////////////////////////
//  Encoding
//  NOTES: Provides thread safe text encoding of defined parameter
//         types
LPCTSTR
EncodeP2Pmsg_t ( P2Pmsg_t nMsg );
