package sudoku.structure;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

/**
 * Une pile, qui réprésente les états d'un MultiDoku,
 * utile pour les Solvers.
 */
public class StateManager {

	/**
	 * Le MultiDoku auquel il est associé.
	 */
	private final MultiDoku doku;

	/**
	 * La pile des états du MultiDoku associé.
	 */
	private final Stack<Map<Cell, Integer>> states;

	public StateManager(MultiDoku doku) {
		this.states = new Stack<>();
		this.doku = doku;
	}

	public Map<Cell, Integer> pushState() {
		states.add(saveState());
		return states.getLast();
	}

	public void popState() {
		assert (!states.isEmpty());
		restoreState(states.pop());
	}

	public Map<Cell, Integer> popAndGetState() {
		assert (!states.isEmpty());
		var currentState = saveState();
		restoreState(states.pop());
		return currentState;
	}

	private void restoreState(Map<Cell, Integer> state) {
		for (var entry : state.entrySet()) {
			entry.getKey().setSymbolIndex(entry.getValue());
		}
	}

	private Map<Cell, Integer> saveState() {
		Map<Cell, Integer> state = new HashMap<>();
		for (Cell cell : this.doku.getCells()) {
			state.put(cell, cell.getSymbolIndex());
		}
		return state;
	}

}
