package com.comp301.a05driver;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class ExpandingProximityIterator implements Iterator<Driver> {
private final Iterable<Driver> driverPool;
private final Position clientPosition;
private final int expansionStep;
private Driver nextDriver;
private int size;
private int tracker;
private Iterator<Driver> driverPoolCollection;
private int i;
public ExpandingProximityIterator(
Iterable<Driver> driverPool, Position clientPosition, int expansionStep)
throws IllegalArgumentException {
if (driverPool == null) {
throw new IllegalArgumentException("Driver pool is null");
}
if (clientPosition == null) {
throw new IllegalArgumentException("Client position is null");
}
this.driverPool = driverPool;
this.clientPosition = clientPosition;
this.expansionStep = expansionStep;
nextDriver = null;
tracker = 0;
for (Driver driver : driverPool) {
size += 1;
}
driverPoolCollection = driverPool.iterator();
i = -1;
}
private void loadNextDriverR() {
if (nextDriver == null) {
while (driverPoolCollection.hasNext()) {
Driver currentDriver = driverPoolCollection.next();
if (clientPosition.getManhattanDistanceTo(currentDriver.getVehicle().getPosition())
> 1 + i * expansionStep
&& clientPosition.getManhattanDistanceTo(currentDriver.getVehicle().getPosition())
<= 1 + (i + 1) * expansionStep) {
nextDriver = currentDriver;
tracker++;
return;
}
}
if (tracker != size) {
i++;
driverPoolCollection = driverPool.iterator();
loadNextDriverR();
}
}
}
private void loadNextDriver() {
if (nextDriver == null) {
while (driverPoolCollection.hasNext()) {
Driver currentDriver = driverPoolCollection.next();
if (clientPosition.getManhattanDistanceTo(currentDriver.getVehicle().getPosition())
> 1 + i * expansionStep
&& clientPosition.getManhattanDistanceTo(currentDriver.getVehicle().getPosition())
<= 1 + (i + 1) * expansionStep) {
nextDriver = currentDriver;
tracker++;
return;
}
}
while (tracker != size) {
i++;
driverPoolCollection = driverPool.iterator();
if (nextDriver == null) {
while (driverPoolCollection.hasNext()) {
Driver currentDriver = driverPoolCollection.next();
if (clientPosition.getManhattanDistanceTo(currentDriver.getVehicle().getPosition())
> 1 + i * expansionStep
&& clientPosition.getManhattanDistanceTo(currentDriver.getVehicle().getPosition())
<= 1 + (i + 1) * expansionStep) {
nextDriver = currentDriver;
tracker++;
return;
}
}
}
}
}
}
@Override
public boolean hasNext() {
if (tracker == size) {
return false;
}
loadNextDriver();
return true;
}
@Override
public Driver next() {
if (hasNext()) {
Driver driver = nextDriver;
nextDriver = null;
return driver;
} else {
return nextDriver;
}
}
}