//======================================================
// MAIN COUNTER GAME LOOP
//======================================================

  /* This Game Can Be Called From 
   *  Stand Alone Mode / Bluetooth Connection
   *  The primary mode is the standalone but
   *  if the bluetooth is connected it has the priority
   *  so it will take over the control of the device
   *  
   *  If you want to control the game via bluetooth
   *  you need to call : game_counter_bluetooth(JSON String)
   *  If you want to use the stand alone mode
   *  you need to call : game_counter_standalone()
   *  
   *  the game returns a float point number which is
   *  in seconds. so the athlete know how long he takes to react
   */

//======================================================
// THIS IS THE STAND ALONE CALL FOR THE GAME
//======================================================

  void game_counter_standalone()
  {
    // Variables Of The Game
    uint16_t limit    = 0; 
    bool limitEnable  = 0;

    // Play The Game
    game_counter(limit, limitEnable);
  }

//======================================================
// THIS IS THE BLUETOOTH CALL FOR THE GAME
//======================================================

  /* COUNTER GAME SETTINGS PARAMETERS NOTE:
   * --------------------------------------
   *  
   *  FORMAT :
   *  --------
   *    {"le": false, "lm": 10}
   *  
   *  MEANNING :
   *  ----------
   *    ct : count
   *    le : stands for limit enable, if is TRUE the game end if target value is meet
   *    lm : targeted amount of kicks
   *  
   *  THINGS THAT ENDS THE GAME :
   *  ---------------------------
   *    1. BY A COMMAND "FROM APP VIA BLUETOOTH"
   *    2. BY LIMITS MEET "WHEN NUMBER OF YOUR KICKS REACH TO lm VALUE"
   *  
   *  WHAT JSON TO BE COLLECTED :
   *  ---------------------------
   *    1. FOR EVERY KICK YOU RECEIVE THE COUNTER DISJSON AND TIMESTAMP
   *    WE NEED TO COLLECT TIMESTAMPS AS AN ARRAY IN JSON FORMAT
   *  
   *  CALCULATING RESULTS :
   *  ---------------------
   *    No calculation required, Its directly the count
   */

  void game_counter_bluetooth(String settings)
  {
    //------------------------------------------------------
    // START OF READING THE SETTINGS
    //------------------------------------------------------
     
    // Deserialize the JSON document
    DeserializationError  error = deserializeJson(JSON, settings); // the main JSON body container

    // JSON ERROR
    if(error) {
      dualcomm(JSON_ERROR);
      return;
    }
    
    // PUBLIC VARIABLES
    uint16_t  limit       = JSON["lm"]; // Kick Target Limit
    bool      limitEnable = JSON["le"]; // Enable Kick Target Limit

    // Clearing Buffer
    JSON.clear();

    // Play The Game
    game_counter(limit, limitEnable);
  }

//======================================================
// COUNTER JSON JSON -> To Send Back To Server
//======================================================

  void game_counter(uint16_t limit, bool limitEnable)
  {
    // Kick Counter
    uint16_t counter = 0;

    // Game Start Lights
    LED_SIGNAL_START();

    //-------------------------
    // PREPARE FOR GAME START
    //-------------------------

    // staring Of time stamp
    unsigned long startStamp = millis();

    while(1) 
    {
      // Time Stamp
      unsigned long timeStamp = millis() - startStamp;

      // If Stop Command Came From Smart Phone
      if(isBluetooth)
      {
        String msg = Bluetooth.readStringUntil('\n');
        flushBluetooth;
        msg.trim();
        if(msg == CM_STOP) 
        {
          dualcomm(GAME_OVER);
          // Grean Light In
          LED_SIGNAL_END();
          // RESET
          return;
        }
        else if(msg == CM_RESET) 
        {
          counter = 0;
          startStamp = millis();
          timeStamp = startStamp;
          LED_SIGNAL_RESET();
        }
      }

      // If Limits Are Enabled And Meet
      if(limitEnable == true && counter == limit)
      {
        // END GAME
        dualcomm(GAME_OVER);
        // Celebration
        LED_SIGNAL_CELEBRATION();
        // RESET
        return;
      }

      // Read Impact
      if(readImpact() > VTH)
      {
        counter++;
        dualcomm(counter_JSON_json(counter, timeStamp));
        delay(100);
      }
    }
  }

//======================================================
// COUNTER JSON -> To Send Back To Mobile
//======================================================

  String counter_JSON_json(unsigned int ct, unsigned int st)
  {  
    // Convert Int To Float
    float stamp = st;
    stamp /= 1000;

    // Assignning JSONset
    JSON["ct"]  = ct;
    JSON["st"]  = String(stamp, 3).toFloat();
    
    String output;
    serializeJson(JSON, output);
    JSON.clear();
    return output;
  }
