/**
 * @file
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 *
 * This file is part of The iWear Framework.
 *
 * The iWear Framework is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by the
 * Free Software Foundation as in version 2 of the License.

 * 
 * The iWear Framework 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 General Public License for
 * more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __IWEAR_IPADDRESS_H
#define __IWEAR_IPADDRESS_H

extern "C" {
#include <sys/types.h>
#include <sys/socket.h>
}
#include <string>

struct addrinfo;
namespace iwear
{
    namespace net
    {
enum ip_version 
{ 
    IPAny = 0, 
    IPv4 = PF_INET, 
    IPv6 = PF_INET6,
    IPLocal = PF_UNIX
};

/** 
 * This class is a Base for possible IP Address types. With a static function
 * it will be able to produce the proper IPAdress that fits, transparently to
 * the user.
 *
 * This is quite usefull in case you want to have connection etc. function you
 * just pass an address you got from who knows where and you dont want to
 * bother about whether v4 or v6
 */

class IPAddress
{
private:
protected:
   /**
    * This indicates what kind of IP Address this is.
    */
    ip_version ipver;

   /**
    * If available, the System will do a reverse lookup on the IP Address it
    * got, and save it here. If this is not possible, the originally string
    * will be saved here.
    */
    std::string resolved_address;

    IPAddress( );
    IPAddress( ip_version ipv);
public:

    virtual ~IPAddress( ) { }
    const std::string& get_hostname( void ) const { return resolved_address; }

    ip_version get_family( void ) const { return ipver; }
   /**
    * This creates a new IP Adress out of the grey ;)
    * It will resolve the given name. If it does not resolve, it will throw an
    * exception.
    *
    * @param host Is the Hostname that should be resolved to an address. It
    * might also be an IP Adress as a string, which will then just be
    * converted.
    * @param preference Is the preference on what Address you will get. If you
    * prefer IPv4 but only IPv6 is available, then you will get an exception.
    * @param strict is to be set to true in case the preferenc should be obeyed
    * strictly. So if the desired address format cannot be found, an exception
    * will thrown. If strict == false then an exception will only be thrown in
    * case both formats were not found.
    *
    * @note in IPAny preference, IPv6 always has precedence !
    */
    static IPAddress* create_address( const std::string& host, ip_version preference = IPAny, bool strict = false );

    static void display_addrinfo( const addrinfo* res, int d );

    static std::pair<std::string,uint16_t> canonicalize( const std::string& opip );
};

}
}
#endif
