#include "shield.h"

#define BUTTON_SAMPLE_INTERVAL 2000

Shield MFS;

const byte LED[] = {LED_1_PIN, LED_2_PIN, LED_3_PIN, LED_4_PIN};

const byte SEGMENT_DIGITS[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0X80,0X90};
const byte SEGMENT_ALPHA[] = {136, 131, 167, 161, 134, 142, 144, 139 ,207, 241, 182, 199, 182, 171, 163, 140, 152, 175, 146, 135, 227, 182, 182, 182, 145, 182};
const byte SEGMENT_NUM[] = {0xF1,0xF2,0xF4,0xF8};


void Shield::initShield() {
  pinMode(LED[0], OUTPUT);
  pinMode(LED[1], OUTPUT);
  pinMode(LED[2], OUTPUT);
  pinMode(LED[3], OUTPUT);

  digitalWrite(LED[0], HIGH);
  digitalWrite(LED[1], HIGH);
  digitalWrite(LED[2], HIGH);
  digitalWrite(LED[3], HIGH);

  pinMode(LATCH_DIO,OUTPUT);        // Устанавливаем вывод как выход
  pinMode(CLK_DIO,OUTPUT);          // Устанавливаем вывод как выход
  pinMode(DATA_DIO,OUTPUT);         // Устанавливаем вывод как выход

  pinMode(BEEPER_PIN, OUTPUT);
  digitalWrite(BEEPER_PIN, HIGH);

  pinMode(BUTTON_1_PIN, INPUT);
  pinMode(BUTTON_2_PIN, INPUT);
  pinMode(BUTTON_3_PIN, INPUT);
}

byte Shield::readButton(byte btn, byte &btnVal) {
  int val = digitalRead(btn);
  if (btnVal == LOW && val == LOW && m_timerButton == BUTTON_SAMPLE_INTERVAL) {
    m_timerButton = 0;
    return BUTTON_LONG_PRESSED_IND;
  }
  else if (val == HIGH && btnVal != val && m_timerButton < BUTTON_SAMPLE_INTERVAL) {
    btnVal = HIGH;
    m_timerButton = 0;
    return BUTTON_SHORT_RELEASE_IND;
  }
  else if (val == HIGH && btnVal != val) {
    btnVal = HIGH;
    m_timerButton = 0;
    return BUTTON_LONG_RELEASE_IND;
  }
  else if (val == LOW) {
    btnVal = val;
    return BUTTON_PRESSED_IND;
  }
  return 0;
}

byte Shield::getButton() {
  static byte s_valButton_1;
  static byte s_valButton_2;
  static byte s_valButton_3;
  // m_tm = millis();
  unsigned long tm = millis();
  if (m_timerButtonNext < tm) {
    m_timerButtonNext = tm + m_timerButtonTo;
    if (s_valButton_1 == LOW || s_valButton_2 == LOW || s_valButton_3 == LOW)
      m_timerButton += BUTTON_SAMPLE_INTERVAL / 2;
    if (m_timerButton > BUTTON_SAMPLE_INTERVAL) m_timerButton = 0;
  }

  byte val;
  val = readButton(BUTTON_1_PIN, s_valButton_1);
  if (val) return 1 | val;
  val = readButton(BUTTON_2_PIN, s_valButton_2);
  if (val) return 2 | val;
  val = readButton(BUTTON_3_PIN, s_valButton_3);
  if (val) return 3 | val;
  return 0;

  // byte val = digitalRead(BUTTON_1_PIN);
  // // if (val == LOW) Serial.println("Button 1 geted");
  // if (s_valButton_1 == LOW && val == LOW && m_timerButton == BUTTON_SAMPLE_INTERVAL) {
  //   m_timerButton = 0;
  //   Serial.println("Button 1 geted");
  //   return BUTTON_1_LONG_PRESSED;
  // }
  // else if (val == HIGH && s_valButton_1 != val && m_timerButton < BUTTON_SAMPLE_INTERVAL) {
  //   s_valButton_1 = HIGH;
  //   m_timerButton = 0;
  //   Serial.println("Button 1 geted");
  //   return BUTTON_1_SHORT_RELEASE;
  // }
  // else if (val == HIGH && s_valButton_1 != val) {
  //   s_valButton_1 = HIGH;
  //   s_valButton_1 = val;
  //   Serial.println("Button 1 geted");
  //   return BUTTON_1_PRESSED;
  // }
  // val = digitalRead(BUTTON_2_PIN);
  // // if (val == LOW) Serial.println("Button 2 geted");
  // if (s_valButton_2 == LOW && val == LOW && m_timerButton == BUTTON_SAMPLE_INTERVAL) {
  //   m_timerButton = 0;
  //   return BUTTON_2_LONG_PRESSED;
  // }
  // else if (val == HIGH && s_valButton_2 != val && m_timerButton < BUTTON_SAMPLE_INTERVAL) {
  //   s_valButton_2 = HIGH;
  //   m_timerButton = 0;
  //   return BUTTON_2_SHORT_RELEASE;
  // }
  // else if (val == HIGH && s_valButton_2 != val) {
  //   s_valButton_2 = HIGH;
  //   s_valButton_2 = val;
  //   return BUTTON_2_PRESSED;
  // }
  // val = digitalRead(BUTTON_3_PIN);
  // if (s_valButton_3 == LOW && val == LOW && m_timerButton == BUTTON_SAMPLE_INTERVAL) {
  //   m_timerButton = 0;
  //   return BUTTON_3_LONG_PRESSED;
  // }
  // else if (val == HIGH && s_valButton_3 != val && m_timerButton < BUTTON_SAMPLE_INTERVAL) {
  //   s_valButton_3 = HIGH;
  //   m_timerButton = 0;
  //   return BUTTON_3_SHORT_RELEASE;
  // }
  // else if (val == HIGH && s_valButton_3 != val) {
  //   s_valButton_3 = HIGH;
  //   m_timerButton = 0;
  //   return BUTTON_3_LONG_RELEASE;
  // }
  // else if (val == LOW) {
  //   s_valButton_3 = val;
  //   return BUTTON_3_PRESSED;
  // }
  return 0;
}


