package pl.edu.pw.mini.jk.sg.game.graph.advanceable;

import java.util.stream.IntStream;

import com.google.common.cache.Cache;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;

import pl.edu.pw.mini.jk.sg.game.graph.moves.single.DesiredConfigurationMove;

public class AdvanceableDefenderGraphState extends AdvanceableSideGraphState
		implements pl.edu.pw.mini.jk.sg.game.common.advanceable.AdvanceableDefenderState<DesiredConfigurationMove> {
	private static final long serialVersionUID = 1L;

	public AdvanceableDefenderGraphState(ImmutableList<Integer> unitPositions,
			ImmutableList<ImmutableSet<Integer>> possibleDestinationFromVertex, int timeStep) {
	    super(timeStep, unitPositions, possibleDestinationFromVertex);
	}

	public AdvanceableDefenderGraphState(ImmutableList<Integer> unitPositions,
			ImmutableList<ImmutableSet<Integer>> possibleDestinationFromVertex, int timeStep,
			Cache<Object, ImmutableList<DesiredConfigurationMove>> moveCache) {
	    super(timeStep, unitPositions, possibleDestinationFromVertex, moveCache);
	}

	@Override
	public AdvanceableDefenderGraphState advance(DesiredConfigurationMove move) {
		if (!checkLegalMove(move)) {
			throw new IllegalArgumentException("Move not possible");
		} else {
			return new AdvanceableDefenderGraphState(
					ImmutableList.copyOf( IntStream.range(0, move.unitCount()).mapToObj(i -> move.getTargetFor(i))
							.iterator()),
					getPossibleDestinationFromVertex(), getTimeStep() + 1);
		}
	}

	@Override
	public ImmutableList<DesiredConfigurationMove> getPossibleMoves() {
		return super.getPossibleMoves();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		AdvanceableDefenderGraphState other = (AdvanceableDefenderGraphState) obj;
		return true;
	}

	@Override
	public String toString() {
		return "DS " + getTimeStep() + ": " + getUnitPositions().toString();
	}

}
