/****************************************************************************
 * Copyright (c) 2025 MAK Technologies, Inc.
 * All rights reserved.
 ****************************************************************************/

//! \file diguy_module_net.h
//! \brief Contains the diguyNetInterface class declaration.
//! \ingroup libpeopleshop_vrlink

#pragma once

/*********************************************************************
 **
 *t  DI-Guy API, VR-Link
 **
 *b  Link against: libdiguy_module_dis or libdiguy_module_hla
 **
 */

#include <declspec_diguy.h>

#include <diguy_constants.h>

#include <stddef.h>

class diguyCharacter;
class diguyScenario;
class diguyNetInterface;
struct diguyNetInterfaceData;

class bdiDataTracker;


/****************************************************************************/
typedef enum
{
   DIGUY_COORDINATE_SYSTEM_NONE       = 0,
   DIGUY_COORDINATE_SYSTEM_UTM        = 1,
   DIGUY_COORDINATE_SYSTEM_FLAT_EARTH = 2,
   DIGUY_COORDINATE_SYSTEM_GEOCENTRIC = 3

} diguyCoordinateSystemType;


extern "C"
{

/*l
 *b  Description:
 **
 **    This function allows VR-Link to install some callbacks so that DSS file
 **    load and save will include VR-Link-specific info.
 **
 **    It should be called BEFORE the scenario object is constructed.
 **
 *b  Returns:
 **
 **    0 on success, -1 on failure
 **
 *b  Example:
 **
 *e    diguy_module_net_initialize();
 */
BDI_DECLSPEC_diguy int diguy_module_net_initialize();

/*l
 *b  Description:
 **
 **    This function allows DI-Guy networking to clean up.
 **
 **    It should be called once, on application shutdown, after the scenario
 **    object has been destroyed.
 **
 *b  Returns:
 **
 **    0 on success, -1 on failure
 **
 *b  Example:
 **
 *e    diguy_module_net_deinitialize();
 */
BDI_DECLSPEC_diguy int diguy_module_net_deinitialize();

/*l
 *b  Description:
 **
 **    This function returns a diguyNetInterface which can be used to change
 **    settings on the networking module.  This will be an appropriate
 **    version of the net interface, i.e. a DIS or a HLA interface, depending
 **    on which library was linked in.
 **
 *b  Returns:
 **
 **    pointer to a diguyNetInterface
 */
BDI_DECLSPEC_diguy diguyNetInterface* get_net_interface();

}


/****************************************************************************/
/*l
 *b  Description:
 **
 **    This class provides accessors to the interface parameters, as well as
 **    functions for going online and offline.
 **
 */
class BDI_DECLSPEC_diguy diguyNetInterface
{
public:

   /*l
    *b  Description:
    **
    **    This function tells DI-Guy that it should start talking over
    **    VR-Link.
    **
    **    It should be called when DI-Guy should join an exercise.
    **
    *b  Arguments:
    **
    *a    scenario - pointer to the diguyScenario which will be connected to
    *a               the network
    *a    exconn   - optional pointer to a VR-Link exercise connection to use
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int go_online( diguyScenario* scenario, void* exconn = NULL ) = 0;

   /*l
    *b  Description:
    **
    **    This function tells DI-Guy that it should stop talking over
    **    VR-Link.
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int go_offline() = 0;

   /*l
    *b  Description:
    **
    **    This function asks if DI-Guy is connected to the network.
    **
    *b  Returns:
    **
    **    1 if yes, 0 if no
    */
   virtual int get_online() = 0;

   /*l
    *b  Description:
    **
    **    This function sets the filename of the VR-Link configuration file
    **    that will be read by the DI-Guy software.  The default is
    **    "network.cfg".  This function must be called before the network
    **    module is initialized.
    **
    *i  C++ only
    **
    *b  Arguments:
    **
    *a    cfg_file - filename of desired configuration file
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_cfg_file(const char* cfg_filename) = 0;

   /*l
    *b  Description:
    **
    **    This function tells DI-Guy that it should read PDUs from the
    **    network and process them.  Call this function periodically.
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int update() = 0;

   /*l
    *b  Description:
    **
    **    Sets the exercise id to be used by DI-Guy networking.
    **
    **    The function will fail if DI-Guy is on-line (is participating in
    **    an exercise).
    **
    *b  Arguments:
    **
    *a    exercise - the exercise id to use. Must be <= 255 in DIS
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_exercise(int exercise) = 0;

   /*l
    *b  Description:
    **
    **    Gets the exercise id being used by DI-Guy networking.
    **
    *b  Returns:
    **
    **    the exercise id
    */
   virtual int get_exercise() = 0;

   /*l
    *b  Description:
    **
    **    Sets the host id to be used by DI-Guy networking.
    **
    **    The function will fail if DI-Guy is on-line (is participating in
    **    an exercise).
    **
    *b  Arguments:
    **
    *a    host - the host id to use; the host id identifies the local
    *a           machine
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
    virtual int set_host(int host) = 0;

   /*l
    *b  Description:
    **
    **    Gets the host id being used by DI-Guy networking.
    **
    *b  Returns:
    **
    **    the host id
    */
   virtual int get_host() = 0;

