package tc.oc.pgm.rotation;
import java.util.List;
import javax.annotation.Nonnull;
import tc.oc.pgm.map.PGMMap;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
/**
* Represents a map rotation. Instances are completely immutable.
*/
public final class RotationState {
/**
* Creates a new RotationState instance.
*
* @param maps PGM maps in the rotation (order matters)
* @param nextId Id of the next map in the rotation
*
* @throws NullPointerException if maps is null
* @throws IllegalArgumentException if maps is empty or nextId is invalid
*/
public RotationState(@Nonnull List<PGMMap> maps, int nextId) {
Preconditions.checkNotNull(maps, "maps");
Preconditions.checkArgument(!maps.isEmpty(), "must have at least one map");
Preconditions.checkArgument(isNextIdValid(maps, nextId), "next id is invalid");
this.maps = ImmutableList.copyOf(maps);
this.nextId = nextId;
}
/**
* Gets the list of maps in order that the rotation has.
* @return Immutable ordered list of maps (guaranteed to be 1 or more)
*/
public @Nonnull List<PGMMap> getMaps() {
return this.maps;
}
/**
* Gets the next map in the rotation as specified by the next id.
* @return Next map in rotation
*/
public @Nonnull PGMMap getNext() {
return this.maps.get(this.nextId);
}
/**
* Gets the index of the next map.
* @return Index of next map
*/
public int getNextId() {
return this.nextId;
}
/**
* Skip n maps in the rotation
* @param n Number of maps to skip
* @return New rotation state instance with the modifications
*/
public @Nonnull RotationState skip(int n) {
int newNextId = (this.nextId + n) % this.maps.size();
return new RotationState(this.maps, newNextId);
}
/**
* Skip to the nth map in the rotation.
* @param n Index of the next map
* @return New rotation state instance with the modifications
*
* @throws IllegalArgumentException if n is invalid
*/
public @Nonnull RotationState skipTo(int n) {
Preconditions.checkArgument(isNextIdValid(this.maps, n), "n is invalid");
return new RotationState(this.maps, n);
}
/**
* Checks whether the given next id is valid for the list of maps.
* @param maps List of rotation maps
* @param newRotationId Next id to check
* @return true if the next id is a valid index, false otherwise
*/
public static boolean isNextIdValid(List<PGMMap> maps, int newRotationId) {
return 0 <= newRotationId && newRotationId < maps.size();
}
protected final List<PGMMap> maps;
protected final int nextId;
}