/*
This Work is under GPL provided with this work.

This work is based on the java implementation of the Kademlia protocol.
Kademlia: Peer-to-peer routing based on the XOR metric
Copyright (C) 2002  Petar Maymounkov [petar@post.harvard.edu]
http://kademlia.scs.cs.nyu.edu
and
This work is bassed on translation from Barry Dunne to C++
Copyright (C)2003 Barry Dunne (http://www.emule-project.net)
*/

#ifndef cZone_h
#define cZone_h
#include "cygwin.h"
#include "cBucket.h"
class cZone {
	time_t 		  m_nextBigTimer;
	time_t 		  m_nextSmallTimer;
	class cZone 	 *m_subZones[2];
	class cZone 	 *m_superZone;
	unsigned 	  m_level;		// This Zone represent 1/(2^n) of the whole adress space
	uint8_t 	  m_zoneIndex[16];
	class cBucket	 *m_bin;
	time_t 	  	  smallTimer;
	public:
			 ~cZone		();
			  cZone		();
			  cZone		(class cZone *super_zone, int level, const uint8_t *zone_index);
	void 		  init 		(class cZone *super_zone, int level, const uint8_t *zone_index);
	bool		  canSplit	(void) const;
	bool		  areWeInFirstSubtreeOfEnoughSize(void) const;
	size_t		  getNumContacts(void) const;
inline	bool      	  isLeaf        (void) const { return (m_bin != NULL); }
	void		  consolidate	(void);
	bool		  add		(const uint8_t *ID, uint32_t ip, uint16_t UDP, uint8_t TYPE);
	bool 		  contains	(const uint8_t *id) const;
	const class cPeer*getContact	(const uint8_t *id) const;
	size_t		  getClosestTo	(const uint8_t *id, size_t maxRequired, cPeerMap *result, bool emptyFirst=true) const;
	void 		  split		(void);
	void 		  merge		(void);
	class cZone 	 *genSubZone	(int side);
	void 		  setAlive	(uint32_t ip, uint16_t port);
	size_t 		  getApproximateNodeCount(size_t ourLevel) const;
	void 		  randomLookup	(void);
	void		  onBigTimer	(void);
	void 		  onSmallTimer	(void);
	size_t 		  getMaxDepth	(void) const;
	void		  randomBin	(cPeerList *result, bool emptyFirst);
	void		  getAllEntries	(cPeerList *result, bool emptyFirst = true);
	void 		  topDepth	(int depth, cPeerList *result, bool emptyFirst = true);
	size_t 		  getBootstrapContacts(cPeerList *results, size_t maxRequired);
	void 		  dumpContents	(const char *prefix = NULL) const;
	void 		  writeFile	(void);
	void		  readFile	(void);

	};
#endif
