// include the library code:
#include "PlantInput.h"
#include "PlantMonitor.h"
#include <LiquidCrystal.h>

#include "tunes.h"


void setup() 
{
    Serial.begin(9600);
    // lcd screen, and pm
    PlIn::initPeriphs();
}

enum MonitorState
{
    Idle = 0, DataCollect = 1, RequestHelp = 2, AwaitHelp = 3
};
size_t cur_state = Idle;
unsigned long idle_timer = 0;


uint8_t issue_flag = 0;

// time before auto polling, we dont want to poll constantly
// because thats useless wear and tear on our system maybe.
#define IDLE_THRESH 5000

#define HELP_THRESH 50000



void StateMachine(size_t* state, unsigned long* idle_timer, uint8_t* issue_flag)
{
    unsigned long dt;
    PlIn::PlantPoll data;
    PlIn::lcd.clear();
    PlIn::face_to_lcd(*state, *issue_flag);
    PlIn::RequestHelpText(*issue_flag);
    switch(*state)
    {
        case Idle:
            dt = millis() - *idle_timer;
            if(dt > IDLE_THRESH)
            {
                *state = DataCollect;
            }
            break;
        case DataCollect:
            data = PlIn::pollPlant();
            *issue_flag = PlIn::IssueManager(data);
            if(*issue_flag)
            {
                cur_state = RequestHelp;
                break;
            }
            cur_state = Idle;
            *idle_timer = millis();

            break;
        case RequestHelp:
            PlIn::RequestHelp(*issue_flag);
            cur_state = AwaitHelp;
            *idle_timer = millis();
            break;
        case AwaitHelp:
            dt = millis() - *idle_timer;
            data = PlIn::pollPlant();
            *issue_flag = PlIn::IssueManager(data);
            if(!(*issue_flag))
            {
                *idle_timer = millis();
                cur_state = Idle;
                break;
            }
            else if(dt > HELP_THRESH)
            {
                cur_state = RequestHelp;
                break;
            }
            break;
    }
}


void loop() 
{
    // set the cursor to column 0, line 1
    // (note: line 1 is the second row, since counting begins with 0):
    PlIn::lcd.setCursor(0, 1);
    // print the number of seconds since reset:
    // PlIn::lcd.print(millis() / 1000);

    // StateMachine(&cur_state, &idle_timer, &issue_flag);
    // PlIn::print_state(cur_state, issue_flag, false);


    if (Serial.available()) 
    {
        char cmd = Serial.read();
        if (cmd == 'l') 
        {
            PlIn::pm.ledOff();
        }
        else if (cmd == 'L') 
        {
            PlIn::pm.ledOn();
        }
    }
    report();

    // PlIn::LCD_show_data();
    delay(200);
}



void report() {
    // Serial.print("Wetness: ");
    Serial.print(PlIn::pm.getWater());
    Serial.print(" temp (F): ");
    Serial.print(PlIn::getTemp());
    Serial.print(" light: ");
    Serial.println(PlIn::getLight());
}