typedef enum {
  none,
  up=26,
  down=25,
  ok=14
  }Pins;
const Pins BUTTONPIN[] = {none,up,down,ok}; // Inputs for buttons. On many Arduinos pins 0 and 1 are used for serial making pin 2 the first free pin.
const uint8_t BUTTONCOUNT = 4; 
char pressing;           // Number of buttons.

enum Page_Dispaly{
 welcome,//歡迎畫面,LOGO,2秒後進入certification_date,
 certification_check,//顯示到期日及倒數天數,2秒後進入initial,
 return_to_vender,//檢測日期到期,5秒後自動關機
 initial,//初始化頁面,完成後到ready,
 initial_countdown,//倒數畫面,feulcell使用後2分鐘內會出現這個畫面,完成後到ready
 ready,
 ready_wait,//等按鈕,上下切頁到main menu,按OK到detacting
 //main
 main_menu,//主功能顯示,4個選項
 main_menu_wait,//等按鈕,點選上下選擇功能,此時無框
 main_menu_record,//顯示框線,點上下切換功能,點ok進入main_menu_record_page1,
 main_menu_information,//顯示框線,點上下切換功能,點ok進入main_menu_information_page1,
 main_menu_Blue_Tooth_setup,//顯示框線,點上下切換功能,點ok進入main_menu_Blue_Tooth_setup_page1,
 main_menu_back,
 //record
 main_menu_record_page1,//顯示第一頁,三個選項
 main_menu_record_page1_wait,//等按鈕
 main_menu_record_page_back,//回到ready
 main_menu_record_page1_1,//第1個選項加框
 main_menu_record_page1_1_wait,//等按鈕
 main_menu_record_page1_1_data,//最後一筆資料顯示
 main_menu_record_page1_1_data_wait,//等按鈕
 main_menu_record_page1_1_data_print,//列印紐加框
 main_menu_record_page1_1_data_back,//返回紐加框
 main_menu_record_page1_2,//第2個選項加框
 main_menu_record_page1_2_wait,//等按鈕
 main_menu_record_page1_2_data,//最後第2筆資料顯示
 main_menu_record_page1_2_data_wait,//等按鈕
 main_menu_record_page1_2_data_print,//列印紐加框
 main_menu_record_page1_2_data_back,//返回紐加框
 main_menu_record_page1_3,//第2個選項加框
 main_menu_record_page1_3_wait,//等按鈕
 main_menu_record_page1_3_data,//最後第2筆資料顯示
 main_menu_record_page1_3_data_wait,//等按鈕
 main_menu_record_page1_3_data_print,//列印紐加框
 main_menu_record_page1_3_data_back,//返回紐加框
 //info
 main_menu_information_page1,//顯示第一頁
 main_menu_information_page1_wait,//等按鈕,點選上下切頁,OK返回
 main_menu_information_page2,//顯示第二頁
 main_menu_information_page2_wait,//等按鈕,點選上下切頁,OK返回
 //BT,待測試
 main_menu_Blue_Tooth_setup_page,//顯示連接跟返回
 main_menu_Blue_Tooth_setup_page_wait,//上下選擇連接跟返回
 main_menu_Blue_Tooth_setup_page_reconnect,//顯示連接加框
 main_menu_Blue_Tooth_setup_page_reconnect_wait,//上下選擇,按OK開始連接,進入main_menu_Blue_Tooth_setup_page_reconnecting,
 main_menu_Blue_Tooth_setup_page_reconnecting,//顯示正在連接中,完成後進入
 main_menu_Blue_Tooth_setup_page_reconnect_sucess,//顯示已連接的SSID
 main_menu_Blue_Tooth_setup_page_back,//顯示返回加框
 main_menu_Blue_Tooth_setup_page_back_wait,//上下選擇,按OK進入main_menu_record_page1,
 //detacting
 detacting_progress_bar,//顯示請吹氣字樣
 detacting_progress_bar_wait,//等待吹氣,偵測基礎壓力值達標後進入detacting_progress_bar_detacting,
 detacting_progress_bar_detacting,//及時反饋壓力值對應進度條,吹氣壓力達標後進入analyzing,時限內未達標進入analyzing,
 detacting_fail,
 //analyzing
 analyzing,//顯示分析中
 analyzing_wait,//等待分析結果出來,依結果不同分別進入pass跟fail
 analyzing_pass,//顯示通過
 analyzing_pass_wait,//等待確認列印,此時可看讀數,按下按鈕後進入printing,
 analyzing_fail,//顯示不通過
 analyzing_fail_wait,//等待確認列印,此時可看讀數,按下按鈕後進入printing,
 //printing
 printing,//顯示列印
 //USB
 USB_connecting,
 //電量檢查,電壓低於3.1V時跳出,5秒後自動關機
 battery_LOW,
 
};
Page_Dispaly pages;


