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


#ifndef __COUPLED_CELL_H
#define __COUPLED_CELL_H

/** include files **/
#include "coupled.h"          // base class header
#include "cellpos.h"          // class CellPosition
#include "ltranadm.h"         // class LocalTransAdmin


/** foward declarations **/
class ModelAdmin ;
class MainSimulator ;
class CellState ;

/** declarations **/
typedef list< CellPosition > CellPositionList ;

#define	COUPLED_CELL_NAME	"CoupledCell"

class CoupledCell : public Coupled
{
public:
	~CoupledCell() ;

	CellState *cellState()
		{return state;}

	CoupledCell &dim( unsigned int Dim, unsigned int Width)
		{ tdimension.setElement( Dim, Width ); return *this; }

	CoupledCell &dim( nTupla &nt )
		{ tdimension = nt; return *this; }

	CoupledCell &borderWrapped( bool w)
		{ wrapped = w; return *this; }

	CoupledCell &inertialDelay( bool i )
		{ inertial = i; return *this; }

	CoupledCell &initialCellValue( const Real &i )
		{ initialValue = i; return *this; }

	CoupledCell &defaultDelay( const Time &t )
		{ delay = t; return *this; }

	CoupledCell &localTransition( const LocalTransAdmin::Function &lf )
		{ localFn = lf; return *this; }

	CoupledCell &setCellValue( const ModelId &, Value ) ;

	virtual CoupledCell &createCells( const CellPositionList &neighbors, const CellPositionList &selectList ) ;

	virtual CoupledCell &setCellValue( const CellPosition &, const Real & ) ;
	
	CoupledCell &setCellValue( const string &sCellPos, const Real & );

	virtual CoupledCell &setLocalTransition( const CellPosition &, const LocalTransAdmin::Function & ) ;

	string className() const
		{return COUPLED_CELL_NAME;}

	Type type() const
		{return cell;}

	string cellName( const CellPosition &pos ) const
		{ return description() + pos.print(); }

	string cellName( const string &sCellPos ) const
		{ return description() + sCellPos; }

	unsigned int dim(unsigned int pos) const
		{ return tdimension.get(pos); }

	const nTupla &dimension() const
		{return	tdimension;}

	const LocalTransAdmin::Function &localTransition() const
		{return localFn;}

	const LocalTransAdmin::Function &localTrans() const ;

	bool borderWrapped() const
		{return wrapped;}

	const Time &defaultDelay() const
		{return delay;}

protected:
	CoupledCell &cellState( CellState * ) ;

	bool inertialDelay() const
		{return inertial;}

	CoupledCell( const string &name = "CoupledCell" ) ; // default constructor

	const Real &initialCellValue() const
		{return initialValue;}

private:
	friend class ModelAdmin ;
	friend class MainSimulator ;

	// ** instance variables ** //
	nTupla	tdimension;
	bool wrapped, inertial ;
	Real initialValue ;
	CellState *state ;
	LocalTransAdmin::Function localFn ;
	Time delay ;
} ;

#endif // __COUPLED_CELL_H
