//======================================================
// 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    = 10; 
    bool limitEnable  = true;

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

    // Give Permision To Change Display
    DISPLAY_CHANGED = false;
  }

//======================================================
// 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);

    // Give Permision To Change Display
    DISPLAY_CHANGED = false;
  }

//======================================================
// 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();

    // Display On OLED
    GAME_COUNTER_DISPLAY(0, limit);

    //-------------------------
    // 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 Reset To Zero
          counter = 0;
          
          // Starting Stamp From Now
          startStamp = millis();
          
          // Time Stamp Is Now
          timeStamp = startStamp;

          // LED STRIP LED STRIP RESET SIGNAL
          //LED_SIGNAL_RESET();
        }
      }

      // Reset The Counter
      if(BTN_INCREASE.pressed()) {
        counter     = 0;
        startStamp  = millis();
        timeStamp   = startStamp;
        GAME_COUNTER_DISPLAY(counter, limit);
      }

      // Will Exit The Game
      if(BTN_CENTER.pressed()) {
        // Send Game Over JSON Signal
        dualcomm(GAME_OVER);

        // Give Permition To Change OLED
        DISPLAY_CHANGED = false;
        
        // Return To Main Menu
        return;
      }

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

      // Read Impact
      if(PIEZO_MAP >= VTH)
      {
        counter++;
        GAME_COUNTER_DISPLAY(counter, limit);
        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;
  }

//------------------------------------------------------
//  OLED - GAME COUNTER PLAY
//------------------------------------------------------
  
  void GAME_COUNTER_DISPLAY(uint16_t count, uint16_t limit)
  {
    OLED_CLEAR();
    drawTextCenter(128/2, 0, 2, "KICKS");
    drawTextCenter(128/2, 20, 3, String(count) + "/" + String(limit));
    
    // Exit Button Command Only Via Stand Alone Mode
    if(BLUETOOTH_STATUS == false) {
      drawTextCenter(128/2, 50, 1, "<< EXIT >>");
    }
    
    OLED_SHOW();
  }

//------------------------------------------------------
//  OLED - GAME COUNTER RESULT
//------------------------------------------------------
  
  void GAME_RESULT_DISPLAY(uint16_t count, uint16_t limit)
  {
    OLED_CLEAR();
    drawTextCenter(128/2, 0, 2, "FINISHED");
    drawTextCenter(128/2, 20, 3, String(count) + "/" + String(limit));
    
    // Exit Button Command Only Via Stand Alone Mode
    if(BLUETOOTH_STATUS == false) {
      drawTextCenter(128/2, 50, 1, "<< EXIT >>");
    }

    // Show Data On OLED
    OLED_SHOW();

    // Waiting For Center Button To Move On
    while(1){
      if(BTN_CENTER.pressed()) {
        break;
      }
    }
  }
  
