package gui.constants;

import java.util.List;

import sudoku.constraint.IConstraint;
import sudoku.structure.MultiDoku;
import sudoku.structure.SudokuFactory;;

public enum SudokuType {

	Square("Carré", 1,
			(constraints, params) -> SudokuFactory.createBasicEmptySquareDoku(params[0], constraints)),
	Rectangle("Rectangle", 2,
			(constraints, params) -> SudokuFactory.createBasicEmptyRectangleDoku(params[0], params[1], constraints)),
	RandomBloc("Blocs aléatoires", 1,
			(constraints, params) -> SudokuFactory.createBasicEmptyRandomBlockDoku(params[0], constraints)),
	MultiDokuXSquare("Multidoku carré (X)", 1,
			(constraints, params) -> SudokuFactory.createBasicXShapedMultidoku(params[0], constraints)),
	MultidokuXRectangle("Multidoku rectangle (X)", 2,
			(constraints, params) -> SudokuFactory.createBasicXShapedMultidoku(params[0], params[1], constraints)),
	MultiDokuPSquare("Multidoku carré (+)", 1,
			(constraints, params) -> SudokuFactory.createBasicPlusShapedMultidoku(params[0], constraints)),
	MultiDokuPRectangle("Multidoku rectangle (+)", 2,
			(constraints, params) -> SudokuFactory.createBasicPlusShapedMultidoku(params[0], params[1], constraints));

	String displayName;
	SudokuMaker maker;
	int paramCount;

	private SudokuType(String displayName, int paramCount, SudokuMaker maker) {
		this.displayName = displayName;
		this.maker = maker;
		this.paramCount = paramCount;
	}

	public String getDisplayName() {
		return this.displayName;
	}

	public MultiDoku createDoku(List<IConstraint> constraints, int... params) {
		return maker.makeSudoku(constraints, params);
	}

	public int getMakerParamCount() {
		return this.paramCount;
	}

	@FunctionalInterface
	private static interface SudokuMaker {
		MultiDoku makeSudoku(List<IConstraint> constraints, int... params);
	}

	private static final String[] dokuNames;

	static {
		SudokuType[] types = SudokuType.values();
		dokuNames = new String[types.length];
		for (int i = 0; i < types.length; i++) {
			dokuNames[i] = types[i].getDisplayName();
		}
	}

	public static String[] getTypeNames() {
		return dokuNames;
	}

}