   /*l
    *b  Description:
    **
    **    Sets the site id to be used by DI-Guy networking.
    **
    **    The function will fail if DI-Guy is on-line (is participating in
    **    an exercise).
    **
    *b  Arguments:
    **
    *a    site - the site id to use; the site id identifies where the local
    *a           machine is located
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_site(int site) = 0;

   /*l
    *b  Description:
    **
    **    Gets the site id being used by DI-Guy networking.
    **
    *b  Returns:
    **
    **    the site id
    */
   virtual int get_site() = 0;

   /*l
    *b  Description:
    **
    **    Sets the network port number to be used by DI-Guy networking.
    **
    **    The function will fail if DI-Guy is on-line (is participating in
    **    an exercise).
    **
    *b  Arguments:
    **
    *a    port - the port number to use
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_port(int port) = 0;

   /*l
    *b  Description:
    **
    **    Gets the port number of the port being used for DI-Guy networking.
    **
    *b  Returns:
    **
    **    the port address
    */
   virtual int get_port() = 0;

   /*l
    *b  Description:
    **
    **    Sets the IP address to be used by DI-Guy networking.  This address
    **    is the address to which messages are sent.  Normally, it is a
    **    broadcast or multicast address.
    **
    **    The function will fail if DI-Guy is on-line (is participating in
    **    an exercise).
    **
    *b  Arguments:
    **
    *a    ipaddr - the IP address
    **
    **    ipaddr is a string containing 4 integers separated by periods, or
    **    the null string, which means "let DI-Guy choose the address".  An
    **    address of "0" or "0.0.0.0" means broadcast.
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_ipaddr(const char* ipaddr) = 0;

   /*l
    *b  Description:
    **
    **    Gets the IP address currently being used by DI-Guy networking.
    **    This address is the address to which messages are sent.  Normally
    **    this is a broadcast or multicast address.
    **
    *b  Arguments:
    **
    *a    ipaddr - IP address, returned; see below
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    **
    **    ipaddr is a char**, into which a char* will be placed.  This char*
    **    points to static data owned by DI-Guy.  Do not store this pointer,
    **    and do not modify what it points to.  Copy the strings you need
    **    out of the static buffer.  (Assignment of a char* to a Microsoft
    **    CString will work very nicely, for example.)
    **
    **    ipaddr is a string containing 4 integers separated by periods.
    */
   virtual int get_ipaddr(char** ipaddr) = 0;

   /*l
    *b  Description:
    **
    **    Sets the IP address to be used by DI-Guy networking.
    **    This address is the address of the network device to use for sending.
    **    Normally, it is the address assigned to the network card to use.
    **
    **    The function will fail if DI-Guy is on-line (is participating in
    **    an exercise).
    **
    *b  Arguments:
    **
    *a    ipaddr - the IP address
    **
    **    ipaddr is a string containing 4 integers separated by periods, or
    **    the null string, which means "let DI-Guy choose the address".  An
    **    address of "0" or "0.0.0.0" means broadcast.
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_device_ipaddr( const char* ipaddr ) = 0;

   /*l
    *b  Description:
    **
    **    Gets the IP address to be used by DI-Guy networking.
    **    This address is the address of the network device to use for sending.
    **    Normally, it is the address assigned to the network card to use.
    **
    *b  Returns:
    **
    **    String containing the device address.
    **
    */
   virtual const char* get_device_ipaddr() = 0;

   /*l
    *b  Description:
    **
    **    Sets the HLA Federation name you wish to create or join.
    **
    *b  Arguments:
    **
    *a    federation_name - as string
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_federation_name(const char* federation_name);

   /*l
    *b  Description:
    **
    **    Gets the HLA Federation name.
    **
    *b  Returns:
    **
    **    String containing HLA federation name
    */
   virtual const char* get_federation_name();

   /*l
    *b  Description:
    **
    **    Sets the HLA Federate name to use. Federate names should be
    **    unique for each connection instance.
    **
    *b  Arguments:
    **
    *a    federate_name - as string
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_federate_name(const char* federate_name);

   /*l
    *b  Description:
    **
    **    Gets the HLA Federate name.
    **
    *b  Returns:
    **
    **    String containing HLA federate name
    */
   virtual const char* get_federate_name();

   /*l
    *b  Description:
    **
    **    Sets the HLA Federate type to identify as.
    **
    *b  Arguments:
    **
    *a    federate_type - as string
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_federate_type(const char* federate_type);

   /*l
    *b  Description:
    **
    **    Gets the HLA Federate name.
    **
    *b  Returns:
    **
    **    String containing HLA federate type
    */
   virtual const char* get_federate_type();

   /*l
    *b  Description:
    **
    **    Sets whether DI-Guy networking will display remote characters.
    **
    **    The function will fail if DI-Guy is on-line (is participating in
    **    an exercise).
    **
    *b  Arguments:
    **
    *a    display - pass 1 if DI-Guy networking should display remote
    *a              characters, 0 if not
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_display_remote_chars(int display) = 0;

   /*l
    *b  Description:
    **
    **    Returns whether DI-Guy networking will display remote characters
    **    when online.
    **
    *b  Returns:
    **
    **    1 if enabled, 0 if not
    */
   virtual int get_display_remote_chars() = 0;

   /*l
    *b  Description:
    **
    **    This function sets whether DI-Guy is sending diguy state attributes.
    **
    *b  Arguments:
    **
    **    0 if diguy state attributes should not be sent,
    **    1 if diguy state attributes should be sent
    */
   virtual void set_send_diguy_state( int ) = 0;

