#ifndef _IPADDRESS_H_
#define _IPADDRESS_H_

#include <Core/Core.h>

using namespace Upp;

#ifndef PLATFORM_WIN32
	#include <arpa/inet.h>
#endif

class IPV4Address : Moveable<IPV4Address>
{
	private:
	
		uint32_t _addr;
	
	protected:
	
	public:
	
		// constructors
		IPV4Address() { _addr = 0; }
		IPV4Address(String const &addr) { _addr = inet_addr(addr); }
		IPV4Address(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { _addr = ((uint32_t)d << 24) | ((uint32_t)c << 16) | ((uint32_t)b << 8) | (uint32_t)a; }
		IPV4Address(uint32_t addr) { _addr = addr; }
		
		operator uint32_t() const { return _addr; }
		operator unsigned long() const { return _addr; }
		String ToString(void) const { return Format("%d.%d.%d.%d", (int)(_addr & 0xff), (int)((_addr >> 8) & 0xff), (int)((_addr >> 16) & 0xff), (int)((_addr >> 24) & 0xff)); }
		
		uint32_t operator=(uint32_t i) { _addr = i; return i; }
		bool operator==(IPV4Address const &a) const { return _addr == a._addr; }
		bool operator!=(IPV4Address const &a) const { return _addr != a._addr; }
		
		uint8_t operator[](int idx) const { if(idx < 4) return ((uint8_t *)&_addr)[idx]; else return 0xff; }
};

class IPV6Address : Moveable<IPV6Address>
{
	private:
		uint16_t _addr[8];
	
	protected:
	
	public:
	
		// constructors
		IPV6Address(uint16_t const *addr);
		IPV6Address(const char *addr);
		IPV6Address(IPV6Address const &addr);
		
		String ToString(void) const;
		IPV6Address &operator=(IPV6Address const &a);
		bool operator==(IPV6Address const &a) const;
};

#endif
