/*
*   DSFML - SFML Library binding in D language.
*   Copyright (C) 2008 Julien Dagorn (sirjulio13@gmail.com)
*
*   This software is provided 'as-is', without any express or
*   implied warranty. In no event will the authors be held
*   liable for any damages arising from the use of this software.
*
*   Permission is granted to anyone to use this software for any purpose,
*   including commercial applications, and to alter it and redistribute
*   it freely, subject to the following restrictions:
*
*   1.  The origin of this software must not be misrepresented;
*       you must not claim that you wrote the original software.
*       If you use this software in a product, an acknowledgment
*       in the product documentation would be appreciated but
*       is not required.
*
*   2.  Altered source versions must be plainly marked as such,
*       and must not be misrepresented as being the original software.
*
*   3.  This notice may not be removed or altered from any
*       source distribution.
*/

module dsfml.network.ipaddress;

import dsfml.system.common;
import dsfml.system.stringutil;

/**
*   IPAddress provides easy manipulation of IP v4 addresses
*/
struct IPAddress
{
    /**
    *   Construct the address from a string
    *
    *   Params: 
    *       address = IP address ("xxx.xxx.xxx.xxx") or network name
    *
    */
    static IPAddress opCall(char[] address)
    {
        return sfIPAddress_FromString(toStringz(address));
    }


    /**
    *   Construct the address from 4 bytes
    *
    *   Params:
    *       byte0 = First byte of the address
    *       byte1 = Second byte of the address
    *       byte2 = Third byte of the address
    *       byte3 = Fourth byte of the address
    *
    */
    static IPAddress opCall(ubyte byte0, ubyte byte1, ubyte byte2, ubyte byte3)
    {
        return sfIPAddress_FromBytes(byte0, byte1, byte2, byte3);
    }

    /**
    *   Construct the address from a 32 bits integer
    *
    *   Params:
    *       address = 4 bytes of the address packed into a 32 bits integer
    *
    */
    static IPAddress opCall(uint address)
    {
        return sfIPAddress_FromInteger(address);
    }

    /**
    *   Tell if the address is a valid one
    *
    *   Returns: 
    *       True if address has a valid syntax
    *
    */
    bool isValid()
    {
        return cast(bool)sfIPAddress_IsValid(*this);
    }
   
    /**
    *   Get the computer's local IP address (from the LAN point of view)
    *
    *   Returns: 
    *       Local IP address
    *
    */
    static IPAddress getLocalAddress()
    {
        return sfIPAddress_GetLocalAddress();
    }

    /**
    *   Get the computer's public IP address (from the web point of view).
    *   The only way to get a public address is to ask it to a
    *   distant website ; as a consequence, this function may be
    *   very slow -- use it as few as possible !
    *
    *   Returns: 
    *         Public IP address
    *
    */
    static IPAddress getPublicAddress()
    {
        return sfIPAddress_GetPublicAddress();
    }

    bool opEqual(IPAddress other) 
    {
        return Address == other.Address;
    }

    /**
    *   Local host address (to connect to the same computer). 
    */   
    static IPAddress LOCALHOST()
    {
        return sfIPAddress_LocalHost();
    }
 
    byte[16] Address;
    
}

private:

extern (C)
{
    typedef IPAddress function(char*) pf_sfIPAddress_FromString;
	typedef IPAddress function(ubyte, ubyte, ubyte, ubyte) pf_sfIPAddress_FromBytes;
	typedef IPAddress function(uint) pf_sfIPAddress_FromInteger;
	typedef int function(IPAddress) pf_sfIPAddress_IsValid;
	typedef IPAddress function() pf_sfIPAddress_GetLocalAddress;
	typedef IPAddress function() pf_sfIPAddress_GetPublicAddress;
	typedef IPAddress function() pf_sfIPAddress_LocalHost;

	static pf_sfIPAddress_FromString sfIPAddress_FromString;
	static pf_sfIPAddress_FromBytes sfIPAddress_FromBytes;
	static pf_sfIPAddress_FromInteger sfIPAddress_FromInteger;
	static pf_sfIPAddress_IsValid sfIPAddress_IsValid;
	static pf_sfIPAddress_GetLocalAddress sfIPAddress_GetLocalAddress;
	static pf_sfIPAddress_GetPublicAddress sfIPAddress_GetPublicAddress;
	static pf_sfIPAddress_LocalHost sfIPAddress_LocalHost;
}

static this()
{
    DllLoader dll = DllLoader.load("csfml-network");
    
    sfIPAddress_FromBytes = cast(pf_sfIPAddress_FromBytes)dll.getSymbol("sfIPAddress_FromBytes");
    sfIPAddress_FromString = cast(pf_sfIPAddress_FromString)dll.getSymbol("sfIPAddress_FromString");
    sfIPAddress_FromInteger = cast(pf_sfIPAddress_FromInteger)dll.getSymbol("sfIPAddress_FromInteger");
    sfIPAddress_GetLocalAddress = cast(pf_sfIPAddress_GetLocalAddress)dll.getSymbol("sfIPAddress_GetLocalAddress");
    sfIPAddress_GetPublicAddress = cast(pf_sfIPAddress_GetPublicAddress)dll.getSymbol("sfIPAddress_GetPublicAddress");
    sfIPAddress_IsValid = cast(pf_sfIPAddress_IsValid)dll.getSymbol("sfIPAddress_IsValid");
    sfIPAddress_LocalHost = cast(pf_sfIPAddress_LocalHost)dll.getSymbol("sfIPAddress_LocalHost");
}