   /*l
    *b  Description:
    **
    **    This function returns whether DI-Guy is sending diguy state attributes.
    **
    *b  Returns:
    **
    **    0 if diguy state attributes are not being sent,
    **    1 if diguy state attributes are being sent
    */
   virtual int get_send_diguy_state() = 0;

   /*l
    *b  Description:
    **
    **    This function sets whether DI-Guy is sending custom pdus.
    **
    *b  Arguments:
    **
    **    0 if custom pdus should not be sent,
    **    1 if custom pdus should be sent
    */
   virtual void set_send_custom_pdus( int ) = 0;

   /*l
    *b  Description:
    **
    **    This function returns whether DI-Guy is sending custom pdus.
    **
    *b  Returns:
    **
    **    0 if custom pdus are not being sent,
    **    1 if custom pdus are being sent
    */
   virtual int get_send_custom_pdus() = 0;

   /*l
    *b  Description:
    **
    **    This function returns whether DI-Guy sends custom pdus that concatenate
    **    hand item with the body appearance name. DI-Guy 13.0 and up separate these.
    */
   virtual int get_send_diguy_125_appearance_packets() = 0;
   /*l
    *b  Description:
    **
    **    This function set whether whether DI-Guy sends custom pdus that concatenate
    **    hand item with the body appearance name. DI-Guy 13.0 and up separate these.
    */
   virtual void set_send_diguy_125_appearance_packets(int) = 0;


   /*l
    *b  Description:
    **
    **    Turns the 'never create character' bit on.
    */
   virtual void enter_vpnet_mode() = 0;

   /*l
    *b  Description:
    **
    **    returns the diguyCharacter associated with the entity id specified.
    **
    *b  Arguments:
    **
    *a    id - Under HLA, two formats are permitted: the H L A object name,
    *a         or the DIS entity identifier ("site:application:entity", where
    *a         each is an integer)
    **
    **    Under DIS, only the DIS Entity Identifier is permitted.
    */
   virtual diguyCharacter* get_character_from_id(char const* id) = 0;

   /*l
    *b  Description:
    **
    **    Returns the name corresponding to the entity.  The caller must
    **    delete the returned string.
    **
    *b  Arguments:
    **
    *a    reflected_entity - entity to be named
    **
    *b  Returns:
    **
    **    name of reflected entity
    */
   virtual char* get_name_from_entity(void* reflected_entity) = 0;

   /*l
    *b  Description:
    **
    **    Sets whether DI-Guy networking will publish local characters to the
    **    network.
    **
    **    This function WILL succeed even if DI-Guy is on-line (is
    **    participating in an exercise).
    **
    *b  Arguments:
    **
    *a    publish - pass 1 if DI-Guy networking should publish local characters
    *a              to the network, 0 if not
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_publish_local_chars(int publish) = 0;

   /*l
    *b  Description:
    **
    **    Returns whether DI-Guy networking will publish local characters
    **    when online.
    **
    *b  Returns:
    **
    **    1 if enabled, 0 if not
    */
    virtual int get_publish_local_chars() = 0;

   /*l
    *b  Description:
    **
    **    This function sets the position offset which is currently added to
    **    each character when it is published, and subtracted from each
    **    character when it is reflected.  This is useful to compensate for
    **    inter-application location error.
    **
    *b  Arguments:
    **
    *a    z     - z offset in meters
    *a    yaw   - orientation offset in degrees
    *a    roll  - orientation offset in degrees
    *a    pitch - orientation offset in degrees
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_position_offset(float z, float yaw, float roll, float pitch) = 0;

   /*l
    *b  Description:
    **
    **    This function gets the position offset which is currently added to
    **    each character when it is published, and subtracted from each
    **    character when it is reflected.  The offset is useful to
    **    compensate for inter-application database location and orientation
    **    error.
    **
    *b  Arguments:
    **
    *a    z     -  z offset in meters
    *a    yaw   -  orientation offset in degrees
    *a    roll  -  orientation offset in degrees
    *a    pitch -  orientation offset in degrees
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int get_position_offset(float* z,
      float* yaw,
      float* roll,
      float* pitch) = 0;

   /*l
    *b  Description:
    **
    **    This function allows iteration through the list of names remote
    **    VR-Link hosts that DI-Guy knows about.
    **
    *b  Arguments:
    **
    *a    buf     - destination buffer for host name (64 bytes is plenty)
    *a    handle  - return value from last call to the function; pass NULL
    *a              to get the first host name; pass previous return value
    *a              to get the next host name
    **
    *b  Returns:
    **
    **    void* to be passed as handle argument on the next call; NULL when
    **    end of list is reached
    */
   virtual void* get_next_participant_name(char* buf, void* handle) = 0;

