/*
 * zReceiver.h
 * 
 * The Zen API 
 * Copyright (C) 2008-2010 by LMI Technologies Inc.
 * 
 * Licensed under The MIT License.
 * Redistributions of files must retain the above copyright notice.
 */
#ifndef LMITECH_ZRECEIVER_H_INCLUDED
#define LMITECH_ZRECEIVER_H_INCLUDED

#include <zNetwork.h>
#include <zResult.h>
#include <zApiBegin.h>

typedef zHandle zReceiver;      // Receives result messages (health, events, data) from a FireSync system.

typedef zStatus(ZAPI_CALL *zReceiverCallback) (zHandle context, zReceiver receiver, zResult result); //
//
//  Description:
//      Defines the signature of a callback function to receive zResult objects.
//  Arguments:
//      context - User context handle.
//      receiver - zReceiver object. 
//      result - Received result object. 
//  Remarks: 
//      Call zResult_Destroy to free the result object when it is no longer needed.

ZAPI_EXPORT(zStatus) zReceiver_Construct(zReceiver* receiver); //
//
//  Description:
//      Constructs a zReceiver object. 
//  Remarks:
//      After constructing a zReceiver object, setup functions can be used to configure the 
//      receiver.  When setup is complete, call the zReceiver_Open function to begin 
//      communication activities. 
//
//      The functions in this class do not protect against access from multiple threads.

ZAPI_EXPORT(zStatus) zReceiver_Destroy(zReceiver receiver); //
//
//  Description:
//      Destroys a zReceiver object. 
//  Arguments:
//      receiver - zReceiver object. 
//  Remarks: 
//      Destroying the zReceiver object will close the data connection, if currently open.

ZAPI_EXPORT(zStatus) zReceiver_SetBuffers(zReceiver client, zIntPtr socketSize, zIntPtr receiverSize); //
//
//  Description:
//      Sets the size of read buffers. 
//  Arguments:
//      receiver - zReceiver object. 
//      socketSize - Size of the read buffer maintained by the underlying socket (-1 to leave unchanged).
//      receiverSize - Size of the read buffer maintained by the receiver object (-1 to leave unchanged).
//  Remarks: 
//      Socket buffers decouple the sender and receiver, so that the sender does not need to block
//      while waiting for the receiver to receive all bytes. Recevier buffers improve the efficiency 
//      of the recevier when performing several small read operations (e.g. result messages headers). 
//     
//      If you will be using the zReceiver_Read function with a large buffer argument, consider setting
//      receiverSize to 0.  This will bypass zReceiver's internal buffer and copy directly into your 
//      buffer. 
//
//      This function can only be called before a connection is established with zReceiver_Open. 

ZAPI_EXPORT(zStatus) zReceiver_SetReceiveHandler(zReceiver receiver, zReceiverCallback onReceive, zHandle context); //
//
//  Description:
//      Registers or unregisters a callback function that is notified when zResult objects have been received.
//  Arguments:
//      receiver - zReceiver object. 
//      onReceive - Callback function, or zNULL to de-register for callback notification.
//      context - User context handle supplied to the callback function.
//  Remarks: 
//      This function can only be called before a connection is established with zReceiver_Open. 

ZAPI_EXPORT(zStatus) zReceiver_Open(zReceiver receiver, zBool isActive, zIPAddress address, z32u port); //
//
//  Description:
//      Initates network activities for active mode or passive mode connections. 
//  Arguments:
//      receiver - zReceiver object. 
//      isActive - zTRUE for active mode; zFALSE for passive mode (see discussion below).
//      address - Active mode: local address on which to listen (or zIP_ADDRESS_ANY); Passive mode: remote server address. 
//      port - Active mode: local port on which to listen (or zIP_PORT_ANY); Passive mode: remote server port. 
//  Remarks: 
//      After constructing a zReceiver object, setup functions can be used to configure the 
//      receiver.  When setup is complete, zReceiver_Open begins communication activities.  
//      
//      In active mode, this function will cause the zReceiver to open a server port and wait for 
//      incoming data connections.  In passive mode, this function will attempt to establish 
//      a data connection to a server on the network. The use of passive mode can eliminate conflicts
//      with firewall software running in the client network.  However, Passive mode was not available 
//      until FHP 2.1; older systems must use active mode. 

