Index: proiecte/ptvs/src/vnsim/core/Engine2.java
===================================================================
--- proiecte/ptvs/src/vnsim/core/Engine2.java	(revision 135)
+++ proiecte/ptvs/src/vnsim/core/Engine2.java	(revision 135)
@@ -0,0 +1,2321 @@
+//pentru 8 procesoare.
+package vnsim.core;
+
+
+import java.io.BufferedWriter;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.Random;
+import java.util.Vector;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import vnsim.applications.adaptiveTL.IntersectionCarRecord;
+import vnsim.applications.adaptiveTL.WirelessTrafficLight;
+import vnsim.applications.emissions.EmissionsTrafficLight;
+import vnsim.applications.ezcab.EzcabCar;
+import vnsim.applications.ezcab.EzcabClient;
+import vnsim.applications.trafficview.SimulatedCarInfo;
+import vnsim.core.events.CleanupEvent;
+import vnsim.core.events.Event;
+import vnsim.core.events.GPSEvent;
+import vnsim.core.events.ReceiveEvent;
+import vnsim.core.events.SendEvent;
+import vnsim.core.events.UnicastSendEvent;
+import vnsim.map.object.Globals;
+import vnsim.map.object.Map;
+import vnsim.map.object.PeanoKey;
+import vnsim.map.object.Point;
+import vnsim.map.object.Road;
+import vnsim.map.utils.GPSutil;
+import vnsim.network.RadioDev;
+import vnsim.network.dsrc.Application;
+import vnsim.network.dsrc.CarRunningDSRC;
+import vnsim.network.dsrc.DSRCStatisticComponent;
+import vnsim.network.dsrc.DSRCStatistics;
+import vnsim.network.dsrc.EmergencyRequest;
+import vnsim.network.dsrc.MAC80211;
+import vnsim.network.dsrc.WirelessPhy;
+import vnsim.network.propagation.Ricean;
+import vnsim.network.scft.CarRunningSCFT;
+import vnsim.vehicular.emissions.EmissionsResults;
+import vnsim.vehicular.generator.EntryFlowVariation;
+import vnsim.vehicular.generator.Mobility;
+import vnsim.vehicular.generator.NewCarEvent;
+import vnsim.vehicular.routePlan.RoutingConstants;
+import vnsim.vehicular.routePlan.cityRouting.CarToIntersectionComm;
+import vnsim.vehicular.routePlan.cityRouting.CityTrafficLight;
+import vnsim.vehicular.routePlan.cityRouting.IntersectionNode;
+import vnsim.vehicular.routePlan.cityRouting.RoadSegmentCost;
+import vnsim.vehicular.routePlan.cityRouting.Server;
+import vnsim.vehicular.routePlan.infrastructureRouted.DelayRecord;
+import vnsim.vehicular.routePlan.infrastructureRouted.GuidanceRequest;
+import vnsim.vehicular.routePlan.infrastructureRouted.InfrastructureNode;
+import vnsim.vehicular.routePlan.selfRouted.QueryGeneration;
+import vnsim.vehicular.scenarios.EntryExitScenario;
+import vnsim.vehicular.scenarios.EntryScenario;
+import vnsim.vehicular.scenarios.Route;
+import vnsim.vehicular.simulator.AggresivePersonality;
+import vnsim.vehicular.simulator.CalmPersonality;
+import vnsim.vehicular.simulator.CarInstance;
+import vnsim.vehicular.simulator.Personality;
+import vnsim.vehicular.simulator.RegularPersonality;
+import vnsim.vehicular.simulator.SortedCarVector;
+import vnsim.vehicular.simulator.intersections.Intersection;
+import vnsim.vehicular.simulator.intersections.IntersectionWithTrafficLights;
+
+
+
+/**
+ * 
+ * The Engine class is the main class that controlls the simulation. It manages
+ * the list of entities (cars, trafficlights) and the list of events and passes the
+ * control to the mobility layer or communication layer when needed.
+ * 
+ * @author Victor Gradinescu
+ * 
+ */
+
+public class Engine {
+	
+	
+	/**
+	 * PTVS Project
+	 */
+	public ExecutorService executor[];/////////////////////////////////////// thread pool with Executors ////////////////////
+	
+	public void start(Event e, int i) throws IOException {
+	    
+	      executor[i].submit(new EventProcessingThread(this,e));
+	  }
+	
+	int dimens;
+	
+	public static int numThreads;
+	///////////////////////end PTVS Project/////////////////////////////////////////////////////
+	
+	
+	/* EZCab - file informations about the client */
+	public static BufferedWriter bwClient, bwCab;
+	
+	public static double WIRELESS_RANGE = 0.1;
+	public static double EXTENDED_WIRELESS_RANGE = 1.0;
+
+//	Petroaca - simulation protocol type ( 802.11 or DSRC )
+	public static int simulationProtocol=Globals.PROTOCOL_80211;
+	
+	//Petroaca - propagation type ( tworay or shadowing )
+	public static int propagationModel=Globals.TWO_RAY_GROUND;
+	
+	//Petroaca - the Ricean propagation module
+	public static Ricean riceanModule;
+	
+	DataInputStream dis = null;
+
+	public int fps;
+
+	static Vector<Event> eventQueue = null;
+	static int nrEvThreads = 0;
+	
+	//Petroaca - the DSRC emergency channel
+	ArrayList<Event> eventQueueEmergency = null;
+	
+	public boolean pauseFlag = true;
+
+
+	boolean doneFlag = false,doneFlagEmergency=false;
+
+	public ArrayList<SimulatedCarInfo> cars = null;
+
+	public int crtTime = 0;
+
+	public long t0 = 0L;
+
+	public boolean withGUI, startedWithGUI;
+
+	boolean runtimeMobility;
+
+	public boolean disableComm = false;
+
+	File fText = null, fBin = null;
+
+	PrintWriter pwText = null;
+
+	DataOutputStream outBin = null;
+
+	long prevRealSec = 0; 
+	double lastSimSecond = 0.0;
+	
+	int eventsTime = 0, mobilityTime = 0, cleanupTime = 0, netTime = 0, codeTime = 0;
+
+
+	int schedTime = 0,  moveTime = 0, semTime = 0;
+
+
+	public double maxControlDelay = 0;
+	
+	public int mycnt = 0;
+	public long fincars;
+	public long crossedCars;
+	public double totalkm, totalControlDelay;
+	public EmissionsResults totalEM = new EmissionsResults();
+	private long totalTime;
+	
+	public static int created = 0;
+
+	// Routing
+	public static int simulationType = 0;
+	public static int applicationType = 0;
+	int jammed;
+
+	public ArrayList<SimulatedCarInfo> infrastructure = null;
+	
+	Object event;
+
+	//City Routing
+	private Server server= new Server();  
+	
+	/**
+	 * 
+	 * 
+	 * @param withGUI If the simulator is run at the same time with GUI, the code
+	 * will have to be synchronized 
+	 * @param runtimeMobility 
+	 */
+	public Engine(boolean withGUI, boolean runtimeMobility) 
+	{
+		try {
+			FileWriter fwClient = new FileWriter("client_request.txt");
+			bwClient = new BufferedWriter(fwClient);
+			FileWriter fwCab	= new FileWriter("client_answers.txt");
+			bwCab 	 = new BufferedWriter(fwCab); 
+		} catch (IOException e1) {
+			e1.printStackTrace();
+		}
+		this.withGUI = withGUI;
+		this.startedWithGUI = withGUI;
+		this.runtimeMobility = runtimeMobility;
+		// init();
+		prevRealSec = t0 = System.currentTimeMillis();
+	
+	}
+
+	/*
+	 * Load the map, initialize eventqueue, init
+	 */
+	public void init() {
+
+		Map map = Globals.map;
+		
+		//System.out.println("roads.size: "+map.roads.size()+" : "+map.roads.get(0).getName());
+		
+		//Road road = (Road)map.roads.get(0);
+		
+		//System.out.println("road.points: "+road.points);
+		
+		//System.out.println("strada:"+road.getName()+":"+" road.crosses.size(): "+road.crosses.size());
+		
+			
+		
+		
+		
+		/**
+		 * PTVS project
+		 */
+		ArrayList<Intersection> intersectii = map.allIntersections;
+		//numThreads=intersectii.size();
+		numThreads = Globals.NO_FEP_PROC - 1;
+				
+		executor=new ExecutorService[numThreads];
+		
+		for(int i=0; i < numThreads; i++){
+			executor[i] = Executors.newFixedThreadPool(1); // un singur thread e mereu refolosit pt fiecare intersectie.. ar putea fi mai multe
+		}
+		///////////////////////end PTVS Project/////////////////////////////////////////////////////
+		
+		
+		for(int q=0;q<intersectii.size();q++){
+			System.out.println("intersectia "+q+": "+" nume: "+intersectii.get(q).toString()+" "+intersectii.get(q).getMapPoint());
+		}
+		
+		System.out.println(".........................aici4.........");
+		
+		//***************************************************************
+		
+		if (map.roads.get(0).getName().startsWith("Iuliu") || map.roads.get(0).getName().startsWith("Dr"))
+		{
+			
+			Globals.monitorWTL = (WirelessTrafficLight)map.allIntersections.get(1);
+		}
+		pauseFlag = false;
+		doneFlag = false;
+
+		// the positions of the cars may be updated by a mobility module by
+		// recomputing positions at each step or can be updated by reading a 
+		// traces file
+		if (!runtimeMobility) 
+		{
+			try 
+			{
+				if (dis != null) {
+					dis.close();
+				}
+				dis = new DataInputStream(new FileInputStream(Globals.inFile));
+			} 
+			catch (IOException e) 
+			{
+				System.err.println("Error reading scenario; file error"+ Globals.inFile);
+				e.printStackTrace();
+				System.exit(0);
+			}
+			try 
+			{
+				fps = dis.readInt();
+			} 
+			catch (IOException e)
+			{
+				System.err.println("Error reading file " + Globals.inFile);
+				e.printStackTrace();
+			}
+		}
+		else 
+		{
+			fps = Globals.executionFPS;
+
+			Globals.WIRELESS_TRANSMISSION_FRAMES = (int) Math
+					.ceil((double) Globals.WIRELESS_TRANSMISSION_TIME
+							/ (1000 / Globals.executionFPS));
+
+		}
+
+		// init cars and events
+		eventQueue = new Vector<Event>();
+		
+		
+		cars = new ArrayList<SimulatedCarInfo>();
+		
+	
+
+		//Petroaca - if DSRC simulation then initialize the emergency event queue
+		if(Engine.simulationProtocol==Globals.PROTOCOL_DSRC)
+			eventQueueEmergency = new ArrayList<Event>();
+		
+		crtTime = 0;
+
+		if (!runtimeMobility) {
+			readScenarioPhase();
+		} else {
+			// Mobility.initCarsTest(this);
+			// Mobility.initCarsAutostrada(this);
+//			Mobility.initCars(this);
+		}
+
+		synchronized (eventQueue) {
+			
+				eventQueue.add(new GPSEvent(0));
+								
+				eventQueue.add(new CleanupEvent(1));
+				
+				Iterator<SimulatedCarInfo> it = cars.iterator();
+				while (it.hasNext()) 
+				{
+					System.out.println("nu ai cum sa intri pe aici!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! cars este vida");
+					SimulatedCarInfo r = it.next();
+				
+				schedEvent(new SendEvent(4, r,
+						SimulatedCarInfo.STANDARD_MESSAGE_ID));
+				}
+				
+				// cod comentat deaorece vroiam sa vad daca se calculeaza cum trebuie intersectia cea mai apropiata
+				// si partea asta face ca semafoarele din toate intersectiile sa genereze evenimente
+				
+				/* Szekeres A. START_MODIFY - add broadcast event for each traffic light*/
+			for(int i=0;i<Globals.map.allIntersections.size();i++) {
+				Intersection sender = Globals.map.allIntersections.get(i);
+				if (sender instanceof EmissionsTrafficLight)
+				{
+					((EmissionsTrafficLight)sender).init();
+					schedEvent(new SendEvent(4, (EmissionsTrafficLight)sender, (int)Globals.PROT_TL_FEEDBACK));
+				}
+			}			
+				/* Szekeres A. STOP_MODIFY */
+		}
+		
+		
+		try 
+		{
+			if (runtimeMobility && outputToFile) 
+			{
+
+				fText = new File(Globals.inFile + ".txt");
+				fBin = new File(Globals.inFile);
+				fText.createNewFile();
+				fBin.createNewFile();
+				pwText = new PrintWriter(new FileOutputStream(fText));
+				outBin = new DataOutputStream(new FileOutputStream(fBin));
+
+				pwText.println("" + Globals.FPS);
+				outBin.writeInt(Globals.FPS);
+			}
+		}
+		catch (IOException e) 
+		{
+			System.err.println("Error reading scenario; file error"
+					+ Globals.inFile);
+			e.printStackTrace();
+			System.exit(0);
+		}
+
+		if (Engine.simulationType == RoutingConstants.DYNAMIC_INFRASTRUCTURE_ROUTE) {
+			DelayRecord.initDelays();
+			this.infrastructure=new ArrayList<SimulatedCarInfo>();
+			//create a fixed node for every intersection
+			InfrastructureNode.createInfrastructureNodes();
+		}
+
+		//Petroaca - instantiate the ricean propagation module
+		try
+		{
+		  if(Engine.propagationModel==Globals.RICEAN)
+			Engine.riceanModule=new Ricean(Globals.RICEAN_FILE_NAME,true);
+		}
+		catch(IOException ioe){System.out.println("Ricean file io error:"+ioe.getMessage());System.exit(1);}
+		
+		System.out.println(">>> Engine initialized - "+eventQueue.size()+" events in the queue");
+		System.out.println("CARS:"+cars);
+		System.out.println("Events:"+eventQueue);
+		 
+		
+		System.out.println();
+		
+		/*Road r = Globals.map.roads.get(1);
+		System.out.print("road:"+r.getName());
+		System.out.println("  r.points.size():"+r.points.size());
+		
+		Point p1 = r.points.get(r.points.size()-1);
+		System.out.println(p1);
+		Point p2 = r.points.get(r.points.size()-2);
+		System.out.println(p2);
+		
+		System.out.println("distanta: " +(p1.getDistance() - p2.getDistance()));
+		System.out.println("distanta: " +GPSutil.distance(p1, p2));*/
+		System.out.println("__________________end init____________________________\n");
+				
+
+	}
+
+	/**
+	 * Reset simulation
+	 */
+	public void reset()
+	{
+		eventQueue = new Vector<Event>();
+		cars = new ArrayList<SimulatedCarInfo>();
+
+		//Petroaca - if DSRC simulation also reset the emergency channel
+		if(Engine.simulationProtocol==Globals.PROTOCOL_DSRC)
+			eventQueueEmergency = new ArrayList<Event>();
+		
+		crtTime = 0;
+
+	}
+	
+	/**
+	 * Turn on communication by scheduling transmission events for each car.
+	 *
+	 */
+	public void restartCommunication() {
+		disableComm = false;
+		synchronized (eventQueue) {
+			// eventQueue.add(new CleanupEvent(crtTime+1));
+
+			schedEvent(new CleanupEvent(crtTime + 1));
+
+			synchronized (cars) 
+			{
+				Iterator<SimulatedCarInfo> it = cars.iterator();
+				while (it.hasNext()) {
+					SimulatedCarInfo r = it.next();
+					schedEvent(new SendEvent(crtTime + 2, r, SimulatedCarInfo.STANDARD_MESSAGE_ID));
+				}
+			}
+		}
+		
+//		Petroaca - if DSRC simulation also reset the emergency channel
+		if(Engine.simulationProtocol==Globals.PROTOCOL_DSRC)
+			eventQueueEmergency = new ArrayList<Event>();
+	}
+
+	/**
+	 * Start simulation, execute events from queue continously
+	 * 
+	 */
+	public void play() {
+		// supposed to be in the init()
+		// between init and play() Globals.map.allIntersections is changing
+		// need to find a fix
+		
+		if (Engine.simulationType == RoutingConstants.DYNAMIC_CITY_ROUTE) {
+			CityTrafficLight.upgradeToCityTL();
+			RoadSegmentCost.initRoadSegmentsCost();
+			this.infrastructure=new ArrayList<SimulatedCarInfo>();
+			//create a fixed node for every intersection
+			IntersectionNode.createIntersectionNodes(server);
+			server.init();
+		}
+		
+		prevRealSec = t0 = System.currentTimeMillis();
+		pauseFlag = false;
+		while (!pauseFlag && !doneFlag) {
+			step();			
+		}
+	}
+
+	/**
+	 * Execute all the events for the following <seconds> s
+	 * 
+	 */
+	public void play(int seconds) {
+		int frames = seconds * fps;
+		pauseFlag = false;
+		for (int i = 0; i < frames && !pauseFlag && !doneFlag; i++) {
+			step();
+		}
+	}
+
+	/**
+	 * Request the interruption of the continous execution of events
+	 * 
+	 */
+	public void pause() {
+		pauseFlag = true;
+	}
+
+	/**
+	 * Execute all the events for the current moment of time (virtual time)
+	 * 
+	 */
+	double dec1(double x){
+		return (double)((int)(x * 10)) / 10;
+	}
+	
+	
+	long lastTime = -1;
+	
+	
+
+	
+	////////////////////////////////////// step ///////////////////////////////////////////////////////////
+	/**
+	 * Process the events for the current step of the simulation
+	 *
+	 */
+	
+	
+	/**
+	 * PTVS
+	 */
+	
+	
+	public void step() {
+		
+		int cnt = 0;
+		
+		if(Globals.SOCIALNETWORK == 1){
+			double sec = vnsim.socialNet.GlobalNetwork.nextReconfigurationTime*Globals.SECOND;
+		}
+			
+		if (crtTime >  3.5 * Globals.HOUR){	//nu rulez mai mult de 3 ore juma
+			doneFlag = true;
+			System.exit(0);
+			return;
+		}
+		if (withGUI) {
+			synchronized (Globals.mutex) {
+				if (Globals.flag == 1) {
+					try {
+						Globals.mutex.wait();
+					} catch (Exception e) {
+						
+					}
+				}
+				Globals.flag = 0;
+			}
+		}
+
+		long t1 = System.currentTimeMillis();
+		if (crtTime % Globals.SECOND == 0)
+		{
+			lastSimSecond = (double)(t1-prevRealSec)/1000;
+			prevRealSec = t1;
+			if (lastSimSecond < 1)
+				try{
+					Thread.sleep(100);//(int)((1.0 - lastSimSecond)*1000));
+				}catch(Exception e){
+					
+				}
+		}	
+		
+		if (crtTime % Globals.MINUTE == 0){
+
+			Globals.packets = 0;
+			Globals.collided = 0;
+			Globals.lost = 0;
+			
+			System.out.println((crtTime / Globals.MINUTE) + " sim min;\t" +
+					"simulation time: "+ (System.currentTimeMillis() - t0) +"\t" +
+					" cars: "+cars.size() + " created " + created);
+
+			Globals.volume = 0;
+			Globals.demand = 0;
+			
+			//Petroaca
+			if(Engine.simulationProtocol==Globals.PROTOCOL_DSRC)
+			{
+				DSRCStatistics.addStatistic(new DSRCStatisticComponent(0,Globals.DSRC_PACKETS_LOST_WEAK,Globals.DSRC_PACKETS_TOTAL,Globals.DSRC_PACKETS_LOST_CORRUPTED,Globals.DSRC_PACKETS_LOST_COLLISION,Globals.DSRC_PACKETS_LOST_TX,Globals.DSRC_PACKETS_LOST_RX,Globals.DSRC_PACKETS_LOST_PER,Globals.DSRC_PACKETS_RECEIVED_OK
+						,0,0,Globals.CUMMULATIVE_PACKETS_FV,Globals.CUMMULATIVE_PACKETS_NFV,Globals.CUMMULATIVE_PACKETS_LAV,Globals.CUMMULATIVE_PACKETS_RAV,Globals.IRT_FV,Globals.IRT_NFV,Globals.IRT_LAV,Globals.IRT_RAV,0,0,0,0,cars.size(),Globals.EMERGENCY_RECEIVED,Globals.EMERGENCY_SENT));
+				
+				
+				Globals.DSRC_PACKETS_LOST_WEAK=0;
+				Globals.DSRC_PACKETS_LOST_COLLISION=0;
+				Globals.DSRC_PACKETS_LOST_TX=0;
+				Globals.DSRC_PACKETS_LOST_RX=0;
+				Globals.DSRC_PACKETS_LOST_PER=0;
+				Globals.DSRC_PACKETS_LOST_CORRUPTED=0;
+				Globals.DSRC_PACKETS_RECEIVED_OK=0;
+				Globals.DSRC_PACKETS_TOTAL=0;
+				Globals.DSRC_PACKETS_SEND_FALIURE_RX=0;
+				Globals.DSRC_PACKETS_SEND_FALIURE_NOISE=0;
+				Globals.DSRC_SEND=0;
+				
+				//System.out.println((crtTime / Globals.MINUTE)+ " min\t"+"FV:"+Globals.CUMMULATIVE_PACKETS_FV+" NFV:"+Globals.CUMMULATIVE_PACKETS_NFV+" LAV:"+Globals.CUMMULATIVE_PACKETS_LAV+" RAV:"+Globals.CUMMULATIVE_PACKETS_RAV+" EMERGENCY_RECV:"+Globals.EMERGENCY_RECEIVED+" EMERGENCY_SENT:"+Globals.EMERGENCY_SENT);
+				
+				Globals.CUMMULATIVE_PACKETS_RAV=0;
+				Globals.CUMMULATIVE_PACKETS_LAV=0;
+				Globals.CUMMULATIVE_PACKETS_FV=0;
+				Globals.CUMMULATIVE_PACKETS_NFV=0;
+				Globals.IRT_FV=0;
+				Globals.IRT_NFV=0;
+				Globals.IRT_LAV=0;
+				Globals.IRT_RAV=0;
+				Globals.EMERGENCY_RECEIVED=0;
+				Globals.EMERGENCY_SENT=0;
+				
+				/*System.out.println("END DSRC DATA------------------------------");*/
+			}	
+		}		
+		if (crtTime % (5 * Globals.MINUTE) == 0){
+			if (lastTime == -1)
+				lastTime = t0;
+			long realTime = t1 - lastTime;
+			lastTime = t1;
+
+			eventsTime = 0;
+			codeTime = 0;
+			cleanupTime = 0;
+			mobilityTime = 0;
+			
+			Globals.pw.flush();
+			
+			Globals.demo.st.clearInfo();
+			Globals.demo.st.addInfo("Avg Delay "+ dec1(totalControlDelay/(fincars*60))+" min");
+			Globals.demo.st.addInfo("Max Delay "+dec1(maxControlDelay / 60)+" min");
+			Globals.demo.st.addInfo("Fuel: " + dec1( ( totalEM.fc * 100) / (1000 * totalkm)) + " L/100 km");
+			Globals.demo.st.addInfo("CO2: " + dec1((totalEM.co2 * 20 )/ 1000)+" kg/h");
+			Globals.demo.st.addInfo("CO: " + dec1((totalEM.co * 20 )/ 1000)+" kg/h");
+			Globals.demo.st.addInfo("HC: " + dec1((totalEM.hc * 20 )/ 1000)+" kg/h");
+			Globals.demo.st.addInfo("NOx: " + dec1((totalEM.nox * 20 )/ 1000)+" kg/h");
+			
+
+			if (fincars>0) {
+				Globals.pwxc.println( "min " + (crtTime / Globals.MINUTE) +
+						"  cars: " + fincars + 
+						"  total time: " + totalTime +
+						"  total km: " + totalkm +
+						"  time/car: " + totalTime / fincars +
+						"  L/100: "+ ( (totalEM.fc * 100) / ( 1000 * totalkm)) +
+						"  fc: " + (totalEM.fc / fincars) +
+	 					"  co2: " + (totalEM.co2 / fincars) +
+						"  co: " + (totalEM.co / fincars) +
+						"  hc: " + (totalEM.hc / fincars) +
+						"  nox: " + (totalEM.nox / fincars)
+						);
+				Globals.pwxc.flush();
+			}
+		}		
+		
+		
+		if (startedWithGUI) {
+			Globals.demo.st.setCount(crtTime);
+			Globals.demo.st.setCurrentTime(System.currentTimeMillis() - t0);
+			Globals.demo.st.setSimulationTime((float) ((crtTime * 1000) / fps));
+			//Globals.demo.st.setSemTime(mycnt);
+			Globals.demo.st.setNrEvents(eventQueue.size() + nrEvThreads);
+			Globals.demo.st.setCarsNo(cars.size());			
+		}
+		
+		long t2 = System.currentTimeMillis();
+		
+//		Petroaca - if DSRC simualtion play the events in emergency channel as well
+		
+		if(Engine.simulationProtocol==Globals.PROTOCOL_DSRC && Globals.MULTI_CHANNEL)
+		{
+			while (true) {
+				if (eventQueueEmergency.size() == 0) {
+					doneFlagEmergency = true;
+					break;
+				}
+				
+				Event e = (Event) eventQueueEmergency.get(0);
+				if (e.getTime() == crtTime) {
+					playEventEmergency();
+					//cnt++;
+				} else
+					break;
+			}
+		}
+		
+		/*while (true) {
+			if (eventQueue.size() == 0) {
+				doneFlag = true;
+				return;
+			}
+			
+			Event e = (Event) eventQueue.get(0);
+			if (e.getTime() == crtTime) {
+				playEvent(null);
+				cnt++;
+			} else
+				break;
+		}*/
+
+		
+		/**
+		 * PTVS Project
+		 * we know how many intersections i have, to start as many threads as intersections i have
+		 */
+		Map map = Globals.map;
+		ArrayList<Intersection> intersectii = map.allIntersections;
+		numThreads=intersectii.size();
+		numThreads = Globals.NO_FEP_PROC - 1;
+		
+		while (true) {
+			
+			if (eventQueue.size() == 0) {
+				doneFlag = true;
+				System.out.println("\ndoneFlag = true ");
+				return;
+			}
+			
+			// extrag un eveniment din coada !!!!! acum doar il extrag.. cand intru in playEvent il si scot cu remove(0)
+			Event e = (Event) eventQueue.get(0);
+			if (e == null) continue;
+			
+			if (e.getTime() == crtTime) {
+				//System.out.println("------------->> e.getTime() == crtTime== "+crtTime);
+				
+			}
+			
+			if(dimens!=eventQueue.size()){
+				
+				System.out.println("\n----------- number of events in the queue:" +eventQueue.size());
+				dimens = eventQueue.size();
+			}
+			
+			
+			/**
+			 * PTVS Project
+			 * 
+			 * we have an array of threads for processing events based on location (intersection)
+			 * i process only receive and send messages
+			 */
+			
+		
+			if((e instanceof SendEvent) || (e instanceof ReceiveEvent)){
+				
+				synchronized (eventQueue) {
+					e = eventQueue.remove(0);
+					nrEvThreads++;
+					//System.out.println("remove from eventQueue");
+				}
+				
+				/**
+				 * PTVS Project
+				 * i should know the location of the event
+				 */			
+				Road r = null;
+				Point p = null;
+				if(e instanceof SendEvent){
+					SendEvent se=(SendEvent)e;
+					r = (Road) Globals.map.roads.get(se.sender.getRoadIdx());	//aflu strada pe care se afla senderul
+					p = (Point) r.points.get(se.sender.getPointIdx());			//aflu punctul unde se afla senderul
+				}
+				if(e instanceof ReceiveEvent){
+					ReceiveEvent re=(ReceiveEvent)e;
+					r = (Road) Globals.map.roads.get(re.sender.getRoadIdx());
+					p = (Point) r.points.get(re.sender.getPointIdx());
+				}
+				
+				//System.out.println("p:"+p);
+				
+				/**
+				 * PTVS Project
+				 * from intersections array, i find the closest one
+				 */
+				double MIN_DIST=Double.MAX_VALUE;
+				int indexClosestIntersection=0;
+				double distanta;
+				for(int i=0;i<intersectii.size();i++){ 
+					Intersection intersectie = intersectii.get(i);
+					if(r.getPoints().contains(intersectie.getMapPoint())){ //iau in calcul doar intersectiile aflate pe strada pe care sunt
+						distanta=GPSutil.distance(p, intersectie.getMapPoint());
+						if (distanta < MIN_DIST){
+							MIN_DIST=distanta;
+							indexClosestIntersection=i;						
+						}
+					}
+						
+				}
+				
+				/**
+				 * PTVS Project
+				 * i will assign a thread for the event
+				 */
+				
+				
+				if (e.getTime() == crtTime) {
+				
+					if(e instanceof SendEvent){		
+						
+							System.out.print("SendEvent: ");
+							//processingThreads[indexClosestIntersection] = new SendEventProcessingThread(e,this);
+						}
+					else {					
+							System.out.print("ReceiveEvent: ");
+							//processingThreads[indexClosestIntersection] = new ReceiveEventProcessingThread(e,this);
+						}
+					
+					System.out.println("Processing thread "+indexClosestIntersection+" from intersection "+intersectii.get(indexClosestIntersection));
+					
+					try {
+						int indexThread = indexClosestIntersection % (Globals.NO_FEP_PROC - 1);
+						start(e, indexThread);
+						cnt++;
+						
+					} catch (IOException e1) {
+						System.out.println("exception on assigning event for thread");
+						e1.printStackTrace();
+					}
+					
+					//new Thread(processingThreads[indexClosestIntersection]).start();
+					
+				}
+				else
+					break;
+			}
+			
+			else if (e.getTime() == crtTime) {
+				System.out.println("OtherEvent ");
+				playEvent(null);
+				cnt++;
+				
+			} else
+				break;
+			
+			
+		}
+		
+		///////////////////////end PTVS Project/////////////////////////////////////////////////////
+		
+		//increment simulation time
+		crtTime++;
+		//System.out.println("Increment crtTime!  crtTime:"+crtTime);
+		
+		long t3 = System.currentTimeMillis();
+		if (crtTime % (Globals.executionFPS / Globals.FPS) == 0)
+			if (!runtimeMobility)
+				readScenarioPhase();
+			else
+				generateScenarioPhase();
+		
+		checkCreateNewCars();
+		
+		long t4 = System.currentTimeMillis();
+		eventsTime += t3 - t2;
+		mobilityTime += t4 - t3;
+
+		if (Engine.simulationType == RoutingConstants.DYNAMIC_INFRASTRUCTURE_ROUTE) {
+			if (crtTime % 100 == 0) {
+				for (int i = 0; i < this.infrastructure.size(); i++) {
+					
+					((InfrastructureNode) this.infrastructure.get(i)).updateDelays();
+				}
+			}
+		}
+		if (Engine.simulationType == RoutingConstants.DYNAMIC_CITY_ROUTE) {
+			for (int i = 0; i < this.infrastructure.size(); i++) {
+				((IntersectionNode) infrastructure.get(i)).step(crtTime);
+			}
+			server.step(crtTime);
+		}
+	}
+	//////////////////////////////////////////////end metoda step////////////////////////////////////
+
+	static Random random = new Random();
+
+	public static int lastCarID = 0;
+
+	/**
+	 * Insert new cars at the map entry points according to the scheduled flow. 
+	 *
+	 */
+	private void checkCreateNewCars(){
+
+		int percent;
+//		should create some new cars?
+		NewCarEvent first=Mobility.events.first();
+		while(first!=null && first.timestamp==crtTime) {
+			//create this one
+			EntryScenario es=Mobility.entryScenarios.get(first.index);
+
+			int roadIndexSrc=es.entry.roadIdx;
+			int pointIndexSrc=es.entry.ptIdx;
+
+			int ID=lastCarID;
+			lastCarID++;
+
+			//which exit is the car going towards?
+			double rand;
+			rand=(random.nextDouble())*100;
+			int i=0;
+			int sum=0;
+			while(i<es.entryExits.size()) {
+				sum+=es.entryExits.elementAt(i).percentOfFlow;
+				if(rand<sum) {
+					//this is the chosen exit
+					break;
+				}
+				i++;
+			}
+			EntryExitScenario ees=null;
+			if(i==es.entryExits.size()) {
+				//last exit chosen
+				ees=es.entryExits.lastElement();
+			} else 
+				ees=es.entryExits.elementAt(i);
+
+			int roadIndexDst=ees.exit.roadIdx;
+			int pointIndexDst=ees.exit.ptIdx;
+
+			//which route is the car choosing?
+			rand=(random.nextDouble())*100;
+			i=0;
+			sum=0;
+			while(i<ees.percentsEachRoute.size()) {
+				sum+=ees.percentsEachRoute.elementAt(i);
+				if(rand<sum) {
+					//this is the chosen route
+					break;
+				}
+				i++;
+			}
+			Route r=null;
+			if(i==ees.percentsEachRoute.size()) {
+				//last route chosen
+				r=ees.routes.lastElement();
+			} else 
+				r=ees.routes.elementAt(i);
+
+			for(i=0;i<Globals.map.roads.get(roadIndexSrc).laneNo;i++) {
+				//one vehicle on each lane
+
+				Personality personality;
+				rand=(random.nextDouble())*100;
+				if(rand<es.percentsDriverTypes.elementAt(0)) 
+				{
+					personality=new CalmPersonality();
+				} else if(rand<es.percentsDriverTypes.elementAt(0)+es.percentsDriverTypes.elementAt(1)) {
+					personality=new RegularPersonality();
+				} else {
+					personality=new AggresivePersonality();
+				}
+				
+				CarInstance car = null;
+				if (simulationType == RoutingConstants.INITIALLY_PROVIDED_ROUTE || simulationType == RoutingConstants.ROUTING_SCFT) {
+					
+					car = Mobility.createNewCar(roadIndexSrc,
+							pointIndexSrc, 0, i + 1, 0.0, personality, /*personality.getWantedSpeed(roadIndexSrc)*/ 0.0, ID,
+							roadIndexDst, pointIndexDst, r.route);
+					
+					System.out.println("Finished creating new car "+car);
+					
+					double d =0;
+					if(car!=null)
+						d = car.getDistanceToCarInFront();
+					if (d < 10 && d!=0) {
+						// closer than 5 meters --> do not create
+						// System.out.println("Skipping creation...");
+						Globals.map.roads.get(car.getRoadIdx()).carsOnThisRoad.remove(car.ID);
+						continue;
+					}
+				}
+
+				if (Engine.simulationType == RoutingConstants.DYNAMIC_SELF_ROUTE) {
+					System.out.println("Dynamic; we are here");
+					percent = random.nextInt(100);
+					percent = (int) Math.abs((double) percent);
+					if (percent <= Globals.routePlanConstants.percentBestRoute) {
+						percent = 1;
+					} else {
+						percent = 0;
+					}
+					car = Mobility.createNewCar(roadIndexSrc, pointIndexSrc, 0,
+							i + 1, 0.0, personality, 0.0, ID, roadIndexDst,
+							pointIndexDst, r.route, percent);
+					if (car == null) {
+					
+						continue;
+					}
+					double d = car.getDistanceToCarInFront();
+					if (d < 10) {
+						// closer than 10 meters --> do not create
+						
+						Globals.map.roads.get(car.getRoadIdx()).carsOnThisRoad.remove(car.ID);						
+						continue;
+					}
+
+				}
+				if (Engine.simulationType == RoutingConstants.DYNAMIC_INFRASTRUCTURE_ROUTE) {
+
+					car = Mobility.createNewCarCommunicatingWithInfrastucture(
+							roadIndexSrc, pointIndexSrc, 0, i + 1, 0.0,
+							personality, 0.0, ID, roadIndexDst, pointIndexDst,
+							r.route);
+					if (car == null) {
+						
+						continue;
+					}
+					double d = car.getDistanceToCarInFront();
+					if (d < 10) {
+						// closer than 10 meters --> do not create						
+						Globals.map.roads.get(car.getRoadIdx()).carsOnThisRoad
+								.remove(car.ID);
+						
+
+						continue;
+					}
+
+				}
+				
+				//create new ezcab client (entity)
+				
+				if (Engine.simulationType == RoutingConstants.DYNAMIC_CITY_ROUTE) {
+
+					car = Mobility.createNewCityCarCommunicatingWithInfrastucture(
+							roadIndexSrc, pointIndexSrc, 0, i + 1, 0.0,
+							personality, 0.0, ID, roadIndexDst, pointIndexDst,
+							r.route);
+					if (car == null) {					
+						continue;
+					}
+					double d = car.getDistanceToCarInFront();
+					if (d < 10) {
+						// closer than 10 meters --> do not create						
+						Globals.map.roads.get(car.getRoadIdx()).carsOnThisRoad
+								.remove(car.ID);
+						
+
+						continue;
+					}
+
+				}
+
+				ID = lastCarID;
+				lastCarID++;
+				this.addCar(car);
+			}
+			Mobility.events.removeFirst();
+			
+			try {
+				EntryFlowVariation efv=Mobility.entryFlowVariations.get(first.index);
+				
+				if(efv.getFirstMom()<crtTime && efv.getFirstMom()!=-1) {
+					int newFlow=efv.getFirstValue();
+					int old=first.period;
+					first.period=(int)((double)(3600 * Globals.SECOND) / newFlow);
+					System.out.print("TIME="+crtTime+"; CHANGING PERIOD FOR ENTRY="+first.index+" FROM: "+old+" TO: "+first.period);
+					efv.removeFirst();
+				}
+			} catch (Exception ex) {
+				
+			}
+			if(Globals.SOCIALNETWORK == 0 )
+				Mobility.events.addEvent(new NewCarEvent(first.timestamp
+						+ first.period, first.index, first.period));
+			first = Mobility.events.first();
+		}
+	}
+
+////////////////////////////////////////// playEvent ////////////////////////////////////////////////////////////////	
+
+	long messagesSize = 0;
+	long carInfosSize = 0;
+	/**
+	 * Execute the following event in the eventQueue
+	 * 
+	 */
+	public void playEvent(Event ev) {
+	//public void playEvent() {
+		
+		//System.out.println(">> Thread:"+Thread.currentThread().getName());
+		
+		if (eventQueue.size() == 0) {
+			doneFlag = true;
+			return;
+		}
+
+		Event e = null;
+		if (ev == null) {
+			synchronized (eventQueue) {
+				e = eventQueue.remove(0);
+				//System.out.println("remove from eventQueue");
+			}
+		} else {
+			e = ev;
+			synchronized (eventQueue) { nrEvThreads--; }
+		}
+		//System.out.print(e.toString()+", ");
+		//System.out.flush();
+				
+		if (e instanceof GPSEvent) {	//////////// eveniment GPS
+			
+			Iterator<SimulatedCarInfo> it = cars.iterator();
+			while (it.hasNext()) {
+				SimulatedCarInfo r = it.next();
+				r.update();
+			}
+			GPSEvent newEvent = new GPSEvent(crtTime + fps);
+			schedEvent(newEvent);
+		}
+		if (e instanceof CleanupEvent) {	//////////// eveniment CLEANUP
+
+			long t1 = System.currentTimeMillis();
+			long deleted = 0;
+			Iterator<SimulatedCarInfo> it = cars.iterator();
+			while (it.hasNext()) {
+				SimulatedCarInfo r = it.next();
+synchronized (r.trafficDB) {
+				Iterator<CarInfo> j = r.trafficDB.iterator();
+				while (j.hasNext()) {
+					CarInfo neighbor = j.next();
+					if ( (crtTime - neighbor.getTimestamp() > Globals.NEIGHBOR_EXPIRES && neighbor.state != 3) ||
+							(neighbor.state == 3 && crtTime - neighbor.getTimestamp() > Globals.PROMISCUOUS_NEIGHBOR_EXPIRES)){
+						j.remove();
+					}
+				}
+}
+				carInfosSize += r.trafficDB.size();
+			}
+			for (int j = 0; j < Globals.map.lightsIndices.size(); j++) {
+				WirelessTrafficLight wtl = (WirelessTrafficLight) Globals.map.allIntersections
+						.get(Globals.map.lightsIndices.get(j));
+				
+				synchronized(wtl.trafficDB){
+					Iterator<IntersectionCarRecord> wtlit = wtl.trafficDB.iterator();
+					while (wtlit.hasNext()) {
+						IntersectionCarRecord icr = wtlit.next();
+						if (!icr.isPassed() && crtTime - icr.getCar().getTimestamp() > Globals.HOUR 
+								&& icr.getCar().state != 3){
+							icr.segment.cars.remove(icr);
+							wtlit.remove();
+							deleted++;
+						}
+						if (icr.isPassed() && crtTime - icr.getCar().getTimestamp() > Globals.TRAFFICLIGHT_NEIGHBOR_EXPIRES){
+							icr.segment.cars.remove(icr);
+							wtlit.remove();
+						}
+					}
+				}
+			}
+			long t2 = System.currentTimeMillis();
+			cleanupTime += t2 - t1;
+			if (!disableComm) {
+				CleanupEvent newCleanupEvent = new CleanupEvent(crtTime + fps);
+				schedEvent(newCleanupEvent);
+			}
+			messagesSize = 0;
+		}
+		
+		if (e instanceof SendEvent) {	/////////////////////////////// eveniment SEND
+			
+			SendEvent se = (SendEvent) e;
+			Communicator sender = se.getSender();
+			
+			long t1 = System.currentTimeMillis();	
+			
+			// senderul e un SimulatedCarInfo
+			
+			if (se.getMessage() == null){
+				byte[] message = sender.prepareMessage(se.getMessageType());
+				se.setMessage(message);
+				if (se.getMessage() == null){
+					if (sender.isPromiscuousMode() && sender.isPeriodicalMessage(se.getMessageType()) && !disableComm) {
+						int eventPeriod = sender.getPeriod(se.getMessageType());
+						if (eventPeriod != -1)
+							schedEvent(new SendEvent(crtTime + eventPeriod, sender, se.getMessageType()));
+					}
+					return;
+				}
+				messagesSize += message.length;
+				long t2 = System.currentTimeMillis();
+				codeTime += t2 - t1;
+
+				if (sender.isPeriodicalMessage(se.getMessageType()) && !disableComm) {
+					int eventPeriod = sender.getPeriod(se.getMessageType());
+					if (eventPeriod != -1)
+						schedEvent(new SendEvent(crtTime + eventPeriod, sender, se.getMessageType()));
+				}
+			}
+			
+			//Petroaca - the DSRC impl
+			if(Engine.simulationProtocol==Globals.PROTOCOL_80211)
+			{
+				
+				if (!sender.mediumAvailable(crtTime)) {
+					e.setTime(crtTime + 1);
+					schedEvent(e);
+					
+					return;
+				}
+				
+				sender.getRadio().setRadioTxMode();
+				simulateCommunication(se);
+			
+			}
+			else
+			{
+				if(sender instanceof CarRunningDSRC)
+				{
+					MAC80211 macs=((CarRunningDSRC)sender).getMac();
+					WirelessPhy phys=((CarRunningDSRC)sender).getPhysical();
+					
+					macs.refreshFrameTime(crtTime);
+					phys.refreshFrameTime(crtTime);
+					
+					if(macs.sendToPhysical(se.getMessage(),crtTime)!=null)
+					{
+						phys.sendToChannel(se.getMessage(),crtTime);
+						macs.setChannelState(Globals.CCA_BUSY);
+						simulateCommunication(se);
+					}
+					else
+					{
+					
+						e.setTime(crtTime+1);
+						schedEvent(e);
+						
+					}
+					return;
+				} 
+				else
+				{
+					if (!sender.mediumAvailable(crtTime)) {
+						e.setTime(crtTime + 1);
+						schedEvent(e);
+						
+						return;
+					}
+					
+					sender.getRadio().setRadioTxMode();
+					simulateCommunication(se);
+				}
+			}
+		}
+		
+		if (e instanceof ReceiveEvent) {	//////////////////////// eveniment RECEIVE
+			ReceiveEvent re = (ReceiveEvent) e;
+
+				long t1 = System.currentTimeMillis();
+				
+				//Petroaca - the DSRC impl
+				if(Engine.simulationProtocol==Globals.PROTOCOL_80211){
+					RadioDev rxradio = re.receiver.getRadio();
+					ReceiveEvent goodSignal = rxradio.receive(re.signals);
+					re.receiver.removeReceiveEventForTime(re.getTime());
+				
+					if (goodSignal != null){
+							re.receiver.onReceive(goodSignal.getMessage(), goodSignal.getMessageObject(), goodSignal.sender);
+						}
+				}
+				else
+				{
+					if(re.receiver instanceof CarRunningDSRC)
+					{
+						MAC80211 macr=((CarRunningDSRC)re.receiver).getMac();
+						WirelessPhy phyr=((CarRunningDSRC)re.receiver).getPhysical();
+						Application appr=((CarRunningDSRC)re.receiver).getAppLayer();
+						
+						if(Globals.DIFFERENTIAL_CW)
+							macr.recalculateCW(phyr.getTotalReceivedPackets(),crtTime);
+						
+						macr.refreshFrameTime(crtTime);
+						phyr.refreshFrameTime(crtTime);
+						appr.refreshApplication(crtTime);
+						
+						ReceiveEvent best=phyr.recvFromChannel(re.signals,crtTime);
+						re.receiver.removeReceiveEventForTime(re.getTime());
+						
+						double sinr=phyr.getSINR();
+						if(best!=null)
+						{
+							macr.setChannelState(Globals.CCA_BUSY);	
+							
+							if(macr.recvFromPhysical(best,sinr,crtTime)!=null)
+							{
+								appr.ForwardCollisionWarning(best.getMessage(),((CarInfo)re.receiver));
+								//appr.LaneChangeAssistance(best.getMessage(),((CarInfo)re.receiver));
+								re.receiver.onReceive(best.getMessage(), best.getMessageObject(), best.sender);
+							}
+						}
+					}
+					else
+					{
+						RadioDev rxradio = re.receiver.getRadio();
+						ReceiveEvent goodSignal = rxradio.receive(re.signals);
+						re.receiver.removeReceiveEventForTime(re.getTime());
+					
+						if (goodSignal != null){
+								re.receiver.onReceive(goodSignal.getMessage(), goodSignal.getMessageObject(), goodSignal.sender);
+							}
+					}
+				}	
+				
+				long t2 = System.currentTimeMillis();
+				codeTime += t2 - t1;
+			}
+	}
+
+
+	public void playEventEmergency()
+	{
+		if (eventQueueEmergency.size() == 0) {
+			doneFlagEmergency = true;
+			return;
+		}
+
+		Event e = null;
+		synchronized (eventQueueEmergency) {
+			e = eventQueueEmergency.remove(0);
+		}
+		
+		if (e instanceof SendEvent) {
+			SendEvent se = (SendEvent) e;
+			Communicator sender = se.getSender();
+			
+			long t1 = System.currentTimeMillis();	
+			
+			
+			if (se.getMessage() == null){
+				byte[] message = sender.prepareMessage(se.getMessageType());
+				se.setMessage(message);
+				if (se.getMessage() == null){
+	//				System.out.println("null message"+se.sender + " "+se.sender.getClass());
+					if (sender.isPromiscuousMode() && sender.isPeriodicalMessage(se.getMessageType()) && !disableComm) {
+						int eventPeriod = sender.getPeriod(se.getMessageType());
+						if (eventPeriod != -1)
+							schedEventEmergency(new SendEvent(crtTime + eventPeriod, sender, se.getMessageType()));
+					}
+					return;
+				}
+				messagesSize += message.length;
+				long t2 = System.currentTimeMillis();
+				codeTime += t2 - t1;
+
+				if (sender.isPeriodicalMessage(se.getMessageType()) && !disableComm) {
+					int eventPeriod = sender.getPeriod(se.getMessageType());
+					if (eventPeriod != -1)
+						schedEventEmergency(new SendEvent(crtTime + eventPeriod, sender, se.getMessageType()));
+				}
+			}
+			
+			//Petroaca - the DSRC impl
+				if(sender instanceof CarRunningDSRC)
+				{
+					MAC80211 macs=((CarRunningDSRC)sender).getMac();
+					WirelessPhy phys=((CarRunningDSRC)sender).getPhysical();
+					
+					macs.refreshFrameTime(crtTime);
+					phys.refreshFrameTime(crtTime);
+					
+					if(macs.sendToPhysical(se.getMessage(),crtTime)!=null)
+					{
+						phys.sendToChannel(se.getMessage(),crtTime);
+						macs.setChannelState(Globals.CCA_BUSY);
+						simulateCommunicationEmergency(se);
+					}
+					else
+					{
+					
+						e.setTime(crtTime+1);
+						schedEventEmergency(e);
+						
+					}
+					return;
+				}
+				
+				if(sender instanceof CarRunningDSRC)
+				{
+					return;
+				}
+				else
+				{
+					return;
+				}
+			}
+			
+		if (e instanceof ReceiveEvent) {
+			ReceiveEvent re = (ReceiveEvent) e;
+			
+			long t1 = System.currentTimeMillis();
+			
+			//Petroaca - the DSRC impl
+				
+					if(re.receiver instanceof CarRunningDSRC)
+					{
+						MAC80211 macr=((CarRunningDSRC)re.receiver).getMac();
+						WirelessPhy phyr=((CarRunningDSRC)re.receiver).getPhysical();
+						Application appr=((CarRunningDSRC)re.receiver).getAppLayer();
+						appr.refreshApplication(crtTime);
+						
+						if(Globals.DIFFERENTIAL_CW)
+							macr.recalculateCW(phyr.getTotalReceivedPackets(),crtTime);
+						
+						macr.refreshFrameTime(crtTime);
+						phyr.refreshFrameTime(crtTime);
+						
+						ReceiveEvent best=phyr.recvFromChannel(re.signals,crtTime);
+						((SimulatedCarInfo)re.receiver).removeReceiveEventEmergencyForTime(re.getTime());
+						
+						double sinr=phyr.getSINR();
+						if(best!=null)
+						{
+							macr.setChannelState(Globals.CCA_BUSY);	
+							
+							if(macr.recvFromPhysical(best,sinr,crtTime)!=null)
+							{
+								//appr.ForwardCollisionWarning(best.getMessage(),((CarInfo)re.receiver));
+								//appr.LaneChangeAssistance(best.getMessage(),((CarInfo)re.receiver));
+								re.receiver.onReceive(best.getMessage(), best.getMessageObject(), best.sender);
+							}
+						}
+					}
+					long t2 = System.currentTimeMillis();
+					codeTime += t2 - t1;
+				}	
+	}
+	
+	/**
+	 * Applications may schedule dynamically communication events using this method
+	 * to insert new events in the queue.
+	 * 
+	 * @param e Event to schedule
+	 */
+	public void schedEvent(Event e) {
+
+		long t1 = System.currentTimeMillis();
+
+		if (e instanceof ReceiveEvent) {
+			ReceiveEvent re = (ReceiveEvent) e;
+			ReceiveEvent existing = re.receiver.getReceiveEventForTime(e.getTime());
+			//getReceiveEventForTime returneaza evenimentele receive petrecute la momentul e.getTime()
+			
+			if (existing == null){
+				re.receiver.addReceiveEventForTime(re);
+			}else{
+				existing.signals.add(re);
+				return;
+			}
+		}
+		
+		// cauta evenimetul in coada, ii gaseste pozitia corecta in lista de evenimente si il adauga 
+		// ce face de fapt? de ce cauta un eveniment si il readauga tot pe el in lista???
+		int idx = Collections.binarySearch(eventQueue, e);
+		synchronized (eventQueue) {
+			if (idx >= 0) {
+				// advance till the end of the sequence of equal events
+				if (eventQueue.get(idx).equals(e))
+					idx++;
+				eventQueue.add(idx, e);
+				//System.out.println("add in eventQueue..");
+			} else {
+				eventQueue.add(-(idx + 1), e);
+				//System.out.println("add in eventQueue....");
+			}
+		}
+		long t2 = System.currentTimeMillis();
+		schedTime += t2 - t1;
+	}
+
+	//Petroaca - the message scheduler for the emergency channel
+	public void schedEventEmergency(Event e)
+	{
+		long t1 = System.currentTimeMillis();
+
+		if (e instanceof ReceiveEvent) {
+			ReceiveEvent re = (ReceiveEvent) e;
+			ReceiveEvent existing = ((SimulatedCarInfo)re.receiver).getReceiveEventEmergencyForTime(e.getTime());
+			if (existing == null){
+				((SimulatedCarInfo)re.receiver).addReceiveEventEmergencyForTime(re);
+			}else{
+				existing.signals.add(re);
+				return;
+			}
+		}
+		
+		int idx = Collections.binarySearch(eventQueueEmergency, e);
+		synchronized (eventQueueEmergency) {
+			if (idx >= 0) {
+				// advance till the end of the sequence of equal events
+				if (eventQueueEmergency.get(idx).equals(e))
+					idx++;
+				eventQueueEmergency.add(idx, e);
+			} else {
+				eventQueueEmergency.add(-(idx + 1), e);
+			}
+		}
+		long t2 = System.currentTimeMillis();
+		schedTime += t2 - t1;
+	}
+	
+	/**
+	 * Generate the receive events corresponding to one send event, for the cars
+	 * in the wireless range of the sending car.
+	 * 
+	 */
+	public void simulateCommunication(SendEvent e) {
+		
+		Road r1 = null;
+		Point p1 = null;
+		r1 = (Road) Globals.map.roads.get(e.sender.getRoadIdx());
+		p1 = (Point) r1.points.get(e.sender.getPointIdx());
+		
+		if (e instanceof UnicastSendEvent) {
+			long t1 = System.currentTimeMillis();
+			Iterator<SimulatedCarInfo> it = cars.iterator();
+			ReceiveEvent re = null;
+			while (it.hasNext()) {
+				SimulatedCarInfo r = it.next();
+				if (r.vehicleId == ((UnicastSendEvent) e).getReceiverId()) {
+					Road r2 = (Road) Globals.map.roads.get(r.getRealPos().getRoadIdx());
+					Point p2 = (Point) r2.points.get(r.getRealPos().getPointIdx());
+
+					// MODIFIED BY CRISTI!!!
+					// ReceiveEvent er = new ReceiveEvent(e.getTime() + 1, r, e.getMessage());
+
+					re = new ReceiveEvent(e.getTime() + 1, r, e.getMessage(), e.getMessageObject(), e.getMessageType());
+					re.setUnicast(true);
+
+					schedEvent(re);
+					if (GPSutil.distance(p1, p2) < WIRELESS_RANGE) {
+					} else {
+						System.out.println("EROARE! DISTANCE="+ GPSutil.distance(p1, p2));
+					}
+					// END MODIFIED!!!
+					return;
+				}
+			}
+			
+			
+			re.setSender(e.getSender());
+			
+			schedEvent(re);
+
+			long t2 = System.currentTimeMillis();
+			netTime += t2 - t1;
+
+		} else {
+			
+			long tmp = 0;
+			long t3 = System.currentTimeMillis();
+			long t4;
+
+//			re = new ReceiveEvent(e.getTime() + 1, e.getSender(), e.getMessage());
+			
+
+			int cnt3 = 0;
+			int pkcnt = 0;
+			PeanoKey pk = Globals.map.peanoKeys.get(p1.getPeanoKeyIdx());
+
+			ListIterator<PeanoKey> pkit = Globals.map.peanoKeys.listIterator(p1.getPeanoKeyIdx());
+			PeanoKey maxpk = null;
+			
+			double wifirange;
+			if (e.sender instanceof WirelessTrafficLight){
+				maxpk = GPSutil.getMaxSearchBoundPK(p1,Engine.EXTENDED_WIRELESS_RANGE);
+				wifirange = EXTENDED_WIRELESS_RANGE;
+			}else{
+				wifirange = WIRELESS_RANGE;
+				maxpk = pk.getMaxpk();
+			}
+			
+			PeanoKey pkx = null;
+			for (pkx = pkit.next(); pkit.hasNext(); pkx = pkit.next()) {
+				pkcnt++;
+				// long tc1 = System.currentTimeMillis();
+				if (pkx.compareTo(maxpk) > 0)
+					break;
+				// long tc2 = System.currentTimeMillis();
+				// comp += (tc2-tc1);
+
+				if (pkx.getCars() != null) {
+					Road r2 = (Road) Globals.map.roads.get(pkx.getRoadIndex());
+					Point p2 = (Point) r2.points.get(pkx.getPointIndex());
+					if (GPSutil.distance(p1, p2) < 5 * wifirange) {
+						cnt3 += pkx.getCars().size();
+						Iterator<SimulatedCarInfo> it = pkx.getCars().iterator();
+						while (it.hasNext()) {
+							SimulatedCarInfo r = it.next();
+							if (e.sender instanceof SimulatedCarInfo)
+								if (r.getVehicleId() == ((SimulatedCarInfo)e.sender).getVehicleId())
+									continue;
+							r.setLastMediumTransmition(crtTime);
+							
+							ReceiveEvent re = new ReceiveEvent(e.getTime() + 1, r, e.getMessage(), e.getMessageObject(), e.getMessageType());
+							re.setSender(e.getSender());
+							schedEvent(re);
+						}
+					}
+				}
+			}
+			PeanoKey minpk = null;
+			if (e.sender instanceof WirelessTrafficLight)
+				minpk = GPSutil.getMaxSearchBoundPK(p1,-Engine.EXTENDED_WIRELESS_RANGE);
+			else
+				minpk = pk.getMinpk();
+			
+			pkit = Globals.map.peanoKeys.listIterator(p1.getPeanoKeyIdx());
+
+			if (pkit.hasPrevious()){
+				pkx = pkit.previous();
+			}
+			for (; pkit.hasPrevious(); pkx = pkit.previous()) {
+				pkcnt++;
+				// long tc1 = System.currentTimeMillis();
+				if (pkx.compareTo(minpk) < 0) {
+					break;
+				}
+				// long tc2 = System.currentTimeMillis();
+				// comp += (tc2-tc1);
+
+				if (pkx.getCars() != null) {
+					Road r2 = (Road) Globals.map.roads.get(pkx.getRoadIndex());
+					Point p2 = (Point) r2.points.get(pkx.getPointIndex());
+					double distance = GPSutil.distance(p1, p2);
+					if (distance < 5 * wifirange) {
+						Iterator<SimulatedCarInfo> it = pkx.getCars().iterator();
+						cnt3 += pkx.getCars().size();
+						while (it.hasNext()) {
+							SimulatedCarInfo r = it.next();
+							
+							r.setLastMediumTransmition(crtTime);
+						
+							if (e.sender instanceof SimulatedCarInfo)
+								if (r.getVehicleId() == ((SimulatedCarInfo)e.sender).getVehicleId())
+									continue;
+							ReceiveEvent re = new ReceiveEvent(e.getTime() + 1, r, e.getMessage(), e.getMessageObject(), e.getMessageType());
+							re.setSender(e.getSender());
+							schedEvent(re);
+						}
+					}
+				}
+			}
+			
+			for (int j = 0; j < Globals.map.lightsIndices.size(); j++) {
+				WirelessTrafficLight wtl = (WirelessTrafficLight) Globals.map.allIntersections
+						.get(Globals.map.lightsIndices.get(j));
+				long t1sem = System.currentTimeMillis();
+
+				if (GPSutil.distance(p1, wtl.getMapPoint()) < 5 * WIRELESS_RANGE) {
+					wtl.setLastMediumTransmition(crtTime);
+					ReceiveEvent re = new ReceiveEvent(e.getTime() + 1, wtl, e.getMessage(), e.getMessageObject(), e.getMessageType());
+					re.setSender(e.getSender());
+					schedEvent(re);
+				}
+				long t2sem = System.currentTimeMillis();
+				semTime += (t2sem - t1sem);
+			}
+			
+			t4 = System.currentTimeMillis();
+			tmp += t4 - t3;
+			netTime += tmp;
+		}
+	}
+
+	//Petroaca - the communication simulation for the emergency channel
+	public void simulateCommunicationEmergency(SendEvent e) {
+
+		Road r1 = null;
+		Point p1 = null;
+		r1 = (Road) Globals.map.roads.get(e.sender.getRoadIdx());
+		p1 = (Point) r1.points.get(e.sender.getPointIdx());
+		
+		if (e instanceof UnicastSendEvent) {
+			long t1 = System.currentTimeMillis();
+			Iterator<SimulatedCarInfo> it = cars.iterator();
+			ReceiveEvent re = null;
+			while (it.hasNext()) {
+				SimulatedCarInfo r = it.next();
+				if (r.vehicleId == ((UnicastSendEvent) e).getReceiverId()) {
+					Road r2 = (Road) Globals.map.roads.get(r.getRealPos()
+							.getRoadIdx());
+					Point p2 = (Point) r2.points.get(r.getRealPos()
+							.getPointIdx());
+
+					// MODIFIED BY CRISTI!!!
+					// ReceiveEvent er = new ReceiveEvent(e.getTime() + 1, r,
+					// e.getMessage());
+
+					re = new ReceiveEvent(e.getTime() + 1, r, e.getMessage(), e.getMessageObject(), e.getMessageType());
+					re.setUnicast(true);
+
+					schedEventEmergency(re);
+					if (GPSutil.distance(p1, p2) < WIRELESS_RANGE) {
+					} else {
+						System.out.println("EROARE! DISTANCE="
+								+ GPSutil.distance(p1, p2));
+					}
+					// END MODIFIED!!!
+					return;
+				}
+			}
+			
+			re.setSender(e.getSender());
+			schedEventEmergency(re);
+
+			long t2 = System.currentTimeMillis();
+			netTime += t2 - t1;
+
+		} else {
+			
+			long tmp = 0;
+			long t3 = System.currentTimeMillis();
+			long t4;
+
+//			re = new ReceiveEvent(e.getTime() + 1, e.getSender(), e
+//					.getMessage());
+			
+
+			int cnt3 = 0;
+			int pkcnt = 0;
+			PeanoKey pk = Globals.map.peanoKeys.get(p1.getPeanoKeyIdx());
+
+			ListIterator<PeanoKey> pkit = Globals.map.peanoKeys
+					.listIterator(p1.getPeanoKeyIdx());
+			PeanoKey maxpk = null;
+			
+			double wifirange;
+			if (e.sender instanceof WirelessTrafficLight){
+				maxpk = GPSutil.getMaxSearchBoundPK(p1,Engine.EXTENDED_WIRELESS_RANGE);
+				wifirange = EXTENDED_WIRELESS_RANGE;
+			}else{
+				wifirange = WIRELESS_RANGE;
+				maxpk = pk.getMaxpk();
+			}
+			PeanoKey pkx = null;
+			for (pkx = pkit.next(); pkit.hasNext(); pkx = pkit.next()) {
+				pkcnt++;
+				// long tc1 = System.currentTimeMillis();
+				if (pkx.compareTo(maxpk) > 0)
+					break;
+				// long tc2 = System.currentTimeMillis();
+				// comp += (tc2-tc1);
+
+				if (pkx.getCars() != null) {
+					Road r2 = (Road) Globals.map.roads.get(pkx
+							.getRoadIndex());
+					Point p2 = (Point) r2.points.get(pkx.getPointIndex());
+					if (GPSutil.distance(p1, p2) < 5 * wifirange) {
+						cnt3 += pkx.getCars().size();
+						Iterator<SimulatedCarInfo> it = pkx.getCars()
+								.iterator();
+						while (it.hasNext()) {
+							SimulatedCarInfo r = it.next();
+							if (e.sender instanceof SimulatedCarInfo)
+								if (r.getVehicleId() == ((SimulatedCarInfo)e.sender)
+									.getVehicleId())
+									continue;
+							r.setLastMediumTransmition(crtTime);
+							
+							ReceiveEvent re = new ReceiveEvent(e.getTime() + 1, r, e.getMessage(), e.getMessageObject(), e.getMessageType());
+							re.setSender(e.getSender());
+							schedEventEmergency(re);
+						}
+					}
+				}
+			}
+			PeanoKey minpk = null;
+			if (e.sender instanceof WirelessTrafficLight)
+				minpk = GPSutil.getMaxSearchBoundPK(p1,-Engine.EXTENDED_WIRELESS_RANGE);
+			else
+				minpk = pk.getMinpk();
+			
+			pkit = Globals.map.peanoKeys.listIterator(p1.getPeanoKeyIdx());
+
+			if (pkit.hasPrevious()){
+				pkx = pkit.previous();
+			}
+			for (; pkit.hasPrevious(); pkx = pkit
+					.previous()) {
+				pkcnt++;
+				// long tc1 = System.currentTimeMillis();
+				if (pkx.compareTo(minpk) < 0) {
+					break;
+				}
+				// long tc2 = System.currentTimeMillis();
+				// comp += (tc2-tc1);
+
+				if (pkx.getCars() != null) {
+					Road r2 = (Road) Globals.map.roads.get(pkx
+							.getRoadIndex());
+					Point p2 = (Point) r2.points.get(pkx.getPointIndex());
+					double distance = GPSutil.distance(p1, p2);
+					if (distance < 5 * wifirange) {
+						Iterator<SimulatedCarInfo> it = pkx.getCars()
+								.iterator();
+						cnt3 += pkx.getCars().size();
+						while (it.hasNext()) {
+							SimulatedCarInfo r = it.next();
+							r.setLastMediumTransmition(crtTime);
+						
+							if (e.sender instanceof SimulatedCarInfo)
+								if (r.getVehicleId() == ((SimulatedCarInfo)e.sender)
+									.getVehicleId())
+									continue;
+							ReceiveEvent re = new ReceiveEvent(e.getTime() + 1, r, e.getMessage(), e.getMessageObject(), e.getMessageType());
+							re.setSender(e.getSender());
+							schedEventEmergency(re);
+						}
+					}
+				}
+			}
+			
+			t4 = System.currentTimeMillis();
+			tmp += t4 - t3;
+			netTime += tmp;
+		}
+	}
+	
+	/**
+	 * Adds a new car to the simulation. 
+	 * 
+	 * @param car The object that stores the physical behaviour of the vehicle to add
+	 */
+	public void addCar(CarInstance car) 
+	{
+		if (car == null)
+			return;
+		
+		car.timestamp = crtTime;
+		created ++;
+		synchronized (cars) 
+		{
+			SimulatedCarInfo dc = null;
+			if (crtTime == 0) {
+//				dc = new SimulatedCarInfo(car.ID, car.getLane(),
+//						car.getSpeed(), car.getRoadIdx(), car.getPointIdx(),
+//						car.getDirection(), car.getOffset());
+				/*
+				dc = new CarRunningVITP(car.ID, car.getLane(), car.getSpeed(),
+						car.getRoadIdx(), car.getPointIdx(),
+						car.getDirection(), car.getOffset());
+				*/
+				//EZcab car
+				if (applicationType == Globals.PROT_EZCAB){
+					dc=new EzcabCar(car.ID, car.getLane(), car.getSpeed(),
+							car.getRoadIdx(), car.getPointIdx(),
+							car.getDirection(), car.getOffset());
+					System.out.println("new ezcab car created");
+				}
+				else if (simulationType == RoutingConstants.ROUTING_SCFT) 
+					dc=new CarRunningSCFT(car.ID, car.getLane(), car.getSpeed(),
+							car.getRoadIdx(), car.getPointIdx(),
+							car.getDirection(), car.getOffset());
+				else
+					dc=new CarRunningDSRC(car.ID, car.getLane(), car.getSpeed(),
+						car.getRoadIdx(), car.getPointIdx(),
+						car.getDirection(), car.getOffset());
+				
+				dc.setTimestamp(crtTime);
+				dc.setRealPos(car);
+				cars.add(dc);
+				dc.init();
+			} 
+			else 
+			{
+				int poz = cars.indexOf(new SimulatedCarInfo(car.ID));
+				if (poz == -1) 
+				{
+					/*	
+					dc = new CarRunningVITP(car.ID, car.getLane(), car
+							.getSpeed(), car.getRoadIdx(), car.getPointIdx(),
+							car.getDirection(), car.getOffset());
+							*/
+					//Ezcab
+					if (applicationType == Globals.PROT_EZCAB){
+						if(System.currentTimeMillis() % 2 == 0){
+							dc = new EzcabClient(car.ID, car.getLane(), 1.0, //a minimum speed
+									car.getRoadIdx(), car.getPointIdx(),
+									car.getDirection(), car.getOffset());
+							
+//							dc=new EzcabCar(car.ID, car.getLane(), car.getSpeed(),
+//									car.getRoadIdx(), car.getPointIdx(),
+//									car.getDirection(), car.getOffset());
+							//System.out.println("new client created");
+						}
+						else {
+							dc=new EzcabCar(car.ID, car.getLane(), car.getSpeed(),
+									car.getRoadIdx(), car.getPointIdx(),
+									car.getDirection(), car.getOffset());
+							
+//							dc = new EzcabClient(car.ID, car.getLane(), 1.0, //a minimum speed
+//									car.getRoadIdx(), car.getPointIdx(),
+//									car.getDirection(), car.getOffset());
+							//System.out.println("new ezcab car created");
+						}
+					}
+					else if (simulationType == RoutingConstants.ROUTING_SCFT) 
+						dc=new CarRunningSCFT(car.ID, car.getLane(), car.getSpeed(),
+								car.getRoadIdx(), car.getPointIdx(),
+								car.getDirection(), car.getOffset());
+					else
+						dc=new CarRunningDSRC(car.ID, car.getLane(), car.getSpeed(),
+							car.getRoadIdx(), car.getPointIdx(),
+							car.getDirection(), car.getOffset());
+//					dc = new SimulatedCarInfo(car.ID, car.getLane(), car
+//							.getSpeed(), car.getRoadIdx(), car.getPointIdx(),
+//							car.getDirection(), car.getOffset());
+					
+					dc.setTimestamp(crtTime);
+					dc.setRealPos(car);
+					int t = 1 + random.nextInt(fps / 2 - 5);
+					schedEvent(new SendEvent(crtTime + t, dc,SimulatedCarInfo.STANDARD_MESSAGE_ID));
+					cars.add(dc);
+					dc.init();					
+				} 
+				else 
+				{
+					((SimulatedCarInfo) cars.get(poz)).setRealPos(car);
+				}
+			}
+		}
+	}
+
+	/*
+	 * Read a scenario phase from a traces file. Update the vehicle's position 
+	 * for the current step.
+	 * 
+	 */
+	public void readScenarioPhase() {
+		int nrCars = 0;
+		try {
+			int vehId, rdIdx, ptIdx;
+			byte dir, lane, speed;
+			double offset;
+			nrCars = dis.readInt();
+			// System.out.println(nrCars+" masini");
+
+			synchronized (cars) 
+			{
+				for (int i = 0; i < nrCars; i++) 
+				{
+					vehId 	= dis.readInt();
+					rdIdx   = dis.readInt();
+					ptIdx 	= dis.readInt();
+					offset 	= dis.readDouble();
+					dir		= (byte) dis.readInt();
+					lane 	= (byte) dis.readInt();
+					speed 	= (byte) dis.readDouble();
+
+					SimulatedCarInfo dc = null;
+					if (crtTime == 0) {
+						/*	
+						dc = new CarRunningVITP(vehId, lane, speed,
+								(short) rdIdx, (short) ptIdx, dir, offset);
+						*/
+						//create ezcab car
+						if (applicationType == Globals.PROT_EZCAB){
+							dc = new EzcabCar(vehId, lane, speed,
+									(short) rdIdx, (short) ptIdx, dir, offset);
+							System.out.println("new ezcab car");
+						}
+						else if (simulationType == RoutingConstants.ROUTING_SCFT)
+							dc = new CarRunningSCFT(vehId, lane, speed,
+									(short) rdIdx, (short) ptIdx, dir, offset);
+						else
+							dc = new CarRunningDSRC(vehId, lane, speed,
+								(short) rdIdx, (short) ptIdx, dir, offset);
+						// dc = new SimulatedCarInfo(vehId, lane, speed,
+						// (short)rdIdx, (short)ptIdx, dir, offset);
+						dc.setTimestamp(crtTime);
+						dc.setRealPos(new CarInstance((CarInfo) dc));
+						cars.add(dc);
+						dc.init();
+					} else {
+						int poz = cars.indexOf(new SimulatedCarInfo(vehId));
+						if (poz == -1) {
+							/*	
+							dc = new CarRunningVITP(vehId, lane, speed,
+									(short) rdIdx, (short) ptIdx, dir, offset);
+							*/
+							//create new ezcab car or client
+							if (applicationType == Globals.PROT_EZCAB){
+								if(System.currentTimeMillis() % 2 == 0){
+									dc = new EzcabClient(vehId, lane, 1.0, //minimum allowed speed
+											(short) rdIdx, (short) ptIdx, dir, offset);
+//									dc = new EzcabCar(vehId, lane, speed,
+//											(short) rdIdx, (short) ptIdx, dir, offset);
+									//System.out.println("new ezcab client created");
+								}
+								else{
+									dc = new EzcabCar(vehId, lane, speed,
+											(short) rdIdx, (short) ptIdx, dir, offset);
+//									dc = new EzcabClient(vehId, lane, 1.0, //minimum allowed speed
+//											(short) rdIdx, (short) ptIdx, dir, offset);
+									//System.out.println("new ezcab car created");
+								}
+							}
+							else if (simulationType == RoutingConstants.ROUTING_SCFT)
+								dc = new CarRunningSCFT(vehId, lane, speed,
+										(short) rdIdx, (short) ptIdx, dir, offset);
+							else
+								dc = new CarRunningDSRC(vehId, lane, speed,
+									(short) rdIdx, (short) ptIdx, dir, offset);
+							// dc = new SimulatedCarInfo(vehId, lane, speed,
+							// (short)rdIdx, (short)ptIdx, dir, offset);
+							dc.setTimestamp(crtTime);
+							dc.setRealPos(new CarInstance((CarInfo) dc));
+							cars.add(dc);
+							dc.init();
+						} else {
+							CarInstance ci = ((SimulatedCarInfo) cars.get(poz))
+									.getRealPos();
+							ci.deleteCarToPointMapping();
+							ci.setSpeed((byte) speed);
+							ci.setRoadIdx((short) rdIdx);
+							ci.setPointIdx((short) ptIdx);
+							ci.setLane(lane);
+							ci.setDirection((byte) dir);
+							ci.setOffset(offset);
+							ci.setTimestamp(crtTime);
+							ci.updateCarToPointMapping();
+						}
+					}
+				}
+			}
+		} catch (Exception e) {
+			System.err.println("Error reading scenario file");
+			e.printStackTrace();
+		}
+	}
+
+	public static boolean outputToFile = false;
+
+	public void generateScenarioPhase() {
+		
+		long t1sem = System.currentTimeMillis();
+		if (crtTime % Globals.SECOND == 0){
+			for (int j = 0; j < Globals.map.lightsIndices.size(); j++) {
+				IntersectionWithTrafficLights iwtl = (IntersectionWithTrafficLights) Globals.map.allIntersections
+				.get(Globals.map.lightsIndices.get(j));
+				iwtl.step(crtTime);
+			}
+		}
+		long t2sem = System.currentTimeMillis();
+		semTime += (t2sem - t1sem);
+
+		int NCARS = 0;
+
+		for (int j = 0; j < Globals.map.roads.size(); j++) {
+
+			//Petroaca - random car on road to send emergency message
+			Random r;
+			int randId=0;
+			if(Engine.simulationProtocol==Globals.PROTOCOL_DSRC)
+			{
+				r=new Random();
+				randId=r.nextInt(Globals.map.roads.get(j).carsOnThisRoad.size()+1);
+				
+			}
+			
+			SortedCarVector newVector = new SortedCarVector();
+			for (int k = Globals.map.roads.get(j).carsOnThisRoad.size() - 1; k >= 0; k--) {
+				CarInstance car = Globals.map.roads.get(j).carsOnThisRoad
+						.get(k);
+				if (car.finished) {
+					
+					totalControlDelay += car.totalControlDelay;
+					fincars ++;
+					if (maxControlDelay < car.totalControlDelay)
+						maxControlDelay = car.totalControlDelay;
+
+					synchronized (cars) {
+						if (car.startMonitor) {
+							crossedCars++;
+							totalEM.addEmissionsResults(car.em, 1);
+							totalkm += car.totalDistance - car.startMonitorDistance;
+							totalTime += (crtTime - car.startTime)/Globals.SECOND;
+						}
+						Globals.monitoredCars.remove(car.getSimulatedCarInfo());
+						car.finish();
+						car.deleteCarToPointMapping();
+						cars.remove(car.getSimulatedCarInfo());
+					}
+					continue;
+				}
+				try {
+					long t1 = System.currentTimeMillis();
+
+					synchronized (cars) {
+						car.deleteCarToPointMapping();
+						car.move();
+
+						if (Engine.simulationType == RoutingConstants.DYNAMIC_SELF_ROUTE) {
+							QueryGeneration.generateQueryForCar(car);
+						}
+
+						if (Engine.simulationType == RoutingConstants.DYNAMIC_INFRASTRUCTURE_ROUTE) {
+							GuidanceRequest.generateRequestToInfrastructure(car);
+						}
+						
+						if (Engine.simulationType == RoutingConstants.DYNAMIC_CITY_ROUTE) {
+							CarToIntersectionComm.updateMetrics(car);
+						}
+						
+//						Petroaca - emergency messages schedule
+						
+						if(Engine.simulationProtocol==Globals.PROTOCOL_DSRC && car.ID==randId && crtTime%50==0)
+						{
+							EmergencyRequest.generateEmergencyMessage(car);
+						}
+						
+						car.setTimestamp(crtTime);
+					
+						
+						
+						if (car.endMonitor){
+							crossedCars ++;
+							totalEM.addEmissionsResults(car.em, 1);
+							totalkm += car.totalDistance - car.startMonitorDistance;
+	//						System.out.println("Fuel: " + car.em.fc / 1000 +" "+ car.totalDistance + " "+car.em.fc * 100.0/ (10000 * car.totalDistance) + " "+(car.totalDistance * 3600.0)  / (double)(car.travelTime / Globals.SECOND));
+							car.endMonitor = false;
+							car.startMonitor = false;
+						}
+
+						car.updateCarToPointMapping();
+						 
+					}
+
+					long t2 = System.currentTimeMillis();
+					moveTime += t2 - t1;
+				} catch (Exception ex) {
+					ex.printStackTrace();
+				}
+				// if it has changed road, place it in the vector of its new
+				// road
+				if (car.getRoadIdx() != j) {
+					if (car.getRoadIdx() > j)
+						NCARS--; // it will be moved again when that road
+									// will be processed
+					Globals.map.roads.get(car.getRoadIdx()).carsOnThisRoad
+							.addCarInstance(car);
+				} else {
+					// it's still on the same road
+					newVector.addCarInstance(Globals.map.roads.get(j).carsOnThisRoad.get(k));
+				}
+				NCARS++;
+			}
+
+			// loop through the new vector and set the indices
+			for (int k = 0; k < newVector.size(); k++) {
+				newVector.get(k).index = k;
+			}
+			Globals.map.roads.get(j).carsOnThisRoad = newVector;
+		}
+	
+		
+		if (!outputToFile)
+			return;
+		// output text
+		try {
+			pwText.print(NCARS + " ");
+			outBin.writeInt(NCARS);
+			for (int j = 0; j < Globals.map.roads.size(); j++) {
+				for (int k = 0; k < Globals.map.roads.get(j).carsOnThisRoad
+						.size(); k++) {
+					CarInstance ci = Globals.map.roads.get(j).carsOnThisRoad
+							.get(k);
+					pwText.print(ci.ID + " " + ci.getRoadIdx() + " "
+							+ ci.getPointIdx() + " " + ci.getOffset() + " "
+							+ ci.getDirection() + " " + ci.getLane() + "   ");
+					outBin.writeInt(ci.ID);
+					outBin.writeInt(ci.getRoadIdx());
+					outBin.writeInt(ci.getPointIdx());
+					outBin.writeDouble(ci.getOffset());
+					outBin.writeInt(ci.getDirection());
+					outBin.writeInt(ci.getLane());
+					outBin.writeDouble(ci.getSpeed());
+				}
+			}
+			pwText.println();
+		} catch (IOException e) {
+			System.err.println("Error writing traces");
+			e.printStackTrace();
+			System.exit(0);
+		}
+	}
+	
+	public int getCrtTime(){
+		return crtTime;
+	}
+	
+	
+	
+	
+	public SimulatedCarInfo getCarIdx(int rdIdx, int ptIdx) 
+	{
+		synchronized (cars) 
+		{
+			Iterator<SimulatedCarInfo> it = cars.iterator();
+			while (it.hasNext()) {
+				SimulatedCarInfo r = it.next();
+				if (r.getRoadIdx() == rdIdx && r.getPointIdx() == ptIdx)
+					return r;
+			}
+		}
+		return null;
+	}
+
+	public SimulatedCarInfo getCarIdx(int idx) 
+	{
+		synchronized (cars) 
+		{
+			Iterator<SimulatedCarInfo> it = cars.iterator();
+			while (it.hasNext()) {
+				SimulatedCarInfo r = it.next();
+				if (r.vehicleId == idx)
+					return r;
+			}
+		}
+		return null;
+	}
+
+	public static void main(String args[]) {
+		
+		// Globals.map = new Map("Intersectie.RT1","Intersectie.RT2");
+
+		int tests = 1;
+		for (int i = 0; i < tests; i++){
+			try{
+				switch (i){
+					case 0:	Globals.pw.println("Adaptive xc  = 1, variations2");
+						break;
+					case 1:Globals.pw.println("Adaptive xc  = 0.95, variations2");
+						break;
+					case 2:break;
+				}
+				
+//				ObjectInputStream ois=new ObjectInputStream(new FileInputStream(".\\maps\\fsc\\Apaca.fsc"));
+//				Scenario sc=(Scenario)ois.readObject();
+//				Mobility.loadScenario(sc);
+			
+				Engine e = Globals.engine = new Engine(false, true);
+				e.init();
+//						public void run(){
+//							Globals.demo = new Display();
+//							Globals.demo.setVisible(true);
+//						}
+//					});
+//				t.start();
+//				e.play();
+				switch (i){
+					case 0:
+						Globals.Xc = 0.95;
+						break;
+					case 1:break;
+					case 2:break;
+				}
+				
+				if (i != tests - 1){
+					Globals.pw.close();
+					String pwname = "rezultate"+System.currentTimeMillis()+".txt";
+					Globals.pw = new PrintWriter(new FileWriter(pwname));
+				}
+			} catch (Exception ex) {
+				ex.printStackTrace();
+				System.exit(0);
+			}		
+		
+			
+		}
+		
+/*		long t1 = System.currentTimeMillis();
+		e.play(60);
+		long t2 = System.currentTimeMillis();
+
+		System.out.println("SimTime: " + (t2 - t1));
+		System.out.println("events: " + (double) (100 * e.eventsTime)
+				/ (t2 - t1));
+		System.out.println("mobility: " + (double) (100 * e.mobilityTime)
+				/ (t2 - t1));
+		System.out.println("move: " + (double) (100 * e.moveTime) / (t2 - t1));
+		System.out.println("code: " + (double) (100 * e.codeTime) / (t2 - t1));
+		System.out.println("net: " + (double) (100 * e.netTime) / (t2 - t1));
+		System.out.println("cleanup: " + (double) (100 * e.cleanupTime)
+				/ (t2 - t1));
+		System.out
+				.println("sched: " + (double) (100 * e.schedTime) / (t2 - t1));
+
+//		System.out.println("pkavg " + pkavg + "\npkmax" + pkmax
+//				+ "\ncomp time " + avgTime);
+		//		e.play();
+		//		e.step();
+		//		e.step();
+		//		e.step();
+		//		e.step();
+		//		e.step();
+		System.exit(0);*/
+	}
+
+	
+/*	public void createDummyCars() {
+		Road r = Globals.map.roads.get(1);
+		
+		//Stopping a car on a road
+		int ID = lastCarID;
+		lastCarID++;
+		CarInstance car = Mobility.createNewCar(1, 46, 0, 1, 0.0,
+				new NotMovingPersonality(), 0.0, ID, 2, 64, null, 1);
+		if (car == null) {
+			lastCarID--;
+			System.out.println("Could not create the first stopped car");
+		} else {
+			System.out.println("Jammed car id=" + ID);
+			jammed = ID;
+		}
+
+		this.addCar(car);
+	}
+*/
+	
+
+}
