# Play State Modes refactor
**Status**: Deprecated (Feb 6, 2024)

## Changes
:::{important}
There have been some substantial updates to the code since
this was authored. Most of the information included is not wrong,
but it's insufficient to describe this enum. In particular:
 * `GridStateMode` has been replaced by a bitfield. See
   [grid-state-modes.md](grid-state-modes.md) for more information.
:::

## Original Doc

### Rationale:

As per Issue #45 and Issue #11, we have a confusing set of
interactions between settings and modes. This is an attempt to clean
them up and document them better. It also cleans up some pathologies
along the way.

### XwordState

We propose the new structure and enums:

```c
typedef enum
{
  XWORD_STATE_SOLVE,       /* @ Solve a crossword @ */
  XWORD_STATE_BROWSE,      /* @ Browse through a board without modifying it @ */
  XWORD_STATE_EDIT,        /* @ Edit the grid @ */
  XWORD_STATE_EDIT_BROWSE, /* @ Browse through a board without modifying it @ */
  XWORD_STATE_SELECT,      /* @ Select cells @ */
  XWORD_STATE_VIEW,        /* @ Display a board with no interaction @ */
} XwordStateMode;

typedef enum
{
  XWORD_REVEAL_NONE,         /* @ Reveal nothing. Display the crossword as normal @ */
  XWORD_REVEAL_ALL,          /* @ Reveal all unsolved letters. Effectively give up @ */
  XWORD_REVEAL_ERRORS_BOARD, /* @ Reveal all incorrect guesses on the board @ */
  XWORD_REVEAL_ERRORS_CLUE,  /* @ Reveal all incorrect guesses in the current clue @ */
  XWORD_REVEAL_ERRORS_CELL,  /* @ Reveal all incorrect guesses in the current cell @ */
} XwordRevealMode;

typedef enum
{
  XWORD_SELECTION_SINGLE,            /* @ Select individual cells, only @ */
  XWORD_SELECTION_TYPE_LETTERS_ONLY, /* @ Only lets the user select guessed letters @ */
  XWORD_SELECTION_TYPE_BLANKS_ONLY,  /* @ Only lets the user select empty spaces @ */
} XwordSelectionMode;

typedef struct
{
  XwordStateMode mode;
  IpuzPuzzle *xword;

  /* Current keyboard state */
  IpuzCellCoord cursor;
  ClueId clue;

  /* Modifiers to the current display and behavior */
  XwordRevealMode reveal_mode;
  XwordSelectionMode selection_mode;
  CellArray *cell_array;
  CrosswordsQuirks *quirks;
} XwordState;
```

### Modes:

This is a description of each mode, and which fields affect each mode.

* **XWORD_STATE_SOLVE** - Play the game. Lets the user guess answers
    * **reveal_**: Enum to indicate whether to reveal any errors
    * **keyboard state**: Current cursor position and direction
    * **quirks**: Uses the quirks to affect behaviours
* **XWORD_STATE_BROWSE** - It's similar to play but the user can only select cells, and can't edit the board.
    * **keyboard state**: Current cursor position and direction
* **XWORD_STATE_EDIT** - The answer is editable and shown. The guesses struct is ignored.
    * **keyboard state**: Current cursor position and direction
    * **quirks**: Uses the quirks to affect behaviours
* **XWORD_STATE_EDIT_BROWSE** - Similar to browse, but with slightly different movement behaviors. The guesses struct is ignored. Used for clue editing.
    * **keyboard state**: Current cursor position and direction
* **XWORD_STATE_SELECT** - The cell selection mode. Used for the the autofill and clue header. The guesses struct is ignored.
    * **select-mode:** enum to define the selection behavior. This acts very different than a list, so won't reuse any other selection modes
    * **keyboard state**: Current cursor position and direction
    * **cell_array**: Current selection
* **XWORD_STATE_VIEW** - No interaction with the user possible. Used for the hero graphics, etc.

:::{important}
PlayXword can't render **XWORD_STATE_EDIT** and EditXword
can't render **XWORD_STATE_SOLVE**.
:::

### Next Steps:

* [X] Rename PlayState to XwordState, as well as the various enums and fields listed above
* [X] Add XWORD_STATE_VIEW
* [X] Add XWORD_STATE_EDIT_BROWSE
* [X] Change reveal and selection to enums
* [ ] Composable handlers to adjust the state from a more semantic model and the mode /quirk based changes
* [X] Use IpuzCellCoord everywhere, and drop the row/column args
* [ ] (TBD) Change all the actions into a _dispatch() call, and create a single XwordEvent type
* [ ] (TBD) separate the guesses from the board
* [ ] Update `xword-state.md` and `xword-state-modes.md` to match new reality