   /*l
    *b  Description:
    **
    **    Fetches what character type and what appearance should be used for
    **    a given DIS entity type septet.
    **
    *b  Arguments:
    **
    *a    chartype     - address of char*, for returning a string which
    *a                   names the DI-Guy character type
    *a    appearance   - address of char*, for returning a string which
    *a                   names the DI-Guy character appearance
    *a    septet       - array of seven integers specifying the kind,
    *a                   domain, country, category, subCategory, specific,
    *a                   and extra of the entity in question
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
    virtual int get_model_from_septet(const char** chartype,
      const char** appearance,
      const char** hand_item,
      const int septet[7]) = 0;

   /*l
    *b  Description:
    **
    **    Fetches what DIS entity type septet should be used for a given
    **    character type and appearance.
    **
    *b  Arguments:
    **
    *a    chartype     - a string which names the DI-Guy character type
    *a    appearance   - a string which names the DI-Guy character appearance
    *a    septet       - array of seven integers, returned, indicating the kind,
    *a                   domain, country, category, subCategory, specific, and
    *a                   extra of the entity in question
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int get_septet_from_model(int septet[7],
      const char* chartype,
      const char* appearance,
      const char* hand_item) = 0;

   /*l
    *b  Description:
    **
    **    This functions sets the amount of time that can elapse since the
    **    last update before an entity is timed out.  The default is 12
    **    seconds.
    **
    *b  Arguments:
    **
    *a    interval - number of seconds until timeout
    */
   virtual void set_timeout_interval(float interval) = 0;

   /*l
    *b  Returns:
    **
    **    timeout value in seconds; see set_timeout_interval()
    */
   virtual float get_timeout_interval() = 0;

   /*l
    *b  Description:
    **
    **    This function sets the number of hops a packet can take before
    **    being killed.  Setting this value to -1 means that the system
    **    default will be used.
    **
    **    This value must be set before the connection goes online.
    **
    *b  Arguments:
    **
    *a    time_to_live - number of hops until packed is killed
    */
   virtual void set_time_to_live(int time_to_live) = 0;

   /*l
    *b  Returns:
    **
    **    number of hops until packed is killed; see set_time_to_live()
    */
   virtual int get_time_to_live() = 0;


/*****************************************************************************/
/**
 *2  Coordinate System Functions
 */
/****************************************************************************/

   /*l
    *b  Description:
    **
    **    Sets the latitude and longitude to be used by DI-Guy networking.
    **    The latitude and longitude are taken as the location, on Earth, of
    **    the origin of the database.
    **
    **    The function will fail if DI-Guy is on-line (is participating in
    **    an exercise).
    **
    *b  Arguments:
    **
    *a    lat - the latitude in radians, positive north
    *a    lon - the longitude in radians, positive east
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_lat_lon(double lat, double lon) = 0;

   /*l
    *b  Description:
    **
    **    Gets the latitude and longitude currently being used by DI-Guy
    **    networking for the placement of the database origin.
    **
    *b  Arguments:
    **
    *a    lat - latitude of origin, returned; see below
    *a    lon - longitude of origin, returned; see below
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    **
    **    lat and lon are char**'s, into which char*'s will be placed.
    **    These char*'s point to static data owned by DI-Guy.  Do not
    **    store these pointers, and do not modify what they point to.  Copy
    **    the strings needed out of the static buffers.  (Assignment of a
    **    char* to a Microsoft CString will work very nicely, for example.)
    **
    **    lat and lon are expressed as strings of the form:
    **
    *-       - [-]d [N|W|S|E]     or
    *-       - [-]d m [N|W|S|E]   or
    *-       - [-]d m s [N|W|S|E]
    **
    **    N and E are taken as positive.  S and W will negate the value
    **    otherwise computed.  d, m, and s are positive, floating point
    **    values, taken as degrees, minutes, and seconds, respectively.
    **    A leading minus sign will negate the entire value otherwise
    **    computed (so, e.g., a '-' and a 'S' will result in a double-
    **    negation).
    */
   virtual int get_lat_lon(double* lat, double* lon) = 0;

   /*l
    *b  Description:
    **
    **    returns a string of the form
    **
    *-       - d [N|W|S|E]     or
    *-       - d m s [N|W|S|E]
    **
    **    N and E are used for positive angles.  S and W are used for
    **    negative angles.  In the d m s format, d and m are integers
    **    (degrees and minutes) and s (seconds) is a floating point value.
    **    In the d format, d (degrees) is a floating point value.
    **
    *b  Arguments:
    **
    *a    outbuf - a buffer into which to copy the resulting string
    *a    value  - the lat or lon value to be converted into a string
    *a    is_lat - boolean indicating latitude (North/South) rather than
    *a             longitude(East/West)
    *a    is_decimal - boolean indicating that decimal degrees are
    *a                 desired, rather than degrees, minutes, and seconds
    *a    value_is_degrees - boolean indicating whether the input value is
    *a                       in degrees (as opposed to radians)
    */
   virtual void format_lat_or_lon(char* outbuf,
      double value,
      bool is_lat,
      bool is_decimal,
      bool value_is_degrees) = 0;

