#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <ArduinoJson.h>
#include "sprites.h" 

#define SCREEN_WIDTH 128 
#define SCREEN_HEIGHT 64 
#define OLED_RESET     -1 
#define SCREEN_ADDRESS 0x3C ///< see datasheet
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define BUTTON_FEED 5
#define BUTTON_PLAY 6
#define BUTTON_OTHER 7


float health = 100;
float hunger = 100;
float happiness = 100;
float discipline=100;
float weight=1;
float age=0;
bool isAlive = true; 
float money = 100; 
bool isSleep = false;
float sleepometer = 100; 
float poopometer = 0;

//menu:
int selected = 0;
int entered = -1;

int gameState = 0;  

unsigned long previousMillis = 0; 
unsigned long animationStartTime = 0;

bool timerLock1 = false;

byte actionType = 0;
int8_t actionTimer = 2; 


int spriteX = 64;
bool movingRight = true;


void setup() {
  Serial.begin(115200);

  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // loop forever
  }

  display.clearDisplay();
  display.setTextSize(1);           
  display.setTextColor(SSD1306_WHITE);      
  display.setCursor(0,0); 
  display.fillScreen(WHITE);
  display.println("Start");
  display.display();
 
  pinMode(BUTTON_FEED, INPUT_PULLUP);
  pinMode(BUTTON_PLAY, INPUT_PULLUP);
  pinMode(BUTTON_OTHER, INPUT_PULLUP);
  gameState = 2;
}

void loop() {
  unsigned long currentMillis = millis(); 
 
  if (currentMillis - previousMillis >= 1000) {
    previousMillis = currentMillis;
    Serial.print(F("Game state: "));
    Serial.print(gameState);
    Serial.print(F(" Entered: "));
    Serial.println(entered);
    Serial.print(F(" Selected: "));
    Serial.println(selected);
    lifeSimulation();
    
  }
  drawMainScreen();


}


void drawMainScreen() {
  if (gameState==2) {
    display.clearDisplay();
    display.setCursor(0,0);
    display.print("Toka");
    display.print("  ");
    display.write(0x03);
    display.print(int(health));
    //display.setCursor(0, 20);
    display.print("  ");
    display.write(0x04);
    display.print(int(hunger));
    display.print("  ");
    display.write(0x02);
    display.print(int(happiness));
    display.print("  ");
    display.write(0x24);
    display.print(int(money));
 

    
    moveSprite(); 
    drawSprite(); 

    
    handleButtons();
  } 
  if (gameState==1) {displaymenu();}
  
  if (gameState==3) {actionScreen();}
  display.display();

}


void handleButtons() {
  if (digitalRead(BUTTON_OTHER) == LOW) {
    
    hunger += 20;
    if (hunger > 100) {
     hunger = 100;
    }
    
  } else if (digitalRead(BUTTON_PLAY) == LOW) {
    happiness += 20;
    if (happiness > 100) {
     happiness = 100;
    }
   
  } else if (digitalRead(BUTTON_FEED) == LOW) {
    Serial.println(F("Button menu"));
    gameState =1;
    delay(50);
  }
}


void lifeSimulation() {
  
  if (isAlive) { 
    if (!isSleep) { 
      hunger-=0.002;
      if (poopometer<=100) {poopometer+=0.001;}
      if (happiness>=0) {happiness-=0.0001;}
      health-=age*0.0001+poopometer*0.01;
    }
    else {
      if (poopometer<=100) {poopometer+=0.0005;}
      if (happiness>=0) {happiness-=0.00005;}
      health-=age*0.0001+poopometer*0.01;
    }
    age+=0.0001;
  if (hunger<=0 || health<=0) {
    hunger=0;
    health=0;
    isAlive=false;
  }

  }


  
  if (hunger <= 0) {
    Serial.println(F("Dead"));
    gameState = 3;
    actionType = 8;  
    isAlive = false;
   
  }

  
}

