/*******************************************************************
*  DESCRIPTION: Atomic Model sort
*  AUTHOR: Emad Khan
*  EMAIL: emadkhan@cmail.carleton.ca
*  DATE: 30/10/2016
*******************************************************************/

/** include files **/
#include "sort.h"      // class sort
#include "message.h"    // class Message
#include "mainsimu.h"   // MainSimulator

/** public functions **/

/*******************************************************************
* Function Name: sorting
********************************************************************/
sort::sort( const string &name )
: Atomic( name )
, order( addInputPort( "order" ) ) //Represent Input of Orders coming from Admin Office
, reqorder( addInputPort( "reqorder" ) ) //Represent Input of Order Requests coming from Packaging
, packorder( addOutputPort( "packorder" ) ) //Represent Output of Pack Orders to Packaging
, ready( addOutputPort( "ready" ) ) //Represent Output of completed food orders from the Food Bank
, prepTime( 0, 0, 0, 0 ) //Preparation Time = 5 mins

{
   string time( MainSimulator::Instance().getParameter( description(), "prepTime" ) ) ; //Check if parameter prepTime is defined in model file
   if( time != "" )
		prepTime = time ;
}

/*******************************************************************
* Function Name: initFunction
********************************************************************/
Model &sort::initFunction()
{
   cltcount = 0 ; //Initially, there are no clients
   cltmax = 0 ; //Initially, maximum clients are zero
   passivate(); //Initially, model is in passive state
   return *this ;
}

/*******************************************************************
* Function Name: externalFunction
********************************************************************/
Model &sort::externalFunction( const ExternalMessage &msg )
{
	//For message at reqorder
	if( msg.port() == reqorder )
	{
		if(!cltmax){}
		else
		{
			if (!cltcount){}

			else {
				++cltcount ;
				holdIn(active, prepTime ); //State Active till 20mins
				}
		}
	}
	else
	{
		if(state() == active){}

		else
		{   //For message at order
			if( msg.port() == order )
			{
				if(!cltcount)
				{
					cltcount++ ;
					newcltmax = abs((int)msg.value()) ;
					holdIn(active, prepTime ) ;
				}
				else
				{}
			}
		}
	}
	return *this;
}

/*******************************************************************
* Function Name: internalFunction
********************************************************************/
Model &sort::internalFunction( const InternalMessage & )
{
	passivate();
	return *this ;
}

/*******************************************************************
* Function Name: outputFunction
********************************************************************/
Model &sort::outputFunction( const InternalMessage &msg )
{
  if(cltcount == 1)
  {
	  cltmax = newcltmax ;
        sendOutput( msg.time(), packorder, cltcount ) ;
  }
  else
  {
	  if(cltcount > cltmax)
	  {
          cltcount=0;
          sendOutput( msg.time(), ready, cltmax ) ;
          cltmax=newcltmax ;

	  }
	  else
	  {
		  sendOutput( msg.time(), packorder, cltcount ) ;
      }
  }
	return *this ;
}
