package traffic;

/*
 * Road.java
 *
 * Created on 27 de marzo de 2009, 18:47
 *
 */


import java.util.*;


public class Road {
    // length in Km
    float length;
    // Normal speed in the road
    float speed;
    // Maximum flow in vehicles per second
    float maxFlow;
    
    
    /** Creates a new instance of Road */
    public Road(float l, float v, float flow) {
        length = l;
        speed = v;
        maxFlow = flow;
    }
    
    public List<SimulationElement> simulate(List<SimulationElement> simElementList) {
        Queue<SimulationElement> queue;
        float vel, len;
        queue = new PriorityQueue<SimulationElement>();
        for(SimulationElement simElem: simElementList) {
            SimulationElement simElem2 = new SimulationElement();
            simElem2.setVehicle(simElem.getVehicle());
            
            // Calculo del tiempo de llegada al final de la carretera en segundos.
            // Nos quedamos con la menor velocidad de carretera y vehiculo.
            if(simElem.getVehicle().getVehicleMaxVel() < speed)
                vel = simElem.getVehicle().getVehicleMaxVel();
            else
                vel = speed;
            // Si el Km de entrada es mayor que el tamaño de la carretera, nos quedamos con el tamaño de carretera
			if(simElem.getEnterRoadKm() > length) {
                len = length;
				System.err.println(" Km de entrada a carretera erroneo !!");
			}
            else
                len = simElem.getEnterRoadKm();
			simElem2.setExitTime(simElem.getExitTime());
			simElem2.setEnterRoadTime(simElem.getEnterRoadTime());
			simElem2.setAtWork(simElem.getAtWork());
			simElem2.setEstimatedConsumption(simElem.getEstimatedConsumption());
			simElem2.setConsumption(simElem.getConsumption());
            simElem2.setCalculatedTime(simElem.getEnterRoadTime() + (len / vel * 3600));
            // Consumo en la carretera
			
            simElem2.setConsumption(simElem2.getConsumption() + simElem2.getVehicle().getConsumption() * len / 100);
			try{
				queue.add(simElem2);
			}catch(Exception e){
				System.err.println("ERROR: "+e);
			}
        }
        List<SimulationElement> vCarRes = new ArrayList<SimulationElement>();
        
        SimulationElement simElem = queue.remove();
        float time = simElem.getCalculatedTime();
        vCarRes.add(simElem);
        while(!queue.isEmpty() ) {
            
            simElem = queue.remove();
            time = time + 1 / maxFlow;
            if(simElem.getCalculatedTime() >= time)
                time = simElem.getCalculatedTime();
            else
            {
                // Añadimos el consumo en la cola
                simElem.setConsumption(simElem.getConsumption() + (time - simElem.getCalculatedTime())*simElem.getVehicle().getConsumptionStop() / 3600);
                simElem.setCalculatedTime(time);
            }
            vCarRes.add(simElem);
            
        }
        return vCarRes;
    }
    
}
