/*******************************************************************
*
*  DESCRIPTION: class Model
*
*  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/6/1998
*  DATE: 25/4/1999 (v2)
*
*******************************************************************/

/** include files **/
#include "model.h"      // class Model
#include "strutil.h"    // lowerCase

/** public functions **/
/*******************************************************************
* Function Name: Model
* Description: constructor default
********************************************************************/
Model::Model( const string &name )
: ident( Processor::InvalidId ) 
, parent_id( Processor::InvalidId )
, descript( name )
{}

/*******************************************************************
* Function Name: ~Model
* Description: destructor
********************************************************************/
Model::~Model()
{
	PortList::iterator cursor = inputList.begin();
	for ( ; cursor != inputList.end() ; cursor++ )
		delete cursor->second;

	for ( cursor = outputList.begin(); cursor != outputList.end(); cursor++ )
		delete cursor->second;
}

/*******************************************************************
* Function Name: addInputPort
* Post: adds the port to the input list
********************************************************************/
Port &Model::addInputPort( const string &portName )
{
	Port *pPort = new Port( lowerCase( portName ), id() );
	inputPorts()[ pPort->id() ] = pPort;
	return *pPort;
}

/*******************************************************************
* Function Name: addOuputPort
* Description: adds the port to the output list 
********************************************************************/
Port &Model::addOutputPort( const string &portName )
{
	Port *pPort = new Port( lowerCase( portName ), id() );
	outputList[ pPort->id() ] = pPort;
	return *pPort;
}

/*******************************************************************
* Function Name: port
* Description: Retorna el port solicitado
********************************************************************/
Port &Model::port( const string &n )
{
	string name( lowerCase( n ) ) ;

	PortList::iterator cursor = inputPorts().begin();

	for( ; cursor != inputPorts().end() && cursor->second->name() != name; cursor++ )
		;

	if (cursor == inputPorts().end())
	{
		for (cursor = outputPorts().begin(); cursor != outputPorts().end() && cursor->second->name() != name ; cursor++ )
			;

		if ( cursor == outputPorts().end() )
		{
			InvalidPortRequest e ;
			e.addText( name + " port not found!" ) ;
			MTHROW( e ) ;
		}
	}
	MASSERT( cursor->second );
	return *( cursor->second );
}

/*******************************************************************
* Function Name: nextChange
********************************************************************/
Model &Model::nextChange( const Time &t )
{
	SingleProcessorAdmin::Instance().processor( id() ).nextChange(t);
	return *this;
}
