#include <Encoder.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(8,7,12,11,10,9);             //piny_displeje (RS, E, D4 až D7)
Encoder encoder(2,3);                          //piny enkoderu                    
#define EN              A0
#define A               A1
#define B               A2
#define C               A3
#define TAPE1           A4
#define TAPE2           A5
#define spinac_mute     5
#define spinac_adresy   6
#define spinac_bargraf  4
#define rezim_bargraf   13

short menu = -1;
long stara_pozice  = -999;
long nova_pozice  = 0;
short zvolen = 0;

bool zmena_mute=0;
int stav_mute = HIGH;

bool stav_bargraf = LOW;

int stav_novy;             
int posledni_stav = LOW;   
unsigned long posledni_cas = 0;  

int stav_novy2;             
int posledni_stav2 = LOW;   
unsigned long posledni_cas2 = 0;  

int stav_novy3;            
int posledni_stav3 = LOW;   
unsigned long posledni_cas3 = 0;  

unsigned long odezva = 50;  

void setupTimer1() {
  noInterrupts();
  TCCR1A = 0;
  TCCR1B = 0;           //vycisteni registru
  TCNT1 = 0;

  // 1 Hz (16000000/((15624+1)*1024))
  OCR1A = 65535;
  TCCR1B |= (1 << WGM12);
  TCCR1B |= (1 << CS10)|(1 << CS12);    // 1024 delicka 
  TIMSK1 |= (1 << OCIE1A);
  interrupts();
}

void setup() {
  pinMode(spinac_mute,   INPUT);
  pinMode(spinac_adresy, INPUT);
 
  pinMode(A,        OUTPUT);
  pinMode(B,        OUTPUT);
  pinMode(C,        OUTPUT);
  pinMode(EN,       OUTPUT);
  pinMode(TAPE1,     OUTPUT);
  pinMode(TAPE2,     OUTPUT);
  pinMode(rezim_bargraf, OUTPUT);

  digitalWrite(EN,HIGH);
  
  Serial.begin(9600);
  lcd.begin(16,2);
  lcd.print("  AUDIO PREAMP");
  lcd.setCursor(0,1);
  lcd.print("    8 INPUTS");
  delay(3000);
  
}

void loop() 
{
 
  mute();
  okamzite_adresy();
  prepinac();
  bargraf();
               
}

void mute()
{
  int cteni = digitalRead(spinac_mute);
  zmena_mute=0;

  if (cteni != posledni_stav) {
    posledni_cas = millis();
  }

  if ((millis() - posledni_cas) > odezva) {
    
    if (cteni != stav_novy) {
      stav_novy = cteni;

      if (stav_novy == LOW) {
        stav_mute = !stav_mute;
        Serial.println("MUTE změna");
        zmena_mute=1;
      }
      
      
    }
  }
  digitalWrite(EN, stav_mute);

  posledni_stav = cteni;
}

void okamzite_adresy()
{
  int cteni = digitalRead(spinac_adresy);


  if (cteni != posledni_stav2) {
    posledni_cas2 = millis();
  }

  if ((millis() - posledni_cas2) > odezva) {

    if (cteni != stav_novy2) {
      stav_novy2 = cteni;

      if (stav_novy2 == LOW) {
        adresy();
        
        
      }
    }
  }

  posledni_stav2 = cteni;
}

void prepinac()
{
  nova_pozice = encoder.read() / 4;
  if(nova_pozice < stara_pozice) menu--;
  else if(nova_pozice > stara_pozice) menu++;

  if(menu == -1) menu = 7;
  else if (menu == 8) menu = 0;
  
  if (nova_pozice != stara_pozice || zmena_mute==1)
  {
    setupTimer1();
    stara_pozice = nova_pozice;
    
    Serial.println("CASOVAC");  
    Serial.println(menu); 
    lcd.clear();    
    switch(menu)
    {
      case 4: 
        {
          lcd.print("       CD ");
          break;
        }
      case 7:
        {
          lcd.print("     PHONO ");
          break;
        }
      case 3:
        {
          lcd.print("     TUNER");
          break;
        }
      case 5:
        {
          lcd.print("     TAPE 1");
          break;
        }
      case 6:
        {
          lcd.print("     TAPE 2");
          break;
        }
      case 2:
        {
          lcd.print("     AUX 3");
          break;
        }
      case 0:
        {
          lcd.print("     AUX 1");
          break;
        }
      case 1:
        {
          lcd.print("     AUX 2");
          break;
        }
    }
    
   if(stav_mute==0)
   {
    lcd.setCursor(0,1);
    lcd.print("MUTE");
   }
  }
  
}

