#include "Arduino.h"
#if !defined(SERIAL_PORT_MONITOR)
#error "Arduino version not supported. Please update your IDE to the latest version."
#endif

#if defined(SERIAL_PORT_USBVIRTUAL)
// Shield Jumper on HW (for Leonardo and Due)
#define port SERIAL_PORT_HARDWARE
#define pcSerial SERIAL_PORT_USBVIRTUAL
#else
// Shield Jumper on SW (using pins 12/13 or 8/9 as RX/TX)
#include "SoftwareSerial.h"
SoftwareSerial port(12, 13);
#define pcSerial SERIAL_PORT_MONITOR
#endif

#include "EasyVR.h"

EasyVR easyvr(port);

//Groups and Commands
enum Groups
{
  GROUP_0  = 0,
  GROUP_1  = 1,
};

enum Group0
{
  G0_INBUSHKA = 0,
};

enum Group1
{
  G1_POVOROT_NA_PRAVO = 0,
  G1_POVOROT_NA_LEVO = 1,
  G1_POVERNIS_KO_MNE_PEREDOM = 2,
  G1_SMOTRI_V_LES = 3,
  G1_TANSIY = 4,
  G1_ZAGHI_SVET = 5,
  G1_PORYSHI_SVET = 6,
  G1_KRUGOM = 7,
  G1_TYK_TYK = 8,
    G1_POVR = 9,
  G1_POVL = 10,
  G1_POV_K_M_P = 11,
  G1_TANEC = 12,
  G1_SVETON = 13,
  G1_SVETOFF = 14,
};


int8_t group, idx;
int t = 25;
const int red =  6;
const int green =  7;
const int blue =  8;// номер выхода, подключенного к светодиоду
// Variables will change:
int ledState = LOW;             // этой переменной устанавливаем состояние светодиода
long previousMillis = 0;        // храним время последнего переключения светодиода
long interval = 1000;

boolean LogR = true;
void setup()
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);

  // setup PC serial port
  pcSerial.begin(9600);

  // bridge mode?
  int mode = easyvr.bridgeRequested(pcSerial);
  switch (mode)
  {
    case EasyVR::BRIDGE_NONE:
      // setup EasyVR serial port
      port.begin(9600);
      // run normally
      pcSerial.println(F("---"));
      pcSerial.println(F("Bridge not started!"));
      break;

    case EasyVR::BRIDGE_NORMAL:
      // setup EasyVR serial port (low speed)
      port.begin(9600);
      // soft-connect the two serial ports (PC and EasyVR)
      easyvr.bridgeLoop(pcSerial);
      // resume normally if aborted
      pcSerial.println(F("---"));
      pcSerial.println(F("Bridge connection aborted!"));
      break;

    case EasyVR::BRIDGE_BOOT:
      // setup EasyVR serial port (high speed)
      port.begin(115200);
      // soft-connect the two serial ports (PC and EasyVR)
      easyvr.bridgeLoop(pcSerial);
      // resume normally if aborted
      pcSerial.println(F("---"));
      pcSerial.println(F("Bridge connection aborted!"));
      break;
  }

  while (!easyvr.detect())
  {
    Serial.println("EasyVR not detected!");
    delay(1000);
  }

  easyvr.setPinOutput(EasyVR::IO1, LOW);
  Serial.println("EasyVR detected!");
  easyvr.setTimeout(5);
  easyvr.setLanguage(0);

  group = EasyVR::TRIGGER; //<-- start group (customize)
}

void action();

void loop()
{

  digitalWrite(2, 0);
  digitalWrite(3, 0);
  digitalWrite(4, 0);
  digitalWrite(5, 0);
  if (LogR == true) digitalWrite(red, 1);
  else digitalWrite(red, 0);
  easyvr.setPinOutput(EasyVR::IO1, HIGH); // LED on (listening)
  Serial.print("Say a command in Group ");
  Serial.println(group);
  easyvr.recognizeCommand(group);

  do
  {
    // can do some processing while waiting for a spoken command
  }
  while (!easyvr.hasFinished());

  easyvr.setPinOutput(EasyVR::IO1, LOW); // LED off

  idx = easyvr.getWord();
  if (idx >= 0)
  {

    group = GROUP_1;
    // built-in trigger (ROBOT)
    // group = GROUP_X; <-- jump to another group X
    return;
  }
  idx = easyvr.getCommand();
  if (idx >= 0)
  {
    // print debug message
    uint8_t train = 0;
    char name[32];
    Serial.print("Command: ");
    Serial.print(idx);
    if (easyvr.dumpCommand(group, idx, name, train))
    {
      Serial.print(" = ");
      Serial.println(name);
    }
    else
      Serial.println();
    easyvr.playSound(0, EasyVR::VOL_FULL);
    // perform some action
    action();
  }
  else // errors or timeout
  {
    if (easyvr.isTimeout())
      Serial.println("Timed out, try again...");
    int16_t err = easyvr.getError();
    if (err >= 0)
    {
      Serial.print("Error ");
      Serial.println(err, HEX);
      digitalWrite(blue, 0);
      digitalWrite(red, 1);
      delay(10);
      digitalWrite(red, 0);
      delay(10);
      digitalWrite(red, 1);
      delay(10);
      digitalWrite(red, 0);
      delay(10);
      digitalWrite(red, 1);
      delay(10);
      digitalWrite(red, 0);
     digitalWrite(blue, 1);
    }
  }
}

