// Copyright (c) 2021 Dominic Masters
// 
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#pragma once
#include "../libs.h"
#include "../util/list.h"

/** Debug Inputs */
#define INPUT_NULL        (inputbind_t)0x00

/** Real Inputs (Starts at 32/0x20) */
#define INPUT_UP          (inputbind_t)0x20
#define INPUT_DOWN        (inputbind_t)0x21
#define INPUT_LEFT        (inputbind_t)0x22
#define INPUT_RIGHT       (inputbind_t)0x23
#define INPUT_ACCEPT      (inputbind_t)0x24

/** Additional sources */
#define INPUT_MOUSE_X     (inputsource_t)0x10
#define INPUT_MOUSE_Y     (inputsource_t)0x11

#define INPUT_BIND_COUNT 0x40
#define INPUT_SOURCE_COUNT 0xFF

/**
 * Input Bind, a specific action bind reference for the game engine to use.
 * e.g. "Jump" or "Walk Forward".
 */
typedef uint8_t inputbind_t;

/**
 * Input source identifier. It's up to the platform itself to decide what the
 * hell this number refers to. For most platforms it will be an input, such as a
 * keyboard scancode or a (pad number * button count) + button.
 */
typedef uint8_t inputsource_t;

/**
 * Value that represents the state of an input. Defined as 0-1 where 0 is set
 * to be completely off / netural state, and 1 is completely on / full state.
 */
typedef float inputval_t;

/**
 * Structure for the entire input mapping.
 */
typedef struct {
  /** Float of the input between 0 and 1. */
  inputval_t inputsA[INPUT_BIND_COUNT];
  /** Float of the input between 0 and 1. */
  inputval_t inputsB[INPUT_BIND_COUNT];

  /** Flippable state */
  inputval_t *current, *previous;

  /**
   * Binding Map, Array of lists where index = binding and entry is a list of
   * input sources.
   */
  list_t *bindMap[INPUT_BIND_COUNT];

  /**
   * Input buffer array. Keeps track of raw values from the inputs.
   * The engine will read from the buffer when necessary.
   */
  inputval_t buffer[INPUT_SOURCE_COUNT];

  /** Float of the GameTime that the input was actuated last. */
  float times[INPUT_BIND_COUNT];
} input_t;