import * as CellSet from Geometry.CellSet;
import getCellSets from Solver.State;
import * as Strategy from Solver.Strategy;
import {diagonal, getColumn, getRow, plus} from Geometry.Vector;

return {
	find: find
};

function find(solvingState) {
	var cellSets = getCellSets(solvingState);
	return Strategy.map(
		stepOfCell(solvingState.missing),
		Strategy.tryEach(cellSets.map(getSingleCellIn))
	);
}

function getSingleCellIn(cellSet) {
	return function() {
		if(cellSet.size() == 1) {
			return cellSet.toList()[0];
		}
	};
}

function stepOfCell(missing) {
	return function(cell) {
		return {
			reason: 'singleCell',
			empty: toEmpty(cell).intersection(missing),
			star: new CellSet.CellSet(cell)
		};
	};
}

function toEmpty(cell) {
	var union = CellSet.union([
		CellSet.rectangle(plus(cell, diagonal(-1)), diagonal(3)),
		CellSet.row(getRow(cell)),
		CellSet.column(getColumn(cell))
	]);
	union.remove(cell);
	return union;
}