import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import processing.core.PApplet;

public class Cars {
	private static final int NROUTES = 200;
	PApplet p;
	List<Car> cars;
	List<RoadEdge> roads;
	SloRoads network;
	List <List<RoadEdge>> routes;
	
	
	Cars (PApplet parent, SloRoads network) {
		p = parent;
		routes = new ArrayList <List<RoadEdge>> ();
		cars = new ArrayList<Car> ();
		this.network = network;
		roads = network.getRoads();
		createAllRoutes();
		p.println ("routes ok");
		initCars();
		p.println ("cars ok");
		p.println ("routes: " + routes.size());
	}
	
        public List<Car> getAllCars () {
          return cars;
        }

	public void initCars () {
		  cars.clear();
		  Random r = new Random();
		  for (int i = 0; i < 1000; i++) {
			Car car = makeNewCar();
		    cars.add(car);
		  }
		}
	
	public Car makeNewCar () {
		Random r = new Random();
	    //RoadEdge road = roads.get(r.nextInt(network.getRoads().size()-1)); //Roads.N - 1
	    Car car = new Car(p);
//	    List<RoadEdge> route = fixRoute();
//	    while (route == null || route.size() < 2) {
//	    	route = fixRoute();
//	    }
	    List<RoadEdge> route = routes.get(r.nextInt(NROUTES-1));
	    car.setRoute(route);
	    return car;
	}
	
	public List<RoadEdge> fixRoute() {
		Random r = new Random();
	    int b = r.nextInt(network.getBeginnings().size());
	    int e = r.nextInt(network.getEndings().size());
	    String begin = network.getBeginnings().get(b).getId();
	    String end = network.getEndings().get(e).getId();
	    List<RoadEdge> route = network.getRoute(begin, end);
		return route;
		
	}
	
	public void onRoute () {
		Random r = new Random();
		for (int i = cars.size() - 1; i > 0; i--) {
			Car car = (Car) cars.get(i);
			car.draw();
			if (car.update()) {
				cars.remove(car);
				Car newCar = makeNewCar();
				cars.add(newCar);
			}
			if (r.nextFloat() > 0.8f) {
				if (cars.get(i).getVelocity() < cars.get(i).getMaxVelocity()) {
					cars.get(i).incVelocity();
				}
			}
			if (r.nextFloat() > 0.8f) {
				if (cars.get(i).getVelocity() > 0.5f) {
					cars.get(i).decVelocity();
				}
			}
			if (car.isAtEndOfRoute()){
				cars.remove(car);
				Car newCar = makeNewCar();
				cars.add(newCar);
			}
			
			for (int j = cars.size()-1; j > 0; j--) { //cars.size() - 1
				//println ("Size: " + cars.size() + " i:" + i + " j: " + j);
				if (!cars.get(i).equals(cars.get(j))) {
					if (cars.get(i).getRoad().equals(cars.get(j).getRoad())) {
						if (cars.get(i).getPathIdx() > cars.get(j).getPathIdx()) {
							if (cars.get(i).getPathIdx() - cars.get(j).getPathIdx() < 20) {
								if (cars.get(j).getVelocity() > 0) {
									cars.get(j).setVelocity(cars.get(i).getVelocity()); 
									if (cars.get(i).getPathIdx() - cars.get(j).getPathIdx() < 10) {
										cars.get(j).decVelocity();
									}
								}
							} else if (cars.get(j).getVelocity() < cars.get(j).getMaxVelocity()) {
								cars.get(j).incVelocity();
							}
						}
					}
				}
			}
		}

	}
	
	private void createAllRoutes () {
		for (int i = 0; i < NROUTES; i++) {
			List cRoute = fixRoute();
		    while (cRoute == null || cRoute.size() < 2) {
		    	cRoute = fixRoute();
		    }
			routes.add(cRoute);
		}
	}
	
//	public void update() {
//		Random r = new Random();
//		for (int i = cars.size() - 1; i > 0; i--) {
//			Car car = (Car) cars.get(i);
//			car.draw();
//			//car.getRoad().drawDebug();
//			car.update();
//			
//			if (r.nextFloat() > 0.8f) {
//				if (cars.get(i).getVelocity() < cars.get(i).getMaxVelocity()) {
//					cars.get(i).incVelocity();
//				}
//			}
//			if (r.nextFloat() > 0.8f) {
//				if (cars.get(i).getVelocity() > 0.5f) {
//					cars.get(i).decVelocity();
//				}
//			}
//			if (car.isAtEnd()) {
//				RoadEdge current = car.getRoad();
//				RoadEdge nr = (RoadEdge) network.getNewRoad(car.getRoad());
//				//println ("car ID: " + car.getID() + " old road xy: " + current.getTo().getX() + " " + current.getTo().getY() + " road ID: " + current.getID());
//				//println ("car ID: " + car.getID() + " new road xy: " + nr.getTo().getX() + " " + nr.getTo().getY() + " road ID: " + nr.getID());
//				
//
//				if (nr != null) {
//					car.setRoad(nr);
//					//println ("ID new road: " + car.getID() + " xy: " + nr.getTo().getX() + " " + nr.getTo().getY());
//				} else {
//					cars.remove(car);
//					RoadEdge test = roads.get(r.nextInt(network.getRoads().size()-1)); //Roads.N - 1
//					Car car1 = new Car(p);
//					car1.setRoad(test);
//					//car.setPathIdx(r.nextInt(test.getPathPositions().size()));
//					cars.add(car1);
//					break;
//				}
//			}
//			for (int j = cars.size()-1; j > 0; j--) { //cars.size() - 1
//				//println ("Size: " + cars.size() + " i:" + i + " j: " + j);
//				if (!cars.get(i).equals(cars.get(j))) {
//					if (cars.get(i).getRoad().equals(cars.get(j).getRoad())) {
//						if (cars.get(i).getPathIdx() > cars.get(j).getPathIdx()) {
//							if (cars.get(i).getPathIdx() - cars.get(j).getPathIdx() < 20) {
//								if (cars.get(j).getVelocity() > 0) {
//									cars.get(j).setVelocity(cars.get(i).getVelocity()); 
//									if (cars.get(i).getPathIdx() - cars.get(j).getPathIdx() < 10) {
//										cars.get(j).decVelocity();
//									}
//								}
//							} else if (cars.get(j).getVelocity() < cars.get(j).getMaxVelocity()) {
//								cars.get(j).incVelocity();
//							}
//						}
//					}
//				}
//			}
//
//		}
//	}
}

