/***************************************************************************
*   Copyright (C) 2006 by Ian Reinhart Geiser   *
*   geiseri@sourcextreme.com   *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU Library General Public License as       *
*   published by the Free Software Foundation; either version 2 of the    *
*   License, or (at your option) any later version.                       *
*                                                                         *
*   This program 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 Library General Public     *
*   License along with this program; if not, write to the                 *
*   Free Software Foundation, Inc.,                                       *
*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
***************************************************************************/
#include "basicnode.h"
#include "nodeid.h"
#include "qdebug.h"

namespace KRPC
{
}

KRPC::BasicNode::BasicNode(const QHostAddress &host, unsigned port ) : NodeInterface( host,port )
	{}


KRPC::BasicNode::~BasicNode()
	{}


KRPC::NodeInterface *KRPC::BasicNode::find( const NodeID& targetKey ) const
{
	if( key() == targetKey )
	{
		return get(key());
	}
	else if( hasKey(targetKey) )
	{
		return get(targetKey);
	}
	else if( key() < targetKey )
	{
		if( key() == lowerKey() )
			return upper()->find(targetKey);
		else
			return lower()->find(targetKey);
	}
	else if( key() > targetKey )
	{
		if( key() == upperKey() )
			return lower()->find(targetKey);
		else
			return upper()->find(targetKey);

	}
	else qDebug() << "Not found " << targetKey.toString();
	return 0;
}

KRPC::NodeInterface *KRPC::BasicNode::lower() const
{
	return get(lowerKey());
}

KRPC::NodeInterface *KRPC::BasicNode::predecessor() const
{
	return get(previousKey());
}

KRPC::NodeInterface *KRPC::BasicNode::successor() const
{
	return get(nextKey());
}

KRPC::NodeInterface *KRPC::BasicNode::upper() const
{
	return get(upperKey());
}

void KRPC::BasicNode::join( NodeInterface *parent )
{
	put( key(), this);

	if( parent )
	{
		bindNode( parent );
		bindNode( parent->upper() );
		bindNode( parent->lower() );
		bindNode( parent->predecessor() );
		bindNode( parent->successor() );
	}
}

void KRPC::BasicNode::bindNode( NodeInterface *node )
{
	if( node )
	{
		node->put(key(), this );
		put(node->key(), node);
	}
}


