package com.cherokeelessons.cll2ev1;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.JsonWriter.OutputType;
import com.badlogic.gdx.utils.Logger;
import com.cherokeelessons.cll2ev1.models.CardData;
import com.cherokeelessons.cll2ev1.models.GameCard;
import com.cherokeelessons.cll2ev1.screens.LearningSession;
import com.cherokeelessons.deck.CardStats;
import com.cherokeelessons.deck.Deck;
import com.cherokeelessons.deck.ICard;
import com.cherokeelessons.util.SlotFolder;

public class StartSession implements Runnable {

	private final Logger log = new Logger(this.getClass().getSimpleName());

	private static final String ACTIVE_CARDS = CLL2EV1.ACTIVE_CARDS;
	private final AbstractGame game;
	private final int session;
	private final Json json = new Json();

	public StartSession(AbstractGame game, int session) {
		this.game = game;
		this.session = session;
		log.setLevel(Logger.INFO);
	}

	@Override
	public void run() {
		log.info("StartSession#run");
		FileHandle activeCardsJson = SlotFolder.getSlotFolder(session).child(ACTIVE_CARDS);
		String tmp;
		try {
			tmp = activeCardsJson.readString(StandardCharsets.UTF_8.name());
		} catch (Exception e) {
			tmp = "";
		}
		log.info("StartSession#file loaded");
		String[] jsonCardsStats = tmp.split("\n");
		/*
		 * Always create a fresh deck by copying (cloning) cards from the CSV
		 * master deck. If we have stats that don't match a card in the fresh
		 * deck they will be ignored and lost at next save. The match up is done
		 * by "card id" which is the minimal amount of uniqueness to match up as
		 * generated by the CardData object. Being sure to set all stats to
		 * "never shown/correct".
		 */
		Deck<CardData> masterDeck = new Deck<CardData>();
		for (GameCard card : ((CLL2EV1) game).cards) {
			ICard<CardData> copy = card.copy();
			copy.resetStats();
			copy.resetTriesRemaining(CardData.MAX_TRIES);
			copy.getCardStats().setPimsleurSlot(0);
			masterDeck.add(copy);
		}
		log.info("StartSession#master deck created");
		if (Gdx.app.getType().equals(ApplicationType.Desktop)) {
			masterDeck.shuffleThenSortIntoPrefixedGroups(CardData.SORT_KEY_LENGTH);
			SlotFolder.getDeckSlot().mkdirs();
			List<String[]> sortedCardIds = new ArrayList<String[]>();
			for (ICard<CardData> card : masterDeck.getCards()) {
				sortedCardIds.add(new String[] { card.id(), card.sortKey() });
			}
			Json jsonx = new Json(OutputType.json);
			jsonx.setTypeName(null);
			jsonx.setUsePrototypes(false);
			SlotFolder.getDeckSlot().child("master-deck-card-ids.json").writeString(jsonx.prettyPrint(sortedCardIds),
					false, StandardCharsets.UTF_8.name());
			log.info("StartSession#master deck debug file created");
		}

		/*
		 * Shove master deck cards into a Map<> for fast lookup by id.
		 */

		Map<String, ICard<CardData>> cardLookupMap = new HashMap<String, ICard<CardData>>();
		for (ICard<CardData> card : masterDeck.getCards()) {
			cardLookupMap.put(card.id(), card);
		}

		Deck<CardData> activeDeck = new Deck<CardData>();
		/*
		 * The json card stats data aren't stored directly as a single json
		 * object in a list to reduce memory requirements for serialization and
		 * deserialization. Each valid set of stats indicates a card already
		 * "in play". Update each such card with the saved stats and move each
		 * one into the "active deck".
		 */
		for (String jsonCardStats : jsonCardsStats) {
			if (jsonCardStats.trim().isEmpty()) {
				continue;
			}
			if (!jsonCardStats.contains("\t")) {
				continue;
			}
			String[] txtStats = jsonCardStats.split("\t");
			if (txtStats[0].trim().isEmpty()) {
				continue;
			}
			if (txtStats[1].trim().isEmpty()) {
				continue;
			}
			String id = txtStats[0];
			ICard<CardData> card = cardLookupMap.get(id);
			/*
			 * stats refers to a card that no longer exists...
			 */
			if (card==null) {
				log.info("No matching card found for: '"+id+"'");
				continue;
			}
			CardStats stats = json.fromJson(CardStats.class, txtStats[1]);
			card.setCardStats(stats);
			/*
			 * move this "in play" card into the active deck. Being sure to set
			 * all stats to "never shown/correct".
			 */
			card.resetStats();
			card.resetTriesRemaining(CardData.MAX_TRIES);
			card.getCardStats().setPimsleurSlot(0);
			activeDeck.add(card);
		}
		log.info("StartSession#active deck created");
		game.setScreen(new LearningSession(game, session, masterDeck, activeDeck));
	}
}
@@ -4117,20 +4117,21 @@
 %09%09%09%09log.
-info
+error
 (%22No mat

mark as an error