
#include <map>
#include <string>
#include <vector>
#include "ctx.h"
#include "llm.h"
#include "memory_Context.h"
#include "main.h"

// Detect mismatched items
//
// Conditions:
// 0. Two items has just been selected
// 1. The same item has been selected twice
// 2. Selected items are of different groups
memory_Context memory_detectMismatchedItems(
  memory_Context c
) {
  if (!(
    c.recentField == "selectedItems" &&
    c.selectedItems.size() == 2
  )) {
    c.recentField = "none";
    return c;
  }
  if (
    c.selectedItems[0] == c.selectedItems[1]
  ) {
    c.mismatchedItems.clear();
    c.mismatchedItems.push_back(c.selectedItems[0]);
    c.recentField = "mismatchedItems";
    return c;
  }
  if (
    c.playfieldItems[c.selectedItems[0]] != c.playfieldItems[c.selectedItems[1]]
  ) {
    c.mismatchedItems.clear();
    c.mismatchedItems.push_back(c.selectedItems[0]);
    c.mismatchedItems.push_back(c.selectedItems[1]);
    c.recentField = "mismatchedItems";
    return c;
  }
  c.recentField = "none";
  return c;
}

// Detect victory
//
// Conditions:
// 1. Matching items have just been hidden and all items are hidden now
memory_Context memory_detectVictory(
  memory_Context c
) {
  if (
    c.recentField == "hiddenItems" &&
    c.hiddenItems.size() == c.playfieldItems.size()
  ) {
    c.victory = true;
    c.recentField = "victory";
    return c;
  }
  c.recentField = "none";
  return c;
}

// Generate constant playfield
//
// Conditions:
// 1. Size has just been specified
//
// Both ids and group ids start with 0

memory_Context memory_generateConstPlayfield(
  memory_Context c
) {
  if (!(
    c.recentField == "playfieldSize"
  )) {
    c.recentField = "none";
    return c;
  }
  std::map<int, int> idGroups = { };
  auto id = 0;
  for (auto gid = 0; gid < c.playfieldSize; ++gid) {
    idGroups[id] = gid;
    id += 1;
    idGroups[id] = gid;
    id += 1;
  }
  c.playfieldItems = idGroups;
  c.recentField = "playfieldItems";
  return c;
}

// Hide matching selected items
//
// Conditions:
// 1. Two items are selected and they are of the same group
memory_Context memory_hideMatchingItems(
  memory_Context c
) {
  if (
    c.recentField == "selectedItems" &&
    c.selectedItems.size() == 2 &&
    c.playfieldItems[c.selectedItems[0]] == c.playfieldItems[c.selectedItems[1]]
  ) {
    c.hiddenItems.push_back(c.selectedItems[0]);
    c.hiddenItems.push_back(c.selectedItems[1]);
    c.recentField = "hiddenItems";
    return c;
  }
  c.recentField = "none";
  return c;
}

// Select item
//
// Conditions:
// 1. Id has just been specified for selection

memory_Context memory_selectItem(
  memory_Context c
) {
  if (!(
    c.recentField == "selectedId"
  )) {
    c.recentField = "none";
    return c;
  }
  if (
    c.selectedItems.size() == 2
  ) {
    c.selectedItems.clear();
  }
  c.selectedItems.push_back(c.selectedId);
  c.recentField = "selectedItems";
  return c;
}