ISR(TIMER1_COMPA_vect) 
{
  TCNT1=0;
  lcd.clear();    
    switch(zvolen)
    {
      case 4: 
        {
          lcd.print("       CD ");
          break;
        }
      case 7:
        {
          lcd.print("     PHONO ");
          break;
        }
      case 3:
        {
          lcd.print("     TUNER");
          break;
        }
      case 5:
        {
          lcd.print("     TAPE 1");
          break;
        }
      case 6:
        {
          lcd.print("     TAPE 2");
          break;
        }
      case 2:
        {
          lcd.print("     AUX 3");
          break;
        }
      case 0:
        {
          lcd.print("     AUX 1");
          break;
        }
      case 1:
        {
          lcd.print("     AUX 2");
          break;
        }
    }
    
   if(stav_mute==0)
   {
    lcd.setCursor(0,1);
    lcd.print("MUTE");
   }
  menu=zvolen;
  TIMSK1 &= ~(1 << OCIE1A);
  
  TCCR1A = 0; 
  TCCR1B = 0;             //vycisteni_registru
  TCNT1 = 0;
}

void adresy()
{
  TCNT1=0;  
               switch(menu)
              {
                case 2: 
                {
                  zvolen=2;
                  digitalWrite(A,0);
                  digitalWrite(B,1);
                  digitalWrite(C,0);
                  digitalWrite(TAPE1,0);
                  digitalWrite(TAPE2,0);
                  Serial.print("AUX 3"); 
                  break;
                }
                case 3:
                {
                  zvolen=3;
                  digitalWrite(A,1);
                  digitalWrite(B,0);
                  digitalWrite(C,0);
                  digitalWrite(TAPE1,0);
                  digitalWrite(TAPE2,0);
                  Serial.print("TUNER"); 
                  break;
                }
                case 4:
                {
                  zvolen=4;
                  digitalWrite(A,0);
                  digitalWrite(B,0);
                  digitalWrite(C,0);
                  digitalWrite(TAPE1,0);
                  digitalWrite(TAPE2,0);
                  Serial.print("CD"); 
                  break;
                }
                case 5:
                {
                  zvolen=5;
                  digitalWrite(A,0);
                  digitalWrite(B,0);
                  digitalWrite(C,1);
                  digitalWrite(TAPE1,1);
                  digitalWrite(TAPE2,0);
                  Serial.print("TAPE1"); 
                  break;
                }
                case 6:
                {
                  zvolen=6;
                  digitalWrite(A,1);
                  digitalWrite(B,0);
                  digitalWrite(C,1);
                  digitalWrite(TAPE2,1);
                  digitalWrite(TAPE1,0);
                  Serial.print("TAPE2"); 
                  break;
                }
                case 7:
                {
                  zvolen=7;
                  digitalWrite(A,0);
                  digitalWrite(B,1);
                  digitalWrite(C,1);
                  digitalWrite(TAPE1,0);
                  digitalWrite(TAPE2,0);
                  Serial.print("PHONO"); 
                  break;
                }
                case 0:
                {
                  zvolen=0;
                  digitalWrite(A,1);
                  digitalWrite(B,1);
                  digitalWrite(C,0);
                  digitalWrite(TAPE1,0);
                  digitalWrite(TAPE2,0);
                  Serial.print("AUX 1"); 
                  break;
                }
                case 1:
                {
                  zvolen=1;
                  digitalWrite(A,1);
                  digitalWrite(B,1);
                  digitalWrite(C,1);
                  digitalWrite(TAPE1,0);
                  digitalWrite(TAPE2,0);
                  Serial.print("AUX 2"); 
                  break;
                }
              } 
              TIMSK1 &= ~(1 << OCIE1A);
  TCCR1A = 0;
  TCCR1B = 0;                                 //vycisteni registru
  TCNT1 = 0;
}

void bargraf()
{
  
  int cteni = digitalRead(spinac_bargraf);

  if (cteni != posledni_stav3) {
    posledni_cas3 = millis();
  }

  if ((millis() - posledni_cas3) > odezva) {
    

    if (cteni != stav_novy3) {
      stav_novy3 = cteni;

      if (stav_novy3 == LOW) {
        stav_bargraf = !stav_bargraf;
        Serial.println("Zmena bargraf");
        digitalWrite(rezim_bargraf, stav_bargraf);
      }
      
      
    }
  }
  posledni_stav3 = cteni;
}
