//process congestion event and generate the next event
int CCongestionAreaManager::ProcessCongestionEvent(CongestionAreaEvent* pEvent, ElapsedTime eventTime)
{
	Person* pPerson = (Person*)pEvent->GetMobileElement();
	if(pPerson == NULL)
		return 0;
	
	// step1. Leave Cell
	TerminalMobElementBehavior* spTerminalBehavior = pPerson->getTerminalBehavior();
	if (spTerminalBehavior == NULL)
	{
		return 0;
	}
	Point floorpt;
	pPerson->getTerminalPoint(floorpt);
	int nFloor = int(floorpt.getZ()) / 100;

	CCongestionAreaCell* pCell = m_vGrid[nFloor]->GetCell(spTerminalBehavior->GetOldLocation());
	if(pCell != NULL)// && pPerson->GetOldLocation() != pPerson->GetOldStartPoint()
	{
		if(pCell->GetPersonsCount()==0)
		{
			CString str;
			str.Format("1-%d", pPerson->getID());
			AfxMessageBox(str);
		}
		pCell->LeaveCell(pPerson->GetAdminGroupSize());
	}
	// step2. Enter Cell
	Point ptDest;
	pPerson->getTerminalDest(ptDest);
	pCell = m_vGrid[nFloor]->GetCell(ptDest);
//	ASSERT(pCell != NULL);//if the cell is null, last time has already exit
	if(pCell != NULL)
		pCell->EnterCell(pPerson->GetAdminGroupSize());
	// setp3. save the current point as old location
	spTerminalBehavior->SetOldLocation(ptDest);
	// setp4. Write log
	pPerson->writeLogEntry(eventTime, false,false);
	// step5. Next event.
	//calculate the next event destination;
    Point pt;
	pPerson->getTerminalPoint(pt);
	const Point& ptOld = spTerminalBehavior->GetOldDestPoint();
	Point ptNext = /*pt.GetDistancePoint(ptOld, STEPDIST)*/m_vGrid[nFloor]->GetNearestPoint(pt,ptOld);
	//if get null, leaving the congestion area, reset the old destionation and speed;
	//if the ptNext equal ptOld, the person arrived at the end next processor
	pCell = m_vGrid[nFloor]->GetCell(ptNext);
	if(pCell == NULL //the end point not in the congestion area
		|| SAMEPOINT(ptNext, ptOld) ) //the end point in the congestion area,but get the end
	{	
		//if the person leaving the congestion area, leave the current cell,
		CCongestionAreaCell* pPreCell = m_vGrid[nFloor]->GetCell(spTerminalBehavior->GetOldLocation());
		if(pPreCell != NULL)
		{
			if(pPreCell->GetPersonsCount()==0)
			{
				CString str;
				str.Format("2-%d", pPerson->getID());
				AfxMessageBox(str);
			}

			pPreCell->LeaveCell(pPerson->GetAdminGroupSize());
		}
		pPerson->setTerminalDestination(spTerminalBehavior->GetOldDestPoint());
		pPerson->setSpeed(spTerminalBehavior->GetOldSpeed());
		if(pCell == NULL && pPerson->getState() != WalkOnPipe)
		{
			//pPerson->setLocation(ptNext); 
			if(CheckAndHandleCongestion(pPerson, eventTime, TRUE))
				return 1;
			else
				spTerminalBehavior->processGeneralMovementHelp(eventTime);
		}
		else
			spTerminalBehavior->processGeneralMovementHelp(eventTime);
		return 0;
	}

	//reset the new speed to calculate the next event time;
	int nCount = pCell->GetPersonsCount();
	DistanceUnit dSpeed = GetNewSpeed(pPerson, nCount);
	pPerson->setSpeed(dSpeed);
	pPerson->setTerminalDestination(ptNext);
	//Add the next event to the event list;
	ElapsedTime time = eventTime + pPerson->moveTime();
	CongestionAreaEvent* event = new CongestionAreaEvent;
	event->init(pPerson, time,false);
	event->addEvent();
	
	return 1;
}