   /*l
    *b  Description:
    **
    **    Sets the UTM zone of the location currently being used by DI-Guy
    **    networking for the placement of the database origin.  The easting
    **    and northing are assumed not to change.
    **
    *b  Arguments:
    **
    *a    zone - the utm zone
    *a    southzone - pass 1 if the origin is in the southern hemisphere
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_utm_zone(int zone, int southzone) = 0;

   /*l
    *b  Description:
    **
    **    Sets, in UTM coordinates, the location currently being used by
    **    DI-Guy networking for the placement of the database origin.
    **
    *b  Arguments:
    **
    *a    zone      - the utm zone
    *a    southzone - pass 1 if the origin is in the southern hemisphere
    *a    easting   - the normalized (positive only) easting of the database
    *a                origin within the zone
    *a    northing  - the normalized (positive only) northing of the
    *a                database origin within the zone
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_utm(int zone,
      int southzone,
      double easting,
      double northing) = 0;

   /*l
    *b  Description:
    **
    **    Gets, in UTM coordinates, the location currently being used by
    **    DI-Guy networking for the placement of the database origin.
    **
    *b  Arguments:
    **
    *a    zone      - the utm zone, returned
    *a    southzone - 1 if the origin is in the southern hemisphere,
    *a                returned
    *a    easting   - the normalized (positive only) easting of the database
    *a                origin within the zone, returned
    *a    northing  - the normalized (positive only) northing of the
    *a                database origin within the zone, returned
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int get_utm(int* zone,
      int* southzone,
      double* easting,
      double* northing) = 0;

   /*l
    *b  Description:
    **
    **    This function sets whether user-defined latitude/longitude
    **    coordinates should be used for the origin of the database, or the
    **    coordinates that come from graphics files for scenario scene
    **    objects.
    **
    *b  Arguments:
    **
    *a    use_user_defined - pass 1 if user-defined coordinates should be
    *a                       used, 0 if coordinates from graphics file
    *a                       should be used
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_use_user_defined_coords(int use_user_defined) = 0;

   /*l
    *b  Returns:
    **
    **    0 if graphics file coordinates are used,
    **    1 if user-defined coordinates are used
    */
   virtual int get_use_user_defined_coords() = 0;

   /*l
    *b  Description:
    **
    **    Converts a 3d database-origin-relative location into a string
    **    describing it in earth coordinates.  This string could be in a
    **    number of different formats including decimal lat/lon, dms
    **    lat/lon, and UTM.
    **
    *b  Arguments:
    **
    *a    outbuf  - buffer into which to put the output string
    *a    x, y, z - 3 floats specifying location
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure.  Fails if DI-Guy Scenario is not currently
    **    on the network, meaning that a database-to-earth coordinate conversion
    **    cannot be performed.
    */
   virtual int get_earth_coord(char* outbuf,
      const float x,
      const float y,
      const float z) = 0;

   /*l
    *b  Description:
    **
    **    Changes the format of the output of get_earth_coord.  Toggles
    **    between UTM, dms lat/lon, decimal lat/lon, and "punting", meaning
    **    that the caller of get_earth_coord() should fend for itself.  This
    **    generally means that the caller will use database-origin-relative
    **    coordinates.
    */
   virtual void toggle_earth_coord_format() = 0;

   /*l
    *b  Description:
    **
    **    Sets whether networking should use database coordinates or not.
    **    If database coordinates are used, the database origin is placed at
    **    the center of the earth.  This makes coordinate conversion to and
    **    from UTM unnecessary.  Using database coordinates renders
    **    ineffective any UTM-related settings which would position the
    **    database.
    **
    *b  Arguments:
    **
    *a    use_database_coords - 1 if database coordinates should be used,
    *a                          0 otherwise
    **
    *b  Returns:
    **
    **    0 if successful, -1 on failure.
    */
   virtual int set_use_database_coords(int use_dbc) = 0;

   /*l
    *b  Description:
    **
    **    This function returns the number of potential coordinate converters
    **    that the networking module supports.
    **
    *b  Returns:
    **
    **    number of converters
    */
   virtual int get_num_coordinate_systems();

   /*l
    *b  Description:
    **
    **    This function returns the name of the coordinate system at the
    **    specified index.  This is a string representation of a
    **    diguyCoordinateSystemType enumeration.
    **
    *b  Returns:
    **
    **    name of converter
    */
   virtual const char* get_coordinate_system_name(int index);

   /*l
    *b  Description:
    **
    **    Sets the coordinate system based on the name given. Currently
    **    supports: "No Conversion", "UTM", "Flat Earth", "Geocentric".
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure.
    */
   virtual int set_coordinate_system_type(const char* name);

   /*l
    *b  Description:
    **
    **    returns the coordinate system name. Current possible values are
    **    "No Conversion", "UTM", "Flat Earth", "Geocentric".
    **
    *b  Returns:
    **
    **    name of coordinate system type
    */
   virtual const char* get_coordinate_system_type_name();

   /*l
    *b  Description:
    **
    **    Sets the coordinate system based on the system type.
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure.
    */
   virtual int set_coordinate_system_type(diguyCoordinateSystemType system_type);

   /*l
    **
    *b  Description:
    **
    **    Gets the current coordinate system in use.
    **
    *b  Returns:
    **
    **    diguyCoordinateSystemType enumeration
    */
   virtual diguyCoordinateSystemType get_coordinate_system_type();

   /*l
    *b  Description:
    **
    **    Set whether or not to use standard UTM offsets.
    */
   virtual void set_use_UTM_standard_offsets( int standard_offsets );

   /*l
    *b  Description:
    **
    **    Get whether or not to use standard UTM offsets.
    */
   virtual int get_use_UTM_standard_offsets();

   /*l
    *b  Description:
    **
    **    Parses a string of the form
    **
    *-       - [-]d [N|W|S|E]     or
    *-       - [-]d m [N|W|S|E]   or
    *-       - [-]d m s [N|W|S|E]
    **
    **    N and E are taken as positive.  S and W will negate the value
    **    otherwise computed.  d m and s are positive, floating point
    **    values, taken as degrees, minutes, and seconds, respectively.  A
    **    leading minus sign will negate the entire value otherwise computed
    **    (so, e.g., a '-' and a 'S' will result in a double-negation).
    **
    *b  Arguments:
    **
    *a    dms_string - a string of the format described above
    **
    *b  Returns:
    **
    **    a double precision floating point value in radians.
    */
   virtual double parse_dms_to_radians(const char* dms_string) = 0;