void Shield::beep(unsigned int on_period,
          unsigned int off_period,
          byte cycles,
          unsigned int loop_cycles,
          unsigned int loop_delay_period
         ) {
  cycles = cycles == 0 ? 1 : cycles;
  loop_cycles = loop_cycles == 0 ? 1 : loop_cycles;

  if (on_period == 0) {
    digitalWrite(BEEPER_PIN, OFF);
    return;
  }

  m_timerBeeperOnPeriod = 0;
  m_timerBeeperOffPeriod = 0;
  m_timerBeeperLoopDelayPeriod = 0;

  unsigned long tm = millis();
  if (m_timerBeeperNext < tm) {
    m_timerBeeperNext = tm + m_timerBeeperTo;
    if (m_timerBeeperOnPeriod > on_period) m_timerBeeperOnPeriod = 0;
    if (m_timerBeeperOffPeriod > off_period) m_timerBeeperOffPeriod = 0;
    if (m_timerBeeperLoopDelayPeriod > loop_delay_period) m_timerBeeperLoopDelayPeriod = 0;

    for (int i = 0; i < cycles; ++i) {
      for (int j = 0; j < loop_cycles; ++j) {
        digitalWrite(BEEPER_PIN, LOW);
        delay(on_period);
        digitalWrite(BEEPER_PIN, HIGH);
        delay(off_period);
      }
      delay(loop_delay_period);
    }
  }

}

void Shield::blinkLeds(byte led, int millsec, bool turnoff_delay) {
  digitalWrite(led, LOW);
  delay(millsec);
  digitalWrite(led, HIGH);
  if (turnoff_delay) delay(millsec);
}

void Shield::blinkLeds(byte led1, byte led2, int millsec, bool turnoff_delay) {
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  delay(millsec);
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  if (turnoff_delay) {
    delay(millsec);
  }
}

void Shield::blinkLeds(byte led1, byte led2, byte led3, int millsec, bool turnoff_delay) {
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  delay(millsec);
  digitalWrite(led1, HIGH);
  digitalWrite(led2, HIGH);
  digitalWrite(led3, HIGH);
  if (turnoff_delay) {
    delay(millsec);
  }
}

void Shield::blinkLeds(int millsec, bool turnoff_delay) {
  for (int i = 10; i < 14; ++i) {
    digitalWrite(i, LOW);
  }
  delay(millsec);
  for (int i = 10; i < 14; ++i) {
    digitalWrite(i, HIGH);
  }
  if (turnoff_delay)  delay(millsec);
}

void Shield::writeNumber(byte seg, byte val) {
  digitalWrite(LATCH_DIO, LOW);
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_DIGITS[val]);
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_NUM[seg]);
  digitalWrite(LATCH_DIO, HIGH);
}

void Shield::writeAlpha(byte seg, byte val) {
  digitalWrite(LATCH_DIO, LOW);
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_ALPHA[val]);
  shiftOut(DATA_DIO, CLK_DIO, MSBFIRST, SEGMENT_NUM[seg]);
  digitalWrite(LATCH_DIO, HIGH);
}

void Shield::writeDisplay(int val) {
  writeNumber(0, (val / 1000) % 10);
  writeNumber(1, (val / 100) % 10);
  writeNumber(2, (val / 10) % 10);
  writeNumber(3, val % 10);
  writeNumber(4, 0);
}

byte AsciiToSegmentValue (byte ascii) {
  byte segmentValue = 182;
}
