/*
*Arduino Bomb wireless 2 way transmittion code
* Lucas Dahl
*/

// ARDUINO FOR BOMB ONE BY ROUND TABLE

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include<EEPROM.h>
#include "Arduino.h"
#include "Keypad.h"

     byte pipeNum = 0;
    int buttonStatet  = 0;
int buzzer = A11;
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {26, 25, 24, 23}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {29, 28, 27}; //connect to the column pinouts of the keypad
int timers = 0;
int finalcheck = 0;
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

#define button 4
RF24 radio(7, 8); // CE, CSN
const byte address[][6] = {"00001","00002","00003","00004"};
int dummy =0;
int lift =0;
int timer = 0;
int newtimer = 0;
//variables for buttons and their pin outputs
// the 4 small sqare buttons and their input states
int squareButton[] = {0,0,0,0,0};
int squarecheck = 0;
int othercheck = 0;
int largeSquares[] = {30,31,32,33,34};
int largecount = 0;
// the small square buttons and their pins
int squareBut[] = {0,0,0,0};
int test = 0;
int smallSquares[] = {37,35,38,36};
int smallcheck = 0;
int othersmall = 0;
int smallcount = 0;


//---------------------------------motion stuff
int motion = 39;
int motionsensor = 0;
int pirstate = LOW;
int motiontimer = 0;

//button states are the signals from both bombs, if a button is pressed
// the button is multiplied by a prime number and the other bomb reads
// the signal
int buttonState = 0;
//button states is the other bomb side
int buttonStates = 0;


// count is an array that will keep counts for when things are solved
int count[] = {0,0,0,0,0};



//the array to check when everything is satisfied
int finish[] = {0,0,0,0,0,0,0};
//the true or false state for the large and small buttons
int butState[] ={0,0,0,0,0,0,0,0,0,0,0};
int lastbutState[] ={0,0,0,0,0,0,0,0,0,0,0};


//----------------------------------------------------hold stuff
// pin values for the hold and number large buttons
int hold = 40;
// hold state reads if button is held
int holdState[] = {0,0};


//-------------------------------mic stuff
int mic = A13;
int micsensor = 0;
int miccount[] = {0,0};

//--------------------------- random led stuff
int randone =0;
int randtwo = 0;
int randleds[] = {A0,A1,A2,A3,A4,A5,A6,A7,A8,A9};
int randint = 0;
int placeholder = 0;

//------------------------------number button stuff
//int counterleds[] = {53,49,2,3,4,5,6,9,10,11};
int counterleds[] = {6,10,9,4,2,49,3,53,5};
int countertimer= 0;
int countercount =0;
int num = 41;
// reads if the number is read correctly.
int numstate[] = {0,0};
int numcheck[] = {LOW,HIGH,0};

//------------------------------password stuff
int k = 0;
int password[4];
int pass[4] = {50,48,48,50};

//------------------------------final stuff
int finalleds[] ={42,43,44,45,46,47,48};
int finalcount = 0;
int finalcheckk = 0;
int timertwo = 0;
int timerthree = 0;
int randtest=0;
int i = 0;