   /*l
    *b  Description:
    **
    **    Convert the given MGRS coordinate string to local coordinates.
    */
   virtual int convert_mgrs_to_local( const char* MGRS_str, float* x, float* y, float* z ) = 0;

   /*l
    *b  Description:
    **
    **    Convert the given local coordinates to an MGRS coordinate string.
    */
   virtual const char* convert_local_to_mgrs( float x, float y, float z ) = 0;

   /*l
    *b  Description:
    **
    **    Returns the (float) latitude component of the given local coordinates.
    */
   virtual float convert_local_to_lat( float x, float y, float z ) = 0;

   /*l
    *b  Description:
    **
    **    Returns the (double) latitude component of the given local coordinates.
    */
   virtual double convert_local_to_lat_double( double x, double y, double z ) = 0;

   /*l
    *b  Description:
    **
    **    Returns the (float) longitude component of the given local coordinates.
    */
   virtual float convert_local_to_long( float x, float y, float z ) = 0;

   /*l
    *b  Description:
    **
    **    Returns the (double) longitude component of the given local coordinates.
    */
   virtual double convert_local_to_long_double( double x, double y, double z ) = 0;

   /*l
    *b  Description:
    **
    **    Convert the given local coordinates to a latitude/longitude string.
    */
   virtual const char* convert_local_to_lat_long_string(float x, float y, float z) = 0;

   /*l
    *b  Description:
    **
    **    Convert the given (float) latitude/longitude to local coordinates.
    */
   virtual int convert_lat_long_to_local(float lat, float lon, float* x, float* y, float* z) = 0;

   /*l
    *b  Description:
    **
    **    Convert the given (double) latitude/longitude to local coordinates.
    */
   virtual int convert_lat_long_to_local_double(double lat, double lon, float* x, float* y, float* z) = 0;


/*****************************************************************************/
/**
 *2  Ground Clamp Functions
 */

   /*l
    *b  Description:
    **
    **    Sets whether land-based network entities will be ground clamped,
    **    changing their altitude to better correlate with the local
    **    terrain.
    **
    *b  Arguments:
    **
    *a    enabled - pass 1 to enable automatic ground clamping; 0 to disable
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_ground_clamp_reflected_land_entities_enabled(int enabled);

   /*l
    *b  Returns:
    **
    **    1 if land-based network entities will be ground clamped, 0 if not
    */
   virtual int get_ground_clamp_reflected_land_entities_enabled();

   /*l
    *b  Description:
    **
    **    Similar to set_ground_clamp_reflected_land_entities_enabled(), but
    **    will clamp only entities from the specified host.  If there is one
    **    host on the network that has particular trouble sending correlated
    **    altitudes this function can be used to clamp its entities without
    **    clamping all entities from all hosts.
    **
    **    This has been useful in some simulation exercises where
    **    participants from multiple vendors are in use.  Entities from
    **    JCATS in particular have required this.
    **
    *b  Arguments:
    **
    *a    from_host - host whose land entities will be clamped
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_ground_clamp_reflected_land_entities_from_host(int from_host);

   /*l
    *b  Returns:
    **
    **    host whose land entities will be clamped; see
    **    set_ground_clamp_reflected_land_entities_from_host()
    */
   virtual int get_ground_clamp_reflected_land_entities_from_host();

   /*l
    *b  Description:
    **
    **    Sets the maximum upward change in altitude that ground clamping
    **    will have.
    **
    *b  Arguments:
    **
    *a    max_climb - maximum upward change in altitude, in meters
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_ground_clamp_max_climb(float max_climb);

   /*l
    *b  Returns:
    **
    **    maximum upward change in altitude from ground clamping, in meters
    */
   virtual float get_ground_clamp_max_climb();

   /*l
    *b  Description:
    **
    **    Similar to set_ground_clamp_max_climb(), but for downward change.
    */
   virtual int set_ground_clamp_max_drop(float max_drop);

   /*l
    *b  Returns:
    **
    **    maximum downward change in altitude from ground clamping, in
    **    meters
    */
   virtual float get_ground_clamp_max_drop();

   virtual void set_translation_threshold(float value);
   virtual float get_translation_threshold();

   virtual void set_z_velocity_threshold(float value);
   virtual float get_z_velocity_threshold();

   virtual void set_rotation_threshold(float value);
   virtual float get_rotation_threshold();

/****************************************************************************/
/**
 *2  Network Time Functions
 */

   /*l
    *b  Description:
    **
    **    Sets whether network datetime data will be broadcast, received, or
    **    ignored.  See documentation for diguyDatetimeNetworkMode for more
    **    information.
    **
    *b  Arguments:
    **
    *a    network_datetime_mode - how to handle network datetime data
    */
   virtual void set_network_datetime_mode(diguyDatetimeNetworkMode network_datetime_mode);

   /*l
    *b  Returns:
    **
    **    how handle network datetime data will be handled; see
    **    set_network_datetime_mode().
    */
   virtual diguyDatetimeNetworkMode get_network_datetime_mode();

