#include "stdafx.h"

Router::Router()
{
	extra_data = 0;
	for( int i=0 ; i<MAX_CONNECTIONS_PER_ROUTER ; i++ )
		connections[i] = 0;
	packets_to_route = new PacketsBuffer(500);
}

Router::Router( const RouterPosition & par )
{
	extra_data = 0;
	for( int i=0 ; i<MAX_CONNECTIONS_PER_ROUTER ; i++ )
		connections[i] = 0;
	packets_to_route = new PacketsBuffer(500);
	position = par;
}

Router::~Router()
{
	if( extra_data )
		delete extra_data;
	delete packets_to_route;
}

void Router::SetPosition( const RouterPosition & position_par )
{
	position = position_par;
}
		
bool Router::operator == ( const Router & other ) const
{
	return position == other.position;
}

bool Router::operator != ( const Router & other ) const
{
	return position != other.position;
}

// routing function
int Router::GetCapacity() const
{
	return packets_to_route->GetCapacity();
}

int Router::GetLoad() const
{
	return packets_to_route->GetLoad();
}

bool Router::SetPacketToRoute( Packet * packet )
	// false if full
{
	return packets_to_route->Push( packet );
}

Packet * Router::GetNextPacketToRoute()
// 0 if none
{
	return packets_to_route->Pop();
}

bool Router::SendPacket( Packet * packet , Router & destination )
{
	Connection & connection = GetConnection( destination );

	if( connection.GetA() == *this )
		return connection.PutOnePacketToA( packet );
	else if ( connection.GetB() == *this )
		return connection.PutOnePacketToB( packet );
	else
		throw( "" );
}

void Router::RemoveAllPackets()
{
	packets_to_route->Clear();
}

// connection 
void Router::AddConnection( Connection & connection )
{
	int index = 0;
	while( index < MAX_CONNECTIONS_PER_ROUTER && 
		   connections[index] != 0 )
		index++;
	
	assert( index < MAX_CONNECTIONS_PER_ROUTER );

	connections[index] = &connection;
}

void Router::RemoveConnection( Connection & connection )
{
	int index = 0;
	while( index < MAX_CONNECTIONS_PER_ROUTER && 
		   *connections[index] != connection )
		index++;
	
	assert( index < MAX_CONNECTIONS_PER_ROUTER );

	connections[index] = 0;
}

int Router::GetConnectionNum() const
{
	int index = 0;
	while( index < MAX_CONNECTIONS_PER_ROUTER && 
		   connections[index] != 0 )
		index++;
	
	return index;
}

Connection & Router::GetConnection( int index )
{
	assert( index < MAX_CONNECTIONS_PER_ROUTER );
	assert( connections[index] != 0 );
	
	return *connections[index];
}

Connection & Router::GetConnection( Router & destination )
{
	int index = 0;
	while( index < MAX_CONNECTIONS_PER_ROUTER		 && 
		   connections[index] != 0					 &&
		   connections[index]->GetA() != destination &&
		   connections[index]->GetB() != destination )
		index++;

	assert( index < MAX_CONNECTIONS_PER_ROUTER );
	assert( connections[index] != 0 );

	return *connections[index];

}

void Router::SetExtraData( RouterExtraData * new_extra_data )
{
	if( extra_data )
		delete extra_data;
	extra_data = new_extra_data;
}

bool Connection::operator == ( const Connection & other ) const
{
	assert( a && b && other.a && other.b );
	
	return ( *a == *other.a && *b == *other.b );
}

bool Connection::operator != ( const Connection & other ) const
{
	assert( a && b && other.a && other.b );

	return ( *a != *other.a || *b != *other.b );
}