//--------------------------------------------------------------------------SETUP-----------------------------------------------------------------------
void setup() {

  pinMode(buzzer, OUTPUT);
  digitalWrite(buzzer,HIGH);
  for (int i=0; i<10; i++){
  pinMode(randleds[i], OUTPUT);
  }
  pinMode(12, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(hold, INPUT);
  pinMode(num, INPUT);
  for(int j = 0;j<4;j++){
  pinMode(smallSquares[j], INPUT);
  }
    for(int j = 0;j<12;j++){
  pinMode(counterleds[j], OUTPUT);
  digitalWrite(counterleds[j],LOW);
  }
      for(int j = 0;j<7;j++){
  pinMode(finalleds[j], OUTPUT);
  digitalWrite(finalleds[j],LOW);
  }
  for(int j = 0;j<4;j++){
  pinMode(largeSquares[j], INPUT);
  }
  pinMode(motion, INPUT);
  pinMode(hold, INPUT);
  pinMode(num,INPUT);
  pinMode(A15,OUTPUT);
  digitalWrite(A15,LOW);
  Serial.begin(9600);
  radio.begin();
  //opens up the channel to communicate between radios
  radio.openWritingPipe(address[2]);
  //reads safety send and sends to podium
  radio.openReadingPipe(0, address[3]); 
 
  radio.setPALevel(RF24_PA_MIN);


  
}
//                  Reads from Safetysend sends to podium
//============================================================================================LOOP=====================================================================================
void loop() {
 
//**********************************SENDING RADIO HERE*******************************************
   delay(5);
   radio.stopListening();
 //----------------------------------------------------------------Rand LEDS CODE----------------------------------------------------------------------------------
   numstate[0] = digitalRead(num);
   //Serial.println(numstate[0]);
   timertwo = millis();
   if ((timertwo - randtest) > 50){
    digitalWrite(randleds[placeholder],LOW);
    randtest = millis();
    randint = random(0,10);
    digitalWrite(randleds[randint],HIGH);
    placeholder = randint;
   }

   //-----------------------------------------------------------part 2 number button test-------------------------------------------------------------------------
   if (bitRead(buttonState,2) !=1){
      numstate[0] = digitalRead(num);
      if(countercount != 0 && countercount %2==0 && numstate[0] == 1 && numcheck[2]==0){
         numcheck[0]=HIGH;
         numcheck[1]=LOW;
         numcheck[2]=1;
         countercount = 1;
         for (int i=0; i<10; i++){
           digitalWrite(counterleds[i],LOW);
         }
         numstate[0]=0;
         //Serial.println("yup");
       }
       if(numcheck[2] == 1 && countercount > 7 ){
         numcheck[2] =2;
       }        
       if(numcheck[2]==2 && countercount == 7 && numstate[0]==1){
         //Serial.println("led 1 set");
         finalcount++;
         Serial.println("number");
         bitWrite(buttonState,2,1);
         for (int i=0; i<10; i++){
            digitalWrite(counterleds[i],LOW);
         }
       }
       if(countercount%2!=0 && numstate[0]==1 && bitRead(buttonState,2) !=1 && numcheck[2] !=3 && numcheck[2] !=1){
         numcheck[0]=LOW;
         numcheck[1]=HIGH;
         numcheck[2]=3;
         countercount = 0;
         for (int i=0; i<10; i++){
            digitalWrite(counterleds[i],LOW);
         }
         numstate[0]=0;
         //Serial.println("nope");
       } 
       if(numcheck[2] == 3 && countercount > 7 ){
         numcheck[2] =0;
       } 
   }
 
   //----------------------------------------------------------------Part 2 Number button counter-------------------------------------------------------------------------------
   if ((timertwo - countertimer) > 1000 && bitRead(buttonState,2) !=1){
    digitalWrite(counterleds[countercount],numcheck[1]);
    digitalWrite(counterleds[countercount - 1],numcheck[0]);
    countercount++;
   //Serial.println(countercount);
   if(countercount == 1){
    digitalWrite(counterleds[8],numcheck[0]);
   }
    if(countercount > 8){
      countercount =0;
    }
    countertimer = timertwo;
   }

   //--------------------------------------------------------------part 5 keypad-------------------------------------------------------------------------------------------------
   if(bitRead(dummy,5)!=1){
      char key = keypad.getKey();
      if(key)  // Check for a valid key.
      {
        password[k]= key;
        //smallbeep();
        k++;
        Serial.print(key);
      if(k>3)
      {
         for (int j=0;j<4;j++){
          //Serial.println(password[j]);
          //Serial.print(pass[j]);
          if (password[j] == pass[j]){
            count[2]++;
            
          }
          else{
            count[2]=0;
             smallbeep();
  //           smallbeep();
    //         smallbeep();
             k =0;
          }
          //Serial.println(count[2]);
         }
          //bitWrite(buttonState,5,1);
          //finalcount++;
         }
       if(count[2] == 4){
          bitWrite(dummy,5,1);
          finalcount++;
          Serial.println("Keypad");  
          //Serial.println(count[2]);
          //Serial.println("keypad");      
       }
      }
   }
  
//----------------------------------------------------------------part 6 small buttons-------------------------------------------------------------------------------------------
if(bitRead(buttonState,6)!=1){
 for (int m=0;m<4;m++){
    squareBut[m] = digitalRead(smallSquares[m]);
    //Serial.print(m);
    //Serial.print(":");
    //Serial.println(squareBut[m]);
     }
   if(smallcheck == 0){
   //tests each button except for the button that is next in the sequence and if any are pressed it will restart largecount
   for (int m=0;m<4;m++){
      if (m != smallcount){
        //skip so it doesn't check the button it is on 
        if (squareBut[m]==1){
          //if any fail it will reset the smallbutton section
          smallcount =0;
          smallcheck =0;
          bitWrite(buttonState,10,1);
           bitWrite(buttonState,9,0);
         // Serial.println("fail here");
          othersmall = 0;
        }
      }
      //if it is the button that is next it will skip it in the sequence, make sure this is at the end of the loop or it will test outside of the array
      if(m == smallcount){
        m++;
      }
    }
    //Serial.println(bitRead(buttonState,9));
    //makes sure the other room checked the next button
    if(bitRead(buttonStates,9)==1 && othersmall ==0){
      othersmall++;
      bitWrite(buttonState,9,0);
    //  Serial.println("otherroom pass");
    }    
    //if the next button is pressed, if it is the first button, and tests only if the other room past
    if(squareBut[smallcount]==1 && (othersmall == 1 || smallcount ==0)){
      smallcount++;
      beep();
      bitWrite(buttonState,9,1);
      bitWrite(buttonState,10,0);
      //Serial.println(smallcount);
      smallcheck =1;
      othersmall =0;
    //  Serial.println("passed");
    }

    //if the other room fails it resets everything including the fail test for this room
    if(bitRead(buttonStates,10)==1){
      smallcount =0;
      smallcheck =0;
      bitWrite(buttonState,10,0);
      bitWrite(buttonState,9,0);
     // Serial.println("otherroom failed");

    }
  }
  //this is what resets the smallcheck when the button is released
  if(smallcount == 0 || (smallcheck == 1 && squareBut[smallcount -1] == 0)){
    smallcheck =0;
    bitWrite(buttonState,10,0);
    //Serial.println("zeroed");
  }
  //when it reaches the last button in the series it activates
  if(smallcount > 3){
    finalcount ++;
    bitWrite(buttonState, 6,1);
    Serial.println("Small Square");
  }
  if(bitRead(buttonStates,6) == 1 && squareBut[3] ==1){
    finalcount ++;
    bitWrite(buttonState, 6,1);
    Serial.println("Small Square");
  }
}
//-------------------------------------------------------------------part 7 Large Buttons---------------------------------------------------------------------------------------

// This if statement shuts off the large buttons when it is completed
if(bitRead(buttonState,7)!=1){
  //Reads the five buttons if they are pushed or not, there is also a serial print incase an individual button needs to be identified
  for (int m=0;m<5;m++){
    squareButton[m] = digitalRead(largeSquares[m]);
    //Serial.print(m);
    //Serial.print(":");
    //Serial.println(squareButton[m]);
  }
  //the squarecheck function makes sure that the button is released before it checks again or else it will trigger again.
  if(squarecheck == 0){
   //tests each button except for the button that is next in the sequence and if any are pressed it will restart largecount
   for (int m=0;m<5;m++){
      if (m != largecount){
        //skip so it doesn't check the button it is on 
        if (squareButton[m]==1){
          //if any fail it will reset the largebutton section
          largecount =0;
          squarecheck =0;
          bitWrite(buttonState,14,1);
          bitWrite(buttonState,13,0);
          //Serial.println("fail large button");
          othercheck =0;
    
        }
      }
      //if it is the button that is next it will skip it in the sequence, make sure this is at the end of the loop or it will test outside of the array
      if(m == largecount){
        m++;
      }
    }
        if(bitRead(buttonStates,13)==1 && othercheck ==0){
      othercheck++;
      bitWrite(buttonState,13,0);
     // Serial.println("otherroom pass");
    }
    //if the next button is pressed, if it is the first button, and tests only if the other room past
    if(squareButton[largecount]==1 && (othercheck == 1 || largecount ==0)){
      largecount++;
      bitWrite(buttonState,13,1);
      bitWrite(buttonState,14,0);
      //Serial.println(largecount);
      //Serial.println("next button");
      squarecheck =1;
      othercheck =0;
      beep();
    }
    //Serial.println(bitRead(buttonStates,13));
    //makes sure the other room checked the next button

    //if the other room fails it resets everything including the fail test for this room
    if(bitRead(buttonStates,14)==1){
      largecount =0;
      squarecheck =0;
      bitWrite(buttonState,14,0);
      bitWrite(buttonState,13,0);
     // Serial.println("otherroom fail");
    }
  }
  //this is what resets the squarecheck when the button is released
  if(largecount == 0 || (squarecheck == 1 && squareButton[largecount -1] == 0)){
    squarecheck =0;
    bitWrite(buttonState,14,0);
    //Serial.println("zeroed");
  }
  //when it reaches the last button in the series it activates
  if(largecount > 4 || bitRead(buttonStates, 7) ==1){
    finalcount ++;
    bitWrite(buttonState, 7,1);
    Serial.println("LARGE SQUARE PASS");
    
  }
}
//-------------------------------------------------------------------------------part 3 motion sensor-------------------------------------------------------------------------- 
  if( bitRead(buttonState,3)!=1){
    //Serial.println(motiontimer);
     motionsensor = digitalRead(motion);  // read input value
     //Serial.println(motionsensor);
     if (motionsensor == HIGH) {            // check if the input is HIGH
       if (pirstate == LOW) {
         pirstate = HIGH;
         motiontimer = timertwo;
         count[1] =0;
       }
     } else {
       if (pirstate == HIGH){
         pirstate = LOW;
         count[1] = 0;
       }
       if (pirstate == LOW && timertwo - motiontimer > 3000){
        count[1]++;
        motiontimer = timertwo;
        //Serial.println(count[1]);
       }
       if (count[1] >90){
          bitWrite(buttonState,3,1);
          finalcount++;
          Serial.println("motionsensor");
       }    
     }
  }
//----------------------------------------------------------------------------------part 4 nock knnock----------------------------------------------------------------------------------
if(timertwo > 5000){
  timers = 1;
}
 if(bitRead(buttonState,4)!=1 && timers == 1){
     micsensor = analogRead(mic);
     Serial.println(micsensor);
     //Serial.println(micsensor);
     if(micsensor < 10 && miccount[1] == 0){
        miccount[0]++;
        miccount[1] = 1;
        //Serial.println(miccount[0]);
         timer = millis();
     }
    if(micsensor < 10 && miccount[1] == 1){
        miccount[0]++;
        miccount[1] = 1;
        Serial.println(miccount[0]);

     }

    if(miccount[1] == 1 && (timertwo - timer  < 30000) && miccount[0] > 10){
         bitWrite(buttonState,4,1);
         finalcount++;
         Serial.println("Knock Knock");
     }
     if(miccount[1] ==1 && timertwo - timer > 30000){
      miccount[0] =0;
      miccount[1]= 0;
      timer = millis();
     }
 }
 //----------------------------------------------------------------------------------------part 1 hold--------------------------------------------------------------------------------------
  if(bitRead(buttonState,1)==1){
  bitWrite(buttonState,1,1);
 }
 if(bitRead(buttonState,1)!=1){
 holdState[0] = digitalRead(hold);
 if (holdState[0] == HIGH ){
  if(bitRead(buttonState,8)!=1){
  bitWrite(buttonState, 8, 1);
  }
 }
 else{
  holdState[1] = timertwo;
  if(bitRead(buttonState,8)==1){
   bitWrite(buttonState, 8, 0);
  }
 }
 if ( (holdState[0]== HIGH && bitRead(buttonStates,8)==1 && timertwo - holdState[1] > 30000)|| bitRead(buttonStates,1) ==1){
    Serial.println("HOLD");
    bitWrite(buttonState,1,1);
    finalcount++;
 }
}

 //-------------------------------------------------------------------------------------------final leds------------------------------------------------------------------------------------
if (finalcount >0){
  digitalWrite(finalleds[finalcheckk],HIGH);
  finalcount = 0;
  beep();
  finalcheckk++;
}
if(finalcheckk >6){
  bitWrite(buttonState, 12, 1);
}
else{
  bitWrite(buttonState, 12, 0);
}
 //Serial.println(buttonState);
 radio.write(&buttonState, sizeof(buttonState));
//channel 2

//****************************************LISTENING HERE******************************************  


 radio.startListening();
   
 
    if (radio.available()){ 

     radio.read(&buttonStates, sizeof(buttonStates));
     //Serial.print("address[0]:  ");
     //Serial.println(bitRead(buttonStates,15));
    }


//Serial.println(bitRead(lift,1));  
if (bitRead(buttonStates,15)==1){
  bitWrite(buttonState,15,1);
  digitalWrite(12,LOW);
  Serial.println("HELLO");
}
if (bitRead(buttonStates,15)==0){
  bitWrite(buttonStates,15,0);
  digitalWrite(12, HIGH);
  Serial.println("BYE");
  for (int m=0;m<18;m++){
    bitWrite(buttonStates,m,0);
    bitWrite(buttonState,m,0); 
    finalcheckk=0;
    digitalWrite(finalleds[m],LOW);
    numcheck[2]=0;
    countercount =0;
    numstate[0]=0;
    k = 0;
    smallcheck =0;
    smallcount =0;
    squarecheck =0;
    largecount =0;
    count[1] = 0;
    miccount[0] =0;
    miccount[1]= 0;
    dummy = 0;
     timer = millis();
  }
}

  if(bitRead(buttonStates,5) == 1 && bitRead(dummy, 2) == 0){
    Serial.println("countEr");
    bitWrite(buttonState,5,1);
    finalcount++;
    bitWrite(dummy, 2,1);
  }
  if(bitRead(buttonStates,5) ==0){
    bitWrite(buttonState,5,0);
    bitWrite(dummy,2,0);
  }
  }
  //Serial.println(buttonStates);
  //Serial.println(buttonState);
  
  
void beep(){
  digitalWrite(buzzer,LOW);
  delay(20);
  digitalWrite(buzzer,HIGH);
}

void smallbeep(){
  digitalWrite(buzzer,LOW);
  delay(10);
  digitalWrite(buzzer,HIGH);
}