   /*l
    *b  Description:
    **
    **    Sets how often datetime data will be broadcast if this host is
    **    in mode DIGUY_DATETIME_NETWORK_MODE_BROADCAST.
    **
    **    Default is broadcast every 5 seconds.
    **
    *b  Arguments:
    **
    *a    broadcast_interval - how often to broadcast datetime data, in
    *a                         seconds
    */
   virtual void set_network_datetime_broadcast_interval(float broadcast_interval);

   /*l
    *b  Returns:
    **
    **    how often datetime data will broadcast, in seconds
    */
   virtual float get_network_datetime_broadcast_interval();


/****************************************************************************/
/**
 *2  Sync Mode Functions
 **
 **    These functions enable DI-Guy to do pseudo frame syncing across
 **    multiple machines.
 */
/****************************************************************************/

   /*l
    *b  Description:
    **
    **    Sets whether sync mode will be enabled when online.
    **
    **    The function will fail if DI-Guy is already online, participating
    **    in an exercise.
    **
    *b  Arguments:
    **
    *a    enabled - pass 1 if sync mode should be enabled when online,
    *a              0 if not
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_sync_mode_enabled(int enabled) = 0;

   /*l
    *b  Description:
    **
    **    Gets whether sync mode is enabled when online.
    **
    *b  Returns:
    **
    **    1 if sync mode is enabled when online, 0 if not
    */
   virtual int get_sync_mode_enabled() = 0;

   /*l
    *b  Description:
    **
    **    Sets whether this machine will serve as sync master when online
    **    and in sync mode.
    **
    *b  Arguments:
    **
    *a    master - pass 1 if this machine will serve as sync master when
    *a             online and in sync mode, 0 if not
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_sync_mode_master(int master) = 0;

   /*l
    *b  Description:
    **
    **    Gets whether this machine will serve as sync master when online
    **    and in sync mode.
    **
    *b  Returns:
    **
    **    1 if this machine will serve as sync master when online
    **    and in sync mode, 0 if not
    */
   virtual int get_sync_mode_master() = 0;

   /*l
    *b  Description:
    **
    **    Sets whether this machine's camera will be slaved to a remote
    **    master when online and in sync mode and not sync master.
    **
    **    The function will fail if DI-Guy is already online, participating
    **    in an exercise.
    **
    *b  Arguments:
    **
    **    sl_cam - pass 1 if this machine's camera will be slaved to a
    **             remote master when online and in sync mode and not sync
    **             master, 0 if not
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_sync_mode_slave_cam(int sl_cam) = 0;

   /*l
    *b  Description:
    **
    **    Gets whether this machine's camera will be slaved to a remote
    **    master when online, in sync mode, and not sync master.
    **
    *b  Returns:
    **
    **    1 if this machine's camera will be slaved, 0 if not
    */
   virtual int get_sync_mode_slave_cam() = 0;

   /*l
    *b  Description:
    **
    **    This function sets the camera orientation offset to be used in
    **    sync_mode (when VR-Link is online).
    **
    *b  Arguments:
    **
    *a    offset_r - orientation offset
    *a    offset_y - orientation offset
    *a    offset_p - orientation offset
    **
    **    yaw and pitch represent PERCENTAGES of the camera's
    **    horizontal and vertical field of view, respectively.  The
    **    ROLL (which is in degrees) is applied first, then the yaw,
    **    then the pitch.
    **
    **    A typical two screen arrangement would use yaws of 50 and -50 for the
    **    left screen, and right screen, respectively.  For three screens, the
    **    yaws would be -100, 0, and 100.
    **
    **    Using percentages this way makes the screens contiguous even if the
    **    camera's field of view changes.
    **
    **    THIS FUNCTION DOES NOTHING (and returns -1) if called while VR-Link is
    **    online
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure (VR-Link is online).
    */
   virtual int set_sync_mode_camera_offset(float offset_r, float offset_y, float offset_p) = 0;

   /*l
    *b  Description:
    **
    **    This function gets the camera orientation offset to be used in
    **    sync_mode (when VR-Link is online).
    **
    *b  Arguments:
    **
    *a    offset_r - orientation offset
    *a    offset_y - orientation offset
    *a    offset_p - orientation offset
    **
    **    yaw and pitch represent PERCENTAGES of the camera's
    **    horizontal and vertical field of view, respectively.  The
    **    ROLL (which is in degrees) is applied first, then the yaw,
    **    then the pitch.
    **
    **    In the orientation offset the yaw and pitch
    **    represent PERCENTAGES of the camera's horizontal and vertical field
    **    of view, respectively.  The ROLL (which is in degrees) is applied
    **    first, then the yaw, then the pitch.
    **
    **    A typical two screen arrangement would use yaws of 50 and -50 for the
    **    left screen, and right screen, respectively.  For three screens, the
    **    yaws would be 100, 0, and -100 going from left to right.
    **
    **    Using percentages this way makes the screens contiguous even if the
    **    camera's field of view changes.
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int get_sync_mode_camera_offset(float* offset_r,
      float* offset_y,
      float* offset_p) = 0;

   /*l
    *b  Description:
    **
    **    This function sets whether the camera will be slaved when VR-Link is
    **    online, in sync mode, and not sync master.
    **
    **    It can be set even when VR-Link is online.
    **
    *b  Arguments:
    **
    *a    slaved   - whether the camera will be slaved when VR-Link is
    **               online, in sync mode, and not sync master.
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_sync_mode_camera_slaved(int slaved) = 0;

   /*l
    *b  Description:
    **
    **    This function gets whether the camera is currently slaved.  It does
    **    NOT simply return what was passed to set_sync_mode_camera_slaved().
    **
    *b  Returns:
    **
    **    Whether the camera is currently slaved.  This will be 1 only if
    **    VR-link is online, is in sync mode, and is not the sync master, and if
    **    sync_mode_camera_slaved has been set to 1.
    */
   virtual int get_sync_mode_camera_slaved() = 0;

