//----------------------------------------------------------------------
//  IMPLEMENTATION FILE (process.cpp)
//----------------------------------------------------------------------
#include "process.h"

Process::Process(char *filename)
{	ifstream infile(filename);
	Event *evnt;
	char tmpestr[3];
	int  tmpdur;
	EventType tmpeventt;

	//Load in general process information
	infile >> PID;
	infile >> CreateTime;
	infile >> Priority;

	//Load in the event data
	while( 1 )
	{
		infile >> tmpestr[0];
		if(infile.eof())
			break;
		infile >> tmpestr[1];
		tmpestr[2] = '\0';
		tmpeventt = str2EventType(tmpestr);
		infile >> tmpdur;
		evnt = new Event(tmpeventt, tmpdur);
        	if(DEBUG == TRUE)
			cout << "Adding Event " << tmpeventt << " Dur: "<< tmpdur << endl;
		Pevents.Enqueue(evnt);
	}

	//Init event Members
	if(Pevents.IsEmpty() == FALSE)
	{
        	evnt = Pevents.Dequeue();
                CurEvent = evnt->getEvent();
                ETimeRem = evnt->getDuration(); 
     	}
	else
	{	//No events exist
		CurEvent = NONE;
                ETimeRem = 0;
	}

	//Init Statistical data
	WaitTime = 0;
	TurnTime = 0;	
}

Process::~Process()
{
	//No dynamically allocated memory to deallocate.
}   

EventType Process::Age(PStateType state)
{
	Event *evnt;

	switch(state)
	{	//If the process is in the ReadyQ, increase waiting time
		//If in the WaitingQ decrease Event Time Remaining
		//If the process is on the CPU decrease ETimeRem
		case InWQ:      //This process is in the WaitingQ
			//Update Process statistics....Same as if on CPU
		case OnCPU:	//This process is on the CPU
		        ETimeRem--;
        		if(ETimeRem <= 0)
        		{
				if(Pevents.IsEmpty() == TRUE)
				{	//No further events
					CurEvent = NONE;
					ETimeRem = 0;
				}
				else
				{
                			evnt = Pevents.Dequeue();
               		 		CurEvent = evnt->getEvent();
                			ETimeRem = evnt->getDuration();
				}
        		}
			break;
		case InRQ:	//This process is in the ReadyQ
			//Do nothing Special
			WaitTime++;
			break;
		case InTQ:	//This process is in the TermQ
		case InNQ:	//This process is in the NewQ
			//Do Nothing Special
			break;
		default:	//Unknown state
			break;
	}
	
	//Return status of this process
	return(CurEvent);

}

int Process::getWaitTime()
{
	return(WaitTime);
}

int Process::getTurnTime()
{
	return(TurnTime);
}

void Process::setTurnTime(int TT)
{
	TurnTime = TT;
}

int Process::getPID()
{
	return(PID);
}

int Process::getPriority()
{
	return(Priority);
}

void Process::setPriority(int newP)
{
	Priority = newP;
}

int Process::getCreateTime()
{
        return(CreateTime);
}

EventType Process::getCurEvent()
{
	return(CurEvent);
}

EventType Process::str2EventType(char *tmpestr)
{
	if( strcmp(tmpestr, "CR") == 0)
		return(CR);
	if( strcmp(tmpestr, "CC") == 0)
		return(CC);
	if( strcmp(tmpestr, "IO") == 0)
		return(IO);
	if( strcmp(tmpestr, "SL") == 0)
		return(SL);
	return(NONE);
}

void Process::Display()
{

	cout << "PID: " << PID << "\n";
	cout << "CreateTime: " << CreateTime << "\n";
	cout << "Priority: " << Priority << "\n";
	Pevents.Display();
	cout << "CurEvent: " << CurEvent << "\n";
	cout << "ETimeRem: " << ETimeRem << "\n";
	cout << "WaitTime: " << WaitTime << "\n";
	cout << "TurnTime: " << TurnTime << "\n";
}


