package rinde.logistics.pdptw.mas;

import rinde.logistics.pdptw.mas.comm.Communicator;
import rinde.logistics.pdptw.mas.route.RoutePlanner;
import rinde.sim.core.Simulator;
import rinde.sim.core.model.Model;
import rinde.sim.pdptw.common.AddVehicleEvent;
import rinde.sim.pdptw.common.DynamicPDPTWProblem.Creator;
import rinde.sim.pdptw.common.VehicleDTO;
import rinde.sim.pdptw.experiment.DefaultMASConfiguration;
import rinde.sim.util.SupplierRng;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;

/**
 * A {@link rinde.sim.pdptw.experiment.MASConfiguration} that configures a
 * simulation to use a {@link Truck} instance as vehicle.
 * @author Rinde van Lon <rinde.vanlon@cs.kuleuven.be>
 */
public class TruckConfiguration extends DefaultMASConfiguration {
  /**
   * Supplier for {@link RoutePlanner} instances.
   */
  protected final SupplierRng<? extends RoutePlanner> rpSupplier;

  /**
   * Supplier for {@link Communicator} instances.
   */
  protected final SupplierRng<? extends Communicator> cSupplier;

  /**
   * Suppliers for {@link Model}s.
   */
  protected final ImmutableList<? extends SupplierRng<? extends Model<?>>> mSuppliers;

  /**
   * Instantiate a new configuration.
   * @param routePlannerSupplier {@link #rpSupplier}.
   * @param communicatorSupplier {@link #cSupplier}.
   * @param modelSuppliers {@link #mSuppliers}.
   */
  public TruckConfiguration(
      SupplierRng<? extends RoutePlanner> routePlannerSupplier,
      SupplierRng<? extends Communicator> communicatorSupplier,
      ImmutableList<? extends SupplierRng<? extends Model<?>>> modelSuppliers) {
    rpSupplier = routePlannerSupplier;
    cSupplier = communicatorSupplier;
    mSuppliers = modelSuppliers;
  }

  @Override
  public Creator<AddVehicleEvent> getVehicleCreator() {
    return new Creator<AddVehicleEvent>() {
      @Override
      public boolean create(Simulator sim, AddVehicleEvent event) {
        final RoutePlanner rp = rpSupplier.get(sim.getRandomGenerator()
            .nextLong());
        final Communicator c = cSupplier.get(sim.getRandomGenerator()
            .nextLong());
        return sim.register(createTruck(event.vehicleDTO, rp, c));
      }
    };
  }

  /**
   * Factory method that can be overridden by subclasses that want to use their
   * own {@link Truck} implementation.
   * @param dto
   * @param rp
   * @param c
   * @return
   */
  protected Truck createTruck(VehicleDTO dto, RoutePlanner rp, Communicator c) {
    return new Truck(dto, rp, c);
  }

  @Override
  public ImmutableList<? extends SupplierRng<? extends Model<?>>> getModels() {
    return mSuppliers;
  }

  @Override
  public String toString() {
    return rpSupplier + "-" + cSupplier + "-" + Joiner.on("-").join(mSuppliers);
  }
}

@@ -2365,50 +2365,226 @@
  dto
-%0A   * @param rp%0A   * @param c%0A   * @return
+ The %7B@link VehicleDTO%7D containing the vehicle information.%0A   * @param rp The %7B@link RoutePlanner%7D to use in the truck.%0A   * @param c The %7B@link Communicator%7D to use in the truck.%0A   * @return The newly created truck.
 %0A   

update doc