void setup() {
  Serial.begin(115200);                     // Start the serial monitor to see the results.
  char fileName[] = {__FILE__};
  Serial.println(fileName);               // Prints the name of the file the location this sketch is in.
  for (uint8_t i = 0; i < BUTTONCOUNT; ++i) {
    pinMode(BUTTONPIN[i], INPUT_PULLUP);  // Make the button pins inputs with the internal pull up resistor enabled.
  }
  switch(pages) {
    case welcome:
    Serial.println("Aculyzer~ welcome");
    pages=certification_check;
    case certification_check:
    Serial.println("certification_check");
    pages=initial;
    case initial:
    Serial.println("initial");
    pages=ready;
    
  }
}

void loop() {
  
  switch(pages){
   case  ready:
   Serial.println("ready");
   pages=ready_wait;
   break;

   case ready_wait:
   Serial.println("ready_wait");
   while(pressing==0){
     Buttons();   
   switch (pressing){
     case 1:pages=main_menu;
     break;
     case 2:pages=main_menu;
     break;
     case 3:pages=detacting_progress_bar;
     break;
   }
   }
   pressing=0;
   break;

  case main_menu:
  Serial.println("main_menu");
  pages=main_menu_wait;
  break;

  case main_menu_wait:
   Serial.println("main_menu_wait");
   while(pressing==0){
     Buttons();   
   switch (pressing){
     case 1:pages=main_menu;
     break;
     case 2:pages=main_menu;
     break;
     case 3:pages=detacting_progress_bar;
     break;
   }
   }
   pressing=0;
   break;

  case detacting_progress_bar:
  Serial.println("detacting_progress_bar");
  pages=detacting_progress_bar_wait;
  break;
  
  case detacting_progress_bar_wait:
   Serial.println("detacting_progress_bar_wait");
   while(pressing==0){
     Buttons();   
   switch (pressing){
     case 1:pages=main_menu;
     break;
     case 2:pages=main_menu;
     break;
     case 3:pages=detacting_progress_bar;
     break;
   }
   }
   pressing=0;
   break;
  }


 // Buttons(); 
  //Serial.printf ("%d\n",pressing);
  delay(100);

                       // Calls the function to read the button.
  // Your other code goes here, make sure it is non blocking (no delays, no loops that don't exit quickly)


}

/* This is the function that reads the state of the button, debounces it and prints to the serial monitor when it detects a press */
char Buttons(){
  #define buttonPressed LOW                             // When the button is pressed the input will be low, this is to remove the confusion this migth cause.
  uint32_t currentMillis = millis();                    // Millis times uses to debounce the button
  static uint32_t lastMillis[BUTTONCOUNT];              // Start of the debounce timeout for each button
  const uint32_t BOUNCETIMEOUT = 20;                    // Debounce time in milliseconds 
  bool currentButtonState[BUTTONCOUNT];                 // Holds the current state of each button
  static bool lastButtonState[BUTTONCOUNT];             // Holds the previous debounced state of the button
  uint8_t b;
  
  for (b = 0; b < BUTTONCOUNT; ++b) {
    currentButtonState[b] = digitalRead(BUTTONPIN[b]);        // Reads the current state of each button and saves the result
    if (lastButtonState[b] != currentButtonState[b]) {        // Checks to see if each button has been pressed or released, at this point each button has not been debounced
      if (currentMillis-lastMillis[b] >= BOUNCETIMEOUT) {   // Checks to see if the state of each button has been stable for at least bounceTimeout duration
        lastButtonState[b] = currentButtonState[b];           // At this point the button has been debounced, so save the last state
        if (currentButtonState[b] == buttonPressed) {         // The button might have been pressed or released, this make sure only presses are acted on, not releases
          //Serial.print ("Button ");
          switch (b){
            case 1: //Serial.print ("up");
                  return pressing = b;
                  //Serial.printf ("\n%d\n",b);
            break;
            case 2: //Serial.print ("down"); 
                  return pressing = b;
                  //Serial.printf ("\n%d\n",b);
            break;
            case 3: //Serial.print ("ok"); 
                  return pressing = b;
                  //Serial.printf ("\n%d\n",b);
            break;

            default: //Serial.print ("none");
                  return pressing = b;
                  //Serial.printf ("\n%d\n",b);
            }
                  
          //Serial.print (b);
          //Serial.println (" has been pressed");
        }
      }
    } else {
      lastMillis[b] = currentMillis;                         // Saves the current value of millis in last millis so the debounce timer for each button starts from current millis
    }
  }
}
esp:VIN
esp:GND.2
esp:D13
esp:D12
esp:D14
esp:D27
esp:D26
esp:D25
esp:D33
esp:D32
esp:D35
esp:D34
esp:VN
esp:VP
esp:EN
esp:3V3
esp:GND.1
esp:D15
esp:D2
esp:D4
esp:RX2
esp:TX2
esp:D5
esp:D18
esp:D19
esp:D21
esp:RX0
esp:TX0
esp:D22
esp:D23
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r