/*
 * Copyright 2014 Hans Leidekker for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

import "oaidl.idl";
import "objidl.idl";

#ifndef __WIDL__
#define threading(model)
#endif

interface IEnumNetworks;
interface IEnumNetworkConnections;
interface INetwork;
interface INetworkConnection;
interface INetworkCostManager;
interface INetworkListManager;
interface INetworkListManagerEvents;

typedef [v1_enum] enum NLM_CONNECTIVITY
{
    NLM_CONNECTIVITY_DISCONNECTED      = 0x0000,
    NLM_CONNECTIVITY_IPV4_NOTRAFFIC    = 0x0001,
    NLM_CONNECTIVITY_IPV6_NOTRAFFIC    = 0x0002,
    NLM_CONNECTIVITY_IPV4_SUBNET       = 0x0010,
    NLM_CONNECTIVITY_IPV4_LOCALNETWORK = 0x0020,
    NLM_CONNECTIVITY_IPV4_INTERNET     = 0x0040,
    NLM_CONNECTIVITY_IPV6_SUBNET       = 0x0100,
    NLM_CONNECTIVITY_IPV6_LOCALNETWORK = 0x0200,
    NLM_CONNECTIVITY_IPV6_INTERNET     = 0x0400
} NLM_CONNECTIVITY;

typedef [v1_enum] enum NLM_ENUM_NETWORK
{
    NLM_ENUM_NETWORK_CONNECTED    = 0x01,
    NLM_ENUM_NETWORK_DISCONNECTED = 0x02,
    NLM_ENUM_NETWORK_ALL          = 0x03
} NLM_ENUM_NETWORK;

typedef [v1_enum] enum NLM_CONNECTION_COST
{
    NLM_CONNECTION_COST_UNKNOWN              = 0x0,
    NLM_CONNECTION_COST_UNRESTRICTED         = 0x1,
    NLM_CONNECTION_COST_FIXED                = 0x2,
    NLM_CONNECTION_COST_VARIABLE             = 0x4,
    NLM_CONNECTION_COST_OVERDATALIMIT        = 0x10000,
    NLM_CONNECTION_COST_CONGESTED            = 0x20000,
    NLM_CONNECTION_COST_ROAMING              = 0x40000,
    NLM_CONNECTION_COST_APPROACHINGDATALIMIT = 0x80000
} NLM_CONNECTION_COST;

typedef struct NLM_SOCKADDR
{
    BYTE data[128];
} NLM_SOCKADDR;

typedef struct NLM_USAGE_DATA
{
    DWORD    UsageInMegabytes;
    FILETIME LastSyncTime;
} NLM_USAGE_DATA;

typedef struct NLM_DATAPLAN_STATUS
{
    GUID           InterfaceGuid;
    NLM_USAGE_DATA UsageData;
    DWORD          DataLimitInMegabytes;
    DWORD          InboundBandwidthInKbps;
    DWORD          OutboundBandwidthInKbps;
    FILETIME       NextBillingCycle;
    DWORD          MaxTransferSizeInMegabytes;
    DWORD          Reserved;
} NLM_DATAPLAN_STATUS;

[
    object,
    pointer_default(unique),
    uuid(dcb00008-570f-4a9b-8d69-199fdba5723b)
]
interface INetworkCostManager : IUnknown
{
    HRESULT GetCost(
        [out] DWORD *pCost,
        [in, unique] NLM_SOCKADDR *pDestIPAddr);

    HRESULT GetDataPlanStatus(
        [out] NLM_DATAPLAN_STATUS *pDataPlanStatus,
        [in, unique] NLM_SOCKADDR *pDestIPAddr);

    HRESULT SetDestinationAddresses(
        [in] UINT32 length,
        [in, unique, size_is(length)] NLM_SOCKADDR *pDestIPAddrList,
        [in] VARIANT_BOOL bAppend);
}

[
    dual,
    object,
    oleautomation,
    pointer_default(unique),
    uuid(dcb00000-570f-4a9b-8d69-199fdba5723b)
]
interface INetworkListManager : IDispatch
{
    HRESULT GetNetworks(
        [in] NLM_ENUM_NETWORK Flags,
        [out, retval] IEnumNetworks **ppEnumNetwork);

    HRESULT GetNetwork(
        [in] GUID gdNetworkId,
        [out, retval] INetwork **ppNetwork);

    HRESULT GetNetworkConnections(
        [out, retval] IEnumNetworkConnections **ppEnum);

    HRESULT GetNetworkConnection(
        [in] GUID gdNetworkConnectionId,
        [out, retval] INetworkConnection **ppNetworkConnection);

    HRESULT IsConnectedToInternet(
        [out, retval] VARIANT_BOOL *pbIsConnected);

    HRESULT IsConnected(
        [out, retval] VARIANT_BOOL *pbIsConnected);

    HRESULT GetConnectivity(
        [out, retval] NLM_CONNECTIVITY *pConnectivity);
}

[
    threading(both),
    uuid(dcb00c01-570f-4a9b-8d69-199fdba5723b)
]
coclass NetworkListManager { interface INetworkListManager; }

[
    object,
    oleautomation,
    pointer_default(unique),
    uuid(DCB00001-570F-4A9B-8D69-199FDBA5723B)
]
interface INetworkListManagerEvents : IUnknown
{
    HRESULT ConnectivityChanged(
        [in] NLM_CONNECTIVITY newConnectivity);
}
