class WhereIsIt implements GameLifeCycle {

    RoundDetails pickAndBuildRandomPictures(final int numberOfImagesToDisplayPerRound, final ReplayablePseudoRandom random,
                                            final int winnerImageIndexAmongDisplayedImages) {

        final Configuration config = gameContext.getConfiguration();

        int filesCount;
        final String directoryName;
        List<File> imagesFolders = new LinkedList<>();
        List<String> resourcesFolders = new LinkedList<>();

        if (this.gameType == CUSTOMIZED) {
            final File imagesDirectory = new File(config.getWhereIsItDir() + "/images/");
            directoryName = imagesDirectory.getPath();
            filesCount = 0;
            File[] listOfTheFiles = imagesDirectory.listFiles();
            if(listOfTheFiles!=null) {
                for (File f : listOfTheFiles) {
                    File[] filesInf = f.listFiles();
                    if(filesInf != null) {
                        if (f.isDirectory() && filesInf.length > 0){
                            boolean containsImage = false;
                            int i = 0;
                            while( !containsImage && i < filesInf.length) {
                                File file = filesInf[i];
                                containsImage = fileIsImageFile(file);
                                i++;
                            }
                            if(containsImage) {
                                imagesFolders.add(f);
                                filesCount++;
                            }
                        }
                    }
                }
            }
        } else {
            final String resourcesDirectory = "data/" + this.gameType.getResourcesDirectoryName();
            final String imagesDirectory = resourcesDirectory + "/images/";
            directoryName = imagesDirectory;

            // Here we filter out any unwanted resource folders, based on the difficulty JSON file
            Set<String> difficultySet;
            try {
                SourceSet sourceSet = new SourceSet(resourcesDirectory + "/difficulties.json");
                difficultySet = (sourceSet.getResources(this.gameType.getDifficulty()));
            } catch (FileNotFoundException fe) {
                log.info("No difficulty file found; Reading from all directories");
                difficultySet = Collections.emptySet();
            }

            Set<String> tempResourcesFolders = ResourceFileManager.getResourceFolders(imagesDirectory);

            // If nothing can be found we take the entire folder contents.
            if (!difficultySet.isEmpty()) {
                Set<String> finalDifficultySet = difficultySet;
                tempResourcesFolders = tempResourcesFolders
                    .parallelStream()
                    .filter(s ->
                        finalDifficultySet.parallelStream().anyMatch(s::contains)
                    )
                    .collect(Collectors.toSet());
            }

            resourcesFolders.addAll(tempResourcesFolders);

            filesCount = resourcesFolders.size();
        }

        final String language = config.getLanguage();

        if (filesCount == 0) {
            log.warn("No images found in Directory " + directoryName);
            error(language);
            return null;
        }

        int posX = 0;
        int posY = 0;

        final GameSizing gameSizing = new GameSizingComputer(nbLines, nbColumns, fourThree)
            .computeGameSizing(gameContext.getGamePanelDimensionProvider().getDimension2D());

        final List<PictureCard> pictureCardList = new ArrayList<>();
        String questionSoundPath = null;
        String question = null;
        List<Image> pictograms = null;
        if (this.gameType == FIND_ODD) {

            int index = random.nextInt(resourcesFolders.size());
            final String folder = resourcesFolders.remove((index) % filesCount);

            index = random.nextInt(resourcesFolders.size());
            final String winnerFolder = resourcesFolders.remove((index) % filesCount);
            final String folderName = (new File(winnerFolder)).getName();

            for (int i = 0; i < numberOfImagesToDisplayPerRound; i++) {
                final Set<String> files;
                if (i == winnerImageIndexAmongDisplayedImages) {
                    files = ResourceFileManager.getResourcePaths(winnerFolder);
                } else {
                    files = ResourceFileManager.getResourcePaths(folder);
                }

                final int numFile = random.nextInt(files.size());

                final String randomImageFile = (String) files.toArray()[numFile];

                if (winnerImageIndexAmongDisplayedImages == i) {

                    // TODO for now the line under is commented to avoid freeze
                    //questionSoundPath = getPathSound(imagesFolders[(index) % filesCount].getName(), language);

                    question = MultilinguismFactory.getSingleton().getTranslation("findodd", config.getLanguage());

                    pictograms = getPictogramms(folderName);

                }

                final PictureCard pictureCard = new PictureCard(gameSizing.width * posX + gameSizing.shift,
                    gameSizing.height * posY, gameSizing.width, gameSizing.height, gameContext, winnerImageIndexAmongDisplayedImages == i,
                    randomImageFile + "", stats, this);

                final TargetAOI targetAOI = new TargetAOI(gameSizing.width * (posX + 0.25), gameSizing.height * (posY+1), (int)gameSizing.height,
                    System.currentTimeMillis());
                targetAOIList.add(targetAOI);

                pictureCardList.add(pictureCard);

                if ((i + 1) % nbColumns != 0) {
                    posX++;
                } else {
                    posY++;
                    posX = 0;
                }
            }

        } else if (this.gameType == CUSTOMIZED) {

            for (int i = 0; i < numberOfImagesToDisplayPerRound; i++) {

                int index = random.nextInt(imagesFolders.size());

                final File folder = imagesFolders.remove((index) % filesCount);

                final File[] files = getFiles(folder);

                List<File> validImageFiles = new ArrayList<>();

                for ( File file: files){
                    if(fileIsImageFile(file)){
                        validImageFiles.add(file);
                    }
                }

                final int numFile = random.nextInt(validImageFiles.size());

                final File randomImageFile = validImageFiles.get(numFile);

                if (winnerImageIndexAmongDisplayedImages == i) {

                    questionSoundPath = getPathSound(folder.getName(), language);

                    question = getQuestionText(folder.getName(), language);

                    pictograms = getPictogramms(folder.getName());

                }

                // The image file needs 'file:' prepended as this will get images from a local source, not resources.
                final PictureCard pictureCard = new PictureCard(gameSizing.width * posX + gameSizing.shift,
                    gameSizing.height * posY, gameSizing.width, gameSizing.height, gameContext,
                    winnerImageIndexAmongDisplayedImages == i, "file:" + randomImageFile, stats, this);

                final TargetAOI targetAOI = new TargetAOI(gameSizing.width * (posX + 0.25), gameSizing.height * (posY+1), (int)gameSizing.height,
                    System.currentTimeMillis());
                targetAOIList.add(targetAOI);

                pictureCardList.add(pictureCard);


                if ((i + 1) % nbColumns != 0) {
                    posX++;
                } else {
                    posY++;
                    posX = 0;
                }
            }
        } else {
            for (int i = 0; i < numberOfImagesToDisplayPerRound; i++) {
                int index = random.nextInt(resourcesFolders.size());

                final String folder = resourcesFolders.remove((index) % filesCount);
                final String folderName = (new File(folder)).getName();

                final Set<String> files = ResourceFileManager.getResourcePaths(folder);

                final int numFile = random.nextInt(files.size());

                final String randomImageFile = (String) files.toArray()[numFile];

                if (winnerImageIndexAmongDisplayedImages == i) {

                    questionSoundPath = getPathSound(folderName, language);

                    question = getQuestionText(folderName, language);

                    pictograms = getPictogramms(folderName);

                }

                final PictureCard pictureCard = new PictureCard(gameSizing.width * posX + gameSizing.shift,
                    gameSizing.height * posY, gameSizing.width, gameSizing.height, gameContext,
                    winnerImageIndexAmongDisplayedImages == i, randomImageFile + "", stats, this);

                pictureCardList.add(pictureCard);

                final TargetAOI targetAOI = new TargetAOI(gameSizing.width * (posX + 0.25), gameSizing.height * (posY+1), (int)gameSizing.height,
                    System.currentTimeMillis());
                targetAOIList.add(targetAOI);


                if ((i + 1) % nbColumns != 0) {
                    posX++;
                } else {
                    posY++;
                    posX = 0;
                }
            }
        }
        return new RoundDetails(pictureCardList, winnerImageIndexAmongDisplayedImages, questionSoundPath, question,
            pictograms);
    }

    public  WhereIsIt(final WhereIsItGameType gameType, final int nbLines, final int nbColumns, final boolean fourThree,
                     final IGameContext gameContext, final Stats stats);

}