/*******************************************************************
*
*  DESCRIPTION: class NeighborhoodValue
*
*  AUTHOR:    Amir Barylko, Jorge Beyoglonian
*  Version 2: Daniel Rodriguez
*
*  EMAIL: mailto://amir@dc.uba.ar
*         mailto://jbeyoglo@dc.uba.ar
*         mailto://drodrigu@dc.uba.ar
*
*  DATE: 27/06/1998
*  DATE: 02/06/1999 (v2)
*
*******************************************************************/


// ** include files **//
#include <neighval.h>		// base header
#include <cellstate.h>		// class CellState

// ** private data ** //             
Real NeighborhoodValue::undef = Real();

// ** public ** //
NeighborhoodValue &NeighborhoodValue::set( const Real &v )
{
	NeighborPosition	np(dim,0);

	sneighborList->setRealValue( np, v);
	return *this;
}

/*******************************************************************
* Method: NeighborhoodValue
* Description: Constructor
********************************************************************/
NeighborhoodValue::NeighborhoodValue( CellState &mat, const CellPositionList &neighbors, const CellPosition &center) 
: dim( mat.dimension().dimension() )
{
	CellPosition	pos;

	sneighborList = new mList;

	centralCell = center;

	// establezco los valores iniciales del vestd::cindario, de acuerdo al CellState
	CellPositionList::const_iterator cursor = neighbors.begin();

	for ( ; cursor != neighbors.end(); cursor++ )
	{
		pos = *cursor;
		pos += center;

		mat.calcRealPos( pos );

		if (mat.includes( pos ))
			sneighborList->setValue(*cursor, &(mat[ pos ]) );
		else 
			sneighborList->setValue(*cursor, &NeighborhoodValue::undef);
	}
}

/*******************************************************************
* Method: print
********************************************************************/
void NeighborhoodValue::print(ostream &os)
{
	os << "\t\t\tNeighborhood:\n";
	
	for ( sneighborList->initCursor(); ! sneighborList->endCursor(); sneighborList->next() )
		os << "\t\t\tNeighbor " << sneighborList->elementCell() << " = " << *(sneighborList->elementValue()) << "\n";
}

/*******************************************************************
* Method: isValid
********************************************************************/
bool NeighborhoodValue::isValid(CellPosition &cp) const
{
	for ( sneighborList->initCursor(); ! sneighborList->endCursor(); sneighborList->next() )
		if (sneighborList->elementCell() == cp)
			return true;

	return false;
}

/*******************************************************************
* Method: get
********************************************************************/
const Real &NeighborhoodValue::get( const NeighborPosition &npos ) const
{
	lNode	*aux;

	if ( (aux = sneighborList->exists(npos)) != NULL)
		return *(aux->value);

	// Si no lo encontre, entonces npos es invalido
	IvalidNeighbordRef e ;
	MTHROW( e ) ;
	return Real::tundef;
}
