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; }