/*
  Copyright (c) 2025-2026 Kay Kasper
  under the MIT License (MIT)
*/

#ifndef ROTARYENCODER2_TESTSWITCH
#define ROTARYENCODER2_TESTSWITCH

#include "Common.h"

void doRotaryEncoder2Tests(int id){  // ID_ENCODER2TEST = 7
  RotaryEncoder2Analyzer TestREAnalyzer = RotaryEncoder2Analyzer();
  TestRotaryEncoder stdEncoder(&TestREAnalyzer, true, INPUT_PIN, INPUT_PIN_B, 0, false);
  unsigned long tmpMicros, startmicro = 0;
  int seq;
  boolean tmpBool;

  stdEncoder.setMapping(REA_STATE_E_OFF, REA_STATE_E_OFF + 10);
  stdEncoder.setMapping(REA_STATE_E_DIRECTION_R, REA_STATE_E_DIRECTION_R + 10);
  stdEncoder.setMapping(REA_STATE_E_DIRECTION_L, REA_STATE_E_DIRECTION_L + 10);
  
  seq = 0; // no waits, positive logic
  stdEncoder.setReadCycleMillis(0);
  stdEncoder.setDebounceMillis(0);
  stdEncoder.setInvertRaw(false);
  stdEncoder.reset();
  check(stdEncoder.getState(),SW_STATE_UNDEFINED,id,seq+1);
  check(stdEncoder.getPrevState(),SW_STATE_UNDEFINED,id,seq+2);
  check(stdEncoder.getMappedState(),SW_STATE_UNDEFINED,id,seq+3);
  check(stdEncoder.getPrevMappedState(),SW_STATE_UNDEFINED,id,seq+4);

  // test full cycle OFF -> A -> AB
  seq = 10;
  stdEncoder.setRawState(0); // OFF
  check(stdEncoder.hasChanged(),true,id,seq+1);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+2);
  stdEncoder.setRawState(1);  // A
  check(stdEncoder.hasChanged(),false,id,seq+3);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+4);
  stdEncoder.setRawState(3);  // AB
  check(stdEncoder.hasChanged(),true,id,seq+5);
  check(stdEncoder.getState(),REA_STATE_E_DIRECTION_R,id,seq+6);

  // test full cycle AB -> B -> OFF
  seq = 20;
  stdEncoder.setRawState(3); // AB
  check(stdEncoder.hasChanged(),true,id,seq+1);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+2);
  stdEncoder.setRawState(2);  // B
  check(stdEncoder.hasChanged(),false,id,seq+3);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+4);
  stdEncoder.setRawState(0);  // OFF
  check(stdEncoder.hasChanged(),true,id,seq+5);
  check(stdEncoder.getState(),REA_STATE_E_DIRECTION_R,id,seq+6);

  // test full cycle OFF -> B -> AB
  seq = 30;
  stdEncoder.setRawState(0); // OFF
  check(stdEncoder.hasChanged(),true,id,seq+1);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+2);
  stdEncoder.setRawState(2);  // B
  check(stdEncoder.hasChanged(),false,id,seq+3);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+4);
  stdEncoder.setRawState(3);  // AB
  check(stdEncoder.hasChanged(),true,id,seq+5);
  check(stdEncoder.getState(),REA_STATE_E_DIRECTION_L,id,seq+6);

  // test full cycle AB -> A -> OFF
  seq = 40;
  stdEncoder.setRawState(3); // AB
  check(stdEncoder.hasChanged(),true,id,seq+1);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+2);
  stdEncoder.setRawState(1);  // A
  check(stdEncoder.hasChanged(),false,id,seq+3);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+4);
  stdEncoder.setRawState(0);  // OFF
  check(stdEncoder.hasChanged(),true,id,seq+5);
  check(stdEncoder.getState(),REA_STATE_E_DIRECTION_L,id,seq+6);

  // test reduced cycle OFF -> AB -> OFF
  seq = 50;
  stdEncoder.setRawState(0); // OFF
  check(stdEncoder.hasChanged(),true,id,seq+1);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+2);
  stdEncoder.setRawState(3);  // AB
  check(stdEncoder.hasChanged(),false,id,seq+3);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+4);
  stdEncoder.setRawState(0);  // OFF
  check(stdEncoder.hasChanged(),false,id,seq+5);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+6);

  // test reduced cycle OFF -> A -> OFF
  seq = 60;
  stdEncoder.setRawState(0); // OFF
  check(stdEncoder.hasChanged(),false,id,seq+1);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+2);
  stdEncoder.setRawState(1);  // A
  check(stdEncoder.hasChanged(),false,id,seq+3);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+4);
  stdEncoder.setRawState(0);  // OFF
  check(stdEncoder.hasChanged(),false,id,seq+5);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+6);

  // test reduced cycle OFF -> B -> OFF
  seq = 70;
  stdEncoder.setRawState(0); // OFF
  check(stdEncoder.hasChanged(),false,id,seq+1);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+2);
  stdEncoder.setRawState(2);  // B
  check(stdEncoder.hasChanged(),false,id,seq+3);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+4);
  stdEncoder.setRawState(0);  // OFF
  check(stdEncoder.hasChanged(),false,id,seq+5);
  check(stdEncoder.getState(),REA_STATE_E_OFF,id,seq+6);
}

#endif