void action()
{

  switch (group)
  {
      digitalWrite(6, 1);
    case GROUP_0:
      switch (idx)
      {
        case G0_INBUSHKA:
          // write your action code here
          LogR = false;
          digitalWrite (blue, 1);
          group = GROUP_1; //<-- or jump to another group X for composite commands
          break;
      }
      break;
    case GROUP_1:

      switch (idx)
      {
        case G1_POVOROT_NA_PRAVO:
        digitalWrite(2, 1);
        digitalWrite(3, 0);
        digitalWrite(4, 0);
        digitalWrite(5, 0);
        delay(t);
          led();
          break;
        case G1_POVOROT_NA_LEVO:
        digitalWrite(2, 0);
        digitalWrite(3, 1);
        digitalWrite(4, 0);
        digitalWrite(5, 0);
          delay(t);
          led();
          break;
        case G1_POVERNIS_KO_MNE_PEREDOM:
        digitalWrite(2, 1);
        digitalWrite(3, 1);
        digitalWrite(4, 0);
        digitalWrite(5, 0);
          delay(t);
          led();
          break;
        case G1_SMOTRI_V_LES:
        digitalWrite(2, 0);
        digitalWrite(3, 0);
        digitalWrite(4, 1);
        digitalWrite(5, 0);
          delay(t);
          led();
          break;
        case G1_TANSIY:
        digitalWrite(2, 1);
        digitalWrite(3, 0);
        digitalWrite(4, 1);
        digitalWrite(5, 0);
          delay(t);
          led();
          break;
        case G1_ZAGHI_SVET:
        digitalWrite(2, 0);
        digitalWrite(3, 1);
        digitalWrite(4, 1);
        digitalWrite(5, 0);
          delay(t);
          led();
          break;
        case G1_PORYSHI_SVET:
        digitalWrite(2, 1);
        digitalWrite(3, 1);
        digitalWrite(4, 1);
        digitalWrite(5, 0);
          delay(t);
          led(); 
          break;
        case G1_KRUGOM:
        digitalWrite(2, 0);
        digitalWrite(3, 0);
        digitalWrite(4, 0);
        digitalWrite(5, 1);
          delay(t);
          led(); 
          break;
        case G1_TYK_TYK:
        digitalWrite(2, 1);
        digitalWrite(3, 0);
        digitalWrite(4, 0);
        digitalWrite(5, 1);
          delay(t);
          led(); 
          break;

          case G1_POVR:
        digitalWrite(2, 1);
        digitalWrite(3, 0);
        digitalWrite(4, 0);
        digitalWrite(5, 0);

        delay(t);
          led();
        break;
      case G1_POVL:
        digitalWrite(2, 0);
        digitalWrite(3, 1);
        digitalWrite(4, 0);
        digitalWrite(5, 0);
          delay(t);
          led();       
      break;
      case G1_POV_K_M_P:
       digitalWrite(2, 1);
        digitalWrite(3, 1);
        digitalWrite(4, 0);
        digitalWrite(5, 0);
          delay(t);
          led();    
         break;
      case G1_TANEC:
        digitalWrite(2, 1);
        digitalWrite(3, 0);
        digitalWrite(4, 1);
        digitalWrite(5, 0);
         delay(t);
          led();
        break;
      case G1_SVETON:
        digitalWrite(2, 0);
        digitalWrite(3, 1);
        digitalWrite(4, 1);
        digitalWrite(5, 0);
         delay(t);
          led();
       break;
      case G1_SVETOFF:
      digitalWrite(2, 1);
        digitalWrite(3, 1);
        digitalWrite(4, 1);
        digitalWrite(5, 0);
          delay(t);
          led();     // write your action code here
        // group = GROUP_X; <-- or jump to another group X for composite commands
        break;
      }
      break;
  }
}


void led()
{
  digitalWrite(2, 0);
  digitalWrite(3, 0);
  digitalWrite(4, 0);
  digitalWrite(5, 0);

  digitalWrite(blue, 0);
  digitalWrite(green, 1);
  delay (250);
  digitalWrite(blue, 0);
  digitalWrite(green, 0);
  delay (250);
  digitalWrite(blue, 0);
  digitalWrite(green, 1);
  delay (250);
  digitalWrite(blue, 1);
  digitalWrite(green, 0);
}