   /*l
    *b  Description:
    **
    **    Lets VR-Link know that the user has moved the camera, so that if
    **    it is in sync mode, and is the sync master, it can let other hosts
    **    know the new camera position so they can move their cameras.
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_camera_details_out_of_date() = 0;


   /*l
    *b  Description:
    **
    **    Lets DI-Guy know that it should use an adaptive guide that attempts
    **    to fix reckoning errors by stepping. Defaults to on.
    **
    *b  Returns:
    **
    **    0 on success, -1 on failure
    */
   virtual int set_use_adaptive_guide(int use_adaptive_guide) = 0;

   /*l
    *b  Returns:
    **
    **    0 if adaptive guide is disabled 1 otherwise.
    */
   virtual int get_use_adaptive_guide() = 0;


/****************************************************************************/
/****************************************************************************/
/*****************************************************************************/
/**
 *2  Experimental Functions
 **
 **  The following functions are experimental and may change or
 **   disappear with no warning.
 */
/****************************************************************************/
/****************************************************************************/
/****************************************************************************/

   virtual int set_fom_file_name(const char* file_name);
   virtual const char* get_fom_file_name();

   virtual int set_base_module_name(const char* file_name);
   virtual const char* get_base_module_name();

   virtual int set_rpr_fom_version( float version );
   virtual float get_rpr_fom_version() const;

   virtual int set_rpr_fom_revision( int revision );
   virtual int get_rpr_fom_revision() const;

   virtual int set_culling_enabled(int culling);
   virtual int get_culling_enabled();

   /*l
    *b  Description:
    **
    **    Sets whether network datetime data will be broadcast via custom
    **    PDUs.
    **
    **    *NOTE:*  This is functionality that is under development and
    **    should currently not be used by non DI-Guy programmers.
    **
    *b  Arguments:
    **
    *a    enable_diguy_custom_pdus - pass 1 to broadcast network datetime
    *a                               data via custom PDUs, 0 to not
    */
   virtual void set_network_datetime_enable_diguy_custom_pdus(int enable_diguy_custom_pdus);

   /*l
    *b  Returns:
    **
    **    1 if network datetime data will be broadcast via custom PDUs, 0 if
    **    not
    */
   virtual int  get_network_datetime_enable_diguy_custom_pdus();

   /*l
    *b  Description:
    **
    **    Sets whether this host will send DIS standard start/resume PDUs.
    **
    **    *NOTE:*  This is functionality that is under development and
    **    should currently not be used by non DI-Guy programmers.
    **
    *b  Arguments:
    **
    *a    enable_dis_start_resume_pdus - pass 1 to send DIS start/resume
    *a                                   PDUs, 0 to not
    */
   virtual void set_network_datetime_enable_dis_start_resume_pdus(int enable_dis_start_resume_pdus);

   /*l
    *b  Returns:
    **
    **    1 if DIS start/resume should be send, 0 if not
    */
   virtual int  get_network_datetime_enable_dis_start_resume_pdus();

   //! Turns on/off laser designator effects
   virtual int set_draw_laser_designators_effects(int enabled) = 0;
   virtual int get_draw_laser_designators_effects() = 0;

   //! turns on/off laser designator drawing, effects are still updated (meant for sensor fusion)
   virtual int set_laser_designators_effects_visible(int visible) = 0;

   //! turns on/off laser designator line drawing
   virtual int set_draw_laser_designators_lines(int enabled) = 0;
   virtual int get_draw_laser_designators_lines() = 0;

   //! turns on/off use of 0 as wildcard in munition_types.cfg septet mapping
   virtual int set_use_wildcards_in_munitions_map(int enabled) = 0;
   virtual int get_use_wildcards_in_munitions_map() = 0;


/**
 *x  The functions and variables past this point are for internal use only.
 **   No external access to them is expected or necessary.
 */

   /*l
    **   internal functions
    */
   virtual void* get_connect_function() const = 0;
   virtual void read_config_info() = 0;
   virtual void write_config_info() = 0;
   virtual int server_mode() = 0;
   virtual int client_mode() = 0;
   virtual void establish_new_offsets() = 0;
   virtual void draw() = 0;
   virtual bdiDataTracker* get_network_datetime_data_tracker() = 0;

public:

   diguyNetInterfaceData* get_data() {return m_data;}

protected:

   diguyNetInterfaceData* m_data;

   virtual int update_coordinate_sytem() = 0;
   virtual int update_settings() = 0;
   /*l
    **    A private constructor.  Use the DI-Guy function
    **    diguy_module_net_initialize() to create a diguyNetInterface.  Use
    **    get_net_interface() to obtain a pointer to it.
    */
   diguyNetInterface();

   /*l
    **    A private destructor.  Use the DI-Guy function
    **    diguy_module_net_deinitialize() to destroy the diguyNetInterface.
    */
   virtual ~diguyNetInterface();

   friend BDI_DECLSPEC_diguy int diguy_module_net_initialize();

};