ZAPI_EXPORT(zStatus) zReceiver_Close(zReceiver receiver); //
//
//  Description:
//      Terminates network activities. 
//  Arguments:
//      receiver - zReceiver object. 
//  Remarks: 
//      It is not necessary to call this function before calling zReceiver_Destroy - disconnection 
//      will occur automatically upon destruction.

ZAPI_EXPORT(zBool) zReceiver_IsOpen(zReceiver receiver); //
//
//  Description:
//      Reports whether this zReceiver object is in the open state.
//  Arguments:
//      receiver - zReceiver object. 
//  Remarks: 
//      For an active mode receiver, if this function returns zTRUE then a server port was successfully 
//      opened to wait for an incoming data connection. For a passive mode receiver, if this funtion returns 
//      zTRUE then a data connection was successfully established.  

ZAPI_EXPORT(zStatus) zReceiver_Receive(zReceiver receiver, z64u timeout, zResult* result); //
//
//  Description:
//      Waits until a zResult object is received, or until the specified timeout period elapses.
//  Arguments:
//      receiver - zReceiver object. 
//      timeout - Timeout period, in microseconds.
//      result - Receives result object, upon success.  Call zResult_Destroy to free the object.
//  Remarks: 
//      This function is an alternative to registering for asynchonous result callbacks. This function will 
//      fail if a callback handler was registered with the zReceiver_SetReceiveHandler function.
//
//      The timeout supplied to this function may not be strictly honored for active mode connections 
//      during an interval in which the remote data provider is re-establishing the connection.  Under 
//      such conditions, the real timeout might vary from 0 to 2*timeout. 
//
//      This function can only be called after calling zReceiver_Open. 

ZAPI_EXPORT(zStatus) zReceiver_Wait(zReceiver receiver, z64u timeout); //
//
//  Description:
//      Waits until one or more bytes is available to read, or until the specified timeout period elapses.
//  Arguments:
//      receiver - zReceiver object. 
//      timeout - Timeout period, in microseconds.
//  Remarks: 
//      This function can be used in conjuction with zReceiver_Read to read bytes directly from the 
//      underlying socket.  Call zReceiver_Wait until a message has arrived, then call zReceiver_Read
//      to read out the message. 
//
//      The timeout supplied to this function may not be strictly honored for active mode connections 
//      during an interval in which the remote data provider is re-establishing the connection.  Under 
//      such conditions, the real timeout might vary from 0 to 2*timeout. 
//
//      This function will fail if a callback handler was registered with the zReceiver_SetReceiveHandler function.
//
//      This function can only be called after calling zReceiver_Open. 

ZAPI_EXPORT(zStatus) zReceiver_Read(zReceiver receiver, void* buffer, zUIntPtr size); //
//
//  Description:
//      Reads one or more bytes from the underlying socket. 
//  Arguments:
//      receiver - zReceiver object. 
//      buffer - Buffer to receive bytes. 
//      size - The number of bytes to read.
//  Remarks: 
//      This function is an alternative to calling zReceiver_Receive. zReceiver_Read should be used 
//      when low-level access to network data is required, or when the sender is not transmitting messages 
//      in FireSync Result format. Call zReceiver_Wait until a message has arrived, then call zReceiver_Read
//      to read out the message. 
//
//      This function will fail if a callback handler was registered with the zReceiver_SetReceiveHandler function.
//
//      This function can only be called after calling zReceiver_Open. 

ZAPI_EXPORT(zStatus) zReceiver_ListenEndPoint(zReceiver receiver, zIPEndPoint* endPoint); //
//
//  Description:
//      For active receivers, reports the local end point on which the receiver listens 
//      for incoming connections.
//  Arguments:
//      receiver - zReceiver object. 
//  Remarks:
//      The address portion of the returned end point may be zIP_ADDRESS_ANY if the reciever was 
//      constructed without an explicit address.

#include <zApiEnd.h>

#endif      /* #ifndef LMITECH_ZRECEIVER_H_INCLUDED */