void displaymenu(void) {
  const int menuLength = 10; 
  const int visibleItems = 6; 

  if (digitalRead(BUTTON_OTHER) == LOW) {
    entered = -1;
    if (selected > 0) {
      selected--;
    } else {
      selected = menuLength - 1; 
    }
    delay(20);
  } else if (digitalRead(BUTTON_FEED) == LOW) {
    selected++;
    if (selected >= menuLength) {
      selected = 0; 
    }
    delay(20);
  } else if (digitalRead(BUTTON_PLAY) == LOW) {
    entered = selected;
  } else if (digitalRead(BUTTON_OTHER) == LOW) {
    entered = -1;
  }


  const char *options[10] = { 
    " Close Menu ", 
    " Stat ", 
    " Feed ", 
    " Wash ",
    " Heal ",
    " Sleep ",
    " Play ",
    " Setup",
    " Save",
    " Reset"
  };

  int startIndex;
  int endIndex;

  switch (entered) {
    case -1: 
      display.clearDisplay();
      display.setTextSize(1);
      display.setTextColor(SSD1306_WHITE);

      display.drawRoundRect(0, 0, 58, 11, 3, WHITE);
      display.setCursor(2, 2);
      display.println(F("Main Menu"));
      display.setCursor(0, 12);
      //display.println("");

      
      startIndex = max(0, selected - (visibleItems - 1));
      endIndex = min(menuLength - 1, startIndex + visibleItems - 1);

      for (int i = startIndex; i <= endIndex; i++) {
        if (i == selected) {
          display.write(0x10); 
          display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
          display.println(options[i]);
        } else {
          display.setTextColor(SSD1306_WHITE);
          display.println(options[i]);
        }
      }
      break;

    case 0: 
      gameState = 2;
      entered = -1;
      selected = 0;
      break;

    case 1: 
      display.clearDisplay();
      //display.setTextSize(1);             
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(0, 0);
      display.println(F("Stat"));
      display.println("Name: Toka");
      display.setCursor(0, 20);
      display.write(0x03);
      display.print("Health: ");
      display.print(health);
      display.setCursor(0, 30);
      display.write(0x04);
      display.print("Hunger: ");
      display.print(hunger);
      display.setCursor(0, 40);
      display.write(0x02);
      display.print("Happiness: ");
      display.print(happiness);
      display.setCursor(0, 50);
      display.write(0x24);
      display.print("Money: ");
      display.print(money);
      break;

    case 2: 
      gameState = 3; 
      if (hunger <= 100) {
        actionTimer = 2; 
        actionType = 1; 
        hunger += 20.333;
        entered = -1;
        selected = 0;
      }
      else {
        actionTimer = 2; 
        actionType = 0; 
        entered = -1;
        selected = 0;
      }
      break;
      
      // entered = -1;
      // selected = 0;
  }
}



void actionScreen() {
  if (timerLock1==false) {
    animationStartTime = millis(); 
    timerLock1=true;
  }

    
    switch(actionType) {
      case 0: 
        display.clearDisplay();
        display.setTextColor(SSD1306_WHITE);
        display.setCursor(0,0);
        display.print("NO!");
        break;  
      case 1: 
        display.clearDisplay();
        display.setTextColor(SSD1306_WHITE);
        display.setCursor(0,0);
        display.print("Eating...");
        break;
      case 2: 
        // 
        break;
      case 3:

        break;
      case 4:

        break;
      case 5:

        break;
      case 6:

        break;
      case 7:

        break;
      case 8:
      
        break;
      // 
      default:
        gameState = 2;
        break;
    }

    // 
    if (millis() - animationStartTime >= actionTimer*1000) {
      gameState = 2; 
      timerLock1=false;
      }
  
}


void moveSprite() {
    
    if (movingRight) {
        spriteX++; 
        
        if (spriteX + 48 >= SCREEN_WIDTH) {
            movingRight = false; 
        }
    } else { 
        spriteX--; 
        
        if (spriteX <= 0) {
            movingRight = true; 
        }
    }
}


void drawSprite() {
    //display.clearDisplay();
    
    //display.display();
    if (movingRight) {
        display.drawBitmap(spriteX, 32, dinoWalk0, 48, 24, WHITE);
    } else {
        display.drawBitmap(spriteX, 32, dinoWalkInverted, 48, 24, WHITE);
    }
}