/***************************************************************************
*   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 "nodereference.h"
#include "nodeinterface.h"

namespace KRPC
{
	struct Tracker
	{
	Tracker( NodeInterface *ptr, bool weak) :
		m_ptr(ptr), m_count(1), m_dontManage(weak)
		{
		}
		NodeInterface *m_ptr;
		unsigned int m_count;
		bool m_dontManage;
	};
}

KRPC::NodeReference::NodeReference( NodeInterface * ptr, bool weak )
: m_tracker(0)
{
	if( ptr != 0 )
	{
		m_tracker = new Tracker(ptr,weak);
	}
}

KRPC::NodeReference::~NodeReference( )
{
	release();
}

KRPC::NodeReference::NodeReference( const NodeReference & rhs )
{
	if( this != &rhs)
	{
		release();
		aquire( rhs.m_tracker);
	}
}

KRPC::NodeReference &KRPC::NodeReference::operator =( const NodeReference & rhs )
{
	if( this != &rhs )
	{
		release();
		aquire( rhs.m_tracker );
	}
	return *this;
}

KRPC::NodeInterface * KRPC::NodeReference::operator ->( ) const
{
	if( m_tracker == 0 )
		return 0;
	return m_tracker->m_ptr;
}

bool KRPC::NodeReference::isValid( ) const
{
	if( m_tracker == 0)
		return false;
	if( m_tracker->m_ptr == 0)
		return false;
	return true;
}

void KRPC::NodeReference::aquire( Tracker * tracker ) const
{
	m_tracker = tracker;
	if( m_tracker )
		++(m_tracker->m_count);
}

void KRPC::NodeReference::release( ) const
{
	if( isValid() )
	{
		if( --(m_tracker->m_count ) == 0 )
		{
			if( m_tracker->m_dontManage == false)
				delete m_tracker->m_ptr;
			delete m_tracker;
		}
// 		m_tracker = 0;
	}
}







