#include <avr/io.h>
#include <util/delay.h>

//BUTTON PORTS
#define U PINC0
#define D PINC1
#define R PINC2
#define L PINC3
#define ENTER PINC4
#define RESET PINC5

#define MASK_LENGTH 8
uint16_t winningMask[] = {0b000000111, 0b000111000, 0b111000000, 0b001001001, 0b010010010, 0b100100100, 0b100010001, 0b001010100};

//LED PORTS
//PD0 PD1 PD2
//PD3 PD4 PD5
//PD6 PD7 PB0

void ledDisplay(uint8_t position);
void errorBeep(void);
int results (uint16_t playerOne, uint16_t playerTwo);

int main(void)
{
  //button ports
  DDRC  &= 0b11000000;
  PORTC |= 0b00111111;
  //LED ports
  DDRD = 0xff;
  DDRB |= 1;
  int8_t position = 0;
  uint8_t stateR = 0;
  uint8_t stateL = 0;
  uint8_t stateD = 0;
  uint8_t stateU = 0;
  uint8_t stateENTER = 0;
  uint8_t stateRESET = 0;
  uint8_t playerNumber = 1;
  uint16_t playerOne = 0b000000000;
  uint16_t playerTwo = 0b000000000;
  uint16_t isPlaced = 0b000000000;

  while (1)
  {

    if (((PINC & (1 << R)) == 0) && (stateR == 0))
    {
      position++;
      stateR = 1;
      if (position % 3 == 0)
      {
        position -= 3;
      }
    }
    else if ((PINC & (1 << R)) != 0)
    {
      stateR = 0;
    }


    if (((PINC & (1 << L)) == 0) && (stateL == 0))
    {
      position--;
      stateL = 1;

      if (position % 3 == 2)
      {
        position += 3;
      }
      else if (position < 0)
      {
        position = 2;
      }
    }
    else if ((PINC & (1 << L)) != 0)
    {
      stateL = 0;
    }

    if (((PINC & (1 << D)) == 0) && (stateD == 0))
    {
      position += 3;
      stateD = 1;

      if (position > 8)
      {
        position -= 9;
      }
    }
    else if ((PINC & (1 << D)) != 0)
    {
      stateD = 0;
    }

    if (((PINC & (1 << U)) == 0) && (stateU == 0))
    {
      position -= 3;
      stateU = 1;

      if (position < 0)
      {
        position += 9;
      }
    }
    else if ((PINC & (1 << U)) != 0) stateU = 0;


    if (((PINC & (1 << ENTER)) == 0) && (stateENTER == 0))
    {
      if ((isPlaced & (1 << position)) == 1)
      {
        // errorBeep();
      }
      else if ((isPlaced & (1 << position)) == 0)
      {
        isPlaced |= (1 << position);
        if (playerNumber == 1)
        {
          playerOne |= (1 << position);
          playerNumber = 2;
        }
        else if
        (playerNumber == 2)
        {
          playerTwo |= (1 << position);
          playerNumber = 1;
        }
      }
      stateENTER = 1;
    }
    else stateENTER = 0;

   
    ledDisplay(position, playerOne, playerTwo, results(playerOne, playerTwo));


  }
}

void ledDisplay(uint8_t position, uint16_t playerA, uint16_t playerB, uint8_t result)
{
  if (result == 0)
  {
    uint16_t ledToDisplay = playerA | (1 << position) | playerB;
    PORTD = ledToDisplay;
    PORTB = (ledToDisplay >> 8) & (1 << 0);
  }
  else if (result != 0)
  {
    PORTD = 0x00;
    PORTB = 0;
    PORTD |= (1 << result);
  }

}


int results (uint16_t playerOne, uint16_t playerTwo)
{
  for (uint8_t i = 0; i < MASK_LENGTH; i++)
  {
    if ((playerOne & winningMask[i]) == winningMask[i]) return 1; //Player One wins!
    else if ((playerTwo & winningMask[i]) == winningMask[i]) return 2; //Player Two wins!
    else if ((playerOne | playerTwo) == 0b111111111) return 3; //DRAW
  }
  return 0;

}



void errorBeep(void)
{

}