/*******************************************************************************
    PocketScreen "Control GPIO Output with Buttons" Example
    written by Florian Keller
    last changed 20 Nov 20

    Use the button next to the pin header to change the output value of a pin,
    select that pin with the other two buttons.
    Connect LEDs or similar components to the pins.
*******************************************************************************/

#include <PocketScreen.h>
PocketScreen pocketscreen = PocketScreen();

char *pinNames[] = {"D0", "D1", "D2", "D3", "D4", "A0", "A1", "A2"};
int pins[] = {D0, D1, D2, D3, D4, A0, A1, A2};

enum {ANALOG_OFF, ANALOG_QUARTER, ANALOG_HALF, ANALOG_THREE_QUARTER, ANALOG_FULL};

int currentPinSelected = 0;
int status[] = {LOW, LOW, LOW, LOW, LOW, 0, 0, 0};
int lastButtonTime;

void setup() {
    // init pocketscreen
    pocketscreen.begin();
    pocketscreen.setBitDepth(BitDepth16);
    pocketscreen.setFont(pocketScreen7pt);

    // the digital pins must be declared as output, while the analog pins must not
    for (int i = 0; i < 5; i += 1)
        pinMode(pins[i], OUTPUT);

    // print initial info
    printScreen();
}

void loop() {
    // block off any input for 250ms after a button was pressed
    if (millis() > lastButtonTime + 250) {
        // check if button is pressed
        if (!digitalRead(PIN_BUTTON_1) && currentPinSelected > 0) {
            // go down and remember time
            currentPinSelected -= 1;
            lastButtonTime = millis();
            
            // print new info
            printScreen();
        }
        else if (!digitalRead(PIN_BUTTON_0) && currentPinSelected < 7) {
            // go up and remember time
            currentPinSelected += 1;
            lastButtonTime = millis();

            // print new info
            printScreen();
        }
        else if (!digitalRead(PIN_BUTTON_2)) {
            // digital or analog pin?
            if (currentPinSelected < 5) {
                // digital: toggle HIGH and LOW
                if (status[currentPinSelected] == HIGH)
                    status[currentPinSelected] = LOW;
                else
                    status[currentPinSelected] = HIGH;

                // set pin value
                digitalWrite(pins[currentPinSelected], status[currentPinSelected]);
            } else {
                // analog: rotate value
                status[currentPinSelected] = status[currentPinSelected] + 1;
                if (status[currentPinSelected] > ANALOG_FULL)
                    status[currentPinSelected] = ANALOG_OFF;

                // set pin value (maximum analog value is 255)
                if (status[currentPinSelected] == ANALOG_OFF)
                    analogWrite(pins[currentPinSelected], 0);
                else if (status[currentPinSelected] == ANALOG_QUARTER)
                    analogWrite(pins[currentPinSelected], 64);
                else if (status[currentPinSelected] == ANALOG_HALF)
                    analogWrite(pins[currentPinSelected], 128);
                else if (status[currentPinSelected] == ANALOG_THREE_QUARTER)
                    analogWrite(pins[currentPinSelected], 192);
                else if (status[currentPinSelected] == ANALOG_FULL)
                    analogWrite(pins[currentPinSelected], 255);
            }
            
            // remember time
            lastButtonTime = millis();

            // print new info
            printScreen();
        }
    }
}

void printScreen() {
    // clear screen
    pocketscreen.clearScreen();

    // print top text
    pocketscreen.setFontColor(ORANGE_16b, BLACK_16b);
    pocketscreen.setCursor(48 - pocketscreen.getPrintWidth("Select a pin:")/2, 8);
    pocketscreen.print("Select a pin:");

    // print current pin name to screen
    pocketscreen.setFontColor(CYAN_16b, BLACK_16b);
    pocketscreen.setCursor(48 - pocketscreen.getPrintWidth(pinNames[currentPinSelected])/2, 24);
    pocketscreen.print(pinNames[currentPinSelected]);
    
    // and print its value
    pocketscreen.setFontColor(GREEN_16b, BLACK_16b);
    char strbuf[64];
    // digital or analog pin?
    if (currentPinSelected < 5) {
        // digital: put HIGH or LOW into string buffer
        if (status[currentPinSelected] == HIGH)
            sprintf(strbuf, "HIGH");
        else
            sprintf(strbuf, "LOW");
    } else {
        // analog: put value into string buffer
        int percent = (100 * status[currentPinSelected]) / ANALOG_FULL;
        sprintf(strbuf, "%i%%", percent);
    }
    pocketscreen.setCursor(48 - pocketscreen.getPrintWidth(strbuf)/2, 40);
    pocketscreen.print(strbuf);
    
    // print 'arrows' on left and right
    pocketscreen.setFontColor(CYAN_16b, BLACK_16b);
    pocketscreen.setCursor(16, 24);
    pocketscreen.print("<<");
    pocketscreen.setCursor(80 - pocketscreen.getPrintWidth(">>"), 24);
    pocketscreen.print(">>");
}
