#pragma once

#include "Polyomino.h"

#include <vector>
#include <set>
#include <map>


/**
 * A generator of one-sided polyominoes of any size
 */
class Generator {
    private:
        std::vector<Polyomino> validPolyominoes; // the list of already generated polyominoes
        std::set<Position> currentTestedShape;  // the polyomino being created

    public:
        /**
         * Default constructor
         */
        Generator();
        
        /**
         * Generates the list of all one-sided polyominoes of the specified size
         * @return The list of polyominoes
         */
        std::vector<Polyomino>&& generatePolyominoes(int polyominoSize);

    private:
        /**
         * Generates all one-sided polyominoes of the specified size using the current tested shape
         */
        void generate(unsigned polyominoSize, int lastAddedPositionNumber, int nextAvaibleNumber, std::map<Position, int> candidatePositions);

        /**
         * Checks wheter a candidate position can be added to the current tested shape
         */
        void tryToAddCandidatePosition(const Position& candidate, int& nextAvaibleNumber, std::map<Position, int>& candidatePositions);
};
