/* Copyright 2025 by COG9 Enterprises LLC
 * All rights reserved.
 * Title: screens.ino
 * Author: Jed Marti KI7NNP
 * Description: Screen display control.
 * Created: Sun Oct 12 07:01:27 2025
 * Revision History:
 */

#include <stdint.h>
#include "powerard.h"
#include "screens.h"
#include "mcp9808.h"
#include "eepromconst.h"

// Configuration
extern eePROMValues E;

// Which screen is showing.
int8_t   whichScreen = 0;
uint32_t whenLastShown = 0;

// The three error message lines.
static char msg1[23];
static char msg2[23];
static char msg3[23];

void startPageScreen(void)
/*     Start up screen. This shows up after the scrolling. Then you're allowed to scroll through
 *   displays using the push buttons.
 * Parameters: none
 * External References:
 *   VERSION, RELEASE, PATCH: from powerard.h
 * Returned values: none
 * Errors detected: none
 */
{
  char msg[32];
  
  display.clearDisplay();
  display.setCursor(10, 0);
  display.setTextSize(2);
  display.print("POWERARD");

  display.setTextSize(1);

  display.setCursor(0, 17);
  if (E.eeOwner[0] != 0) display.print(E.eeOwner);
  sprintf(msg, " V%d.%02d.%03d", VERSION, RELEASE, PATCH);
  display.print(msg);
  
  display.setCursor(15, 28);
  display.print("Copyright 2026");
  display.setCursor(0, 39);
  display.print("COG9 Enterprises LLC");

  batteryIcon();
}



void showScreen(void)
/*     Update the screen with whatever number we're working with. Put the date and tme at
 *   the bottom.
 * Parameters: none
 * External References:
 *   whenLastShown: Time in milliseconds from when last shown. This is used to cause the
 *     screen to be updated periodically.
 *   whichScreen: Which of multiple screens to show.
 *   ...Page: An enumeration from screens.h.
 * Returned values: none
 * Errors detected: none
 */
{
  char msg[22];
  // Update screen every so often.
  whenLastShown = millis();
  //  Serial.print("showScreen "); Serial.println(whichScreen);

  // The two switches increment/decrement whichScreen.
 again:
  switch(whichScreen) {
  case startPage: startPageScreen(); break;
  case powerPage: powerPageScreen(); break;
  case tempPage: tempPageScreen(); break;
  case errorPage: errorScreen(); break;
  case maAPage: graph16(&maA); break;
  case maBPage: graph16(&maB); break; 
  case maCPage: graph16(&maC); break;
  case TAPage: graph8(&TA); break;
  case TBPage: graph8(&TB); break;
  case TCPage: graph8(&TC); break;
  case TAUXPage: graph8(&TAUX); break;
  case BATPage: graphF(&BAT); break;
  }

  // Put date/time on bottom.
  ctime(msg);
  display.setCursor(0, 55);
  display.print(msg);

  display.display();
}



void nextScreen(void)
/*     Push button to go to the next page. Caused by interrupt.
 * Parameters: none
 * External References:
 *   whichScreen: Which of multiple screens to show. Incremented and wrapped around.
 *   lastPage: The number of the last page (constant).
 * Returned values: none
 * Errors detected: none
 */
{
  // Move to next screen.
  if (++whichScreen > lastPage) whichScreen = startPage;

  // Find the next page. For the graphics, we have to ignore screens that show sensors 
 again:
  switch(whichScreen) {
  case maBPage:
    if (!isOK(MB))
    {
      whichScreen = maCPage;
      break;
    }
    else return;
  case maCPage:
    if (!isOK(MC))
    {
      whichScreen = TAPage;
      break;
    }
    else return;
  case TAPage:
    if (aTemp_i2c == 0)
    {
      whichScreen = TBPage;
      break;
    }
    else return;
  case TBPage:
    if (bTemp_i2c == 0)
    {
      whichScreen = TCPage;
      break;
    }
    else return;
  case TCPage:
    if (cTemp_i2c == 0)
    {
      whichScreen = TAUXPage;
      break;
    }
    else return;
  case TAUXPage:
    if (auxTemp_i2c == 0) whichScreen = BATPage;
    return;
  default: return;
  }
  goto again;
}




void prevScreen(void)
/*     Push button to go to the previous page. Caused by interrupt.
 * Parameters: none
 * External References:
 *   whichScreen: Which of multiple screens to show. Decremented and wrapped around.
 *   lastPage: The number of the last page (constant).
 * Returned values: none
 * Errors detected: none
 */
{
  char msg[22];

  // Move to next screen.
  if (--whichScreen < 0) whichScreen = lastPage;

  // Find the previous page. For the graphics, we have to ignore screens that show sensors 
 again:
  switch(whichScreen) {
  case maBPage:
    if (!isOK(MB))
    {
      --whichScreen;
      break;
    }
    else return;
  case maCPage:
    if (!isOK(MC))
    {
      --whichScreen;
      break;
    }
    else return;
  case TAPage:
    if (aTemp_i2c == 0)
    {
      --whichScreen;
      break;
    }
    else return;
  case TBPage:
    if (bTemp_i2c == 0)
    {
      --whichScreen;
      break;
    }
    else return;
  case TCPage:
    if (cTemp_i2c == 0)
    {
      --whichScreen;
      break;
    }
    else return;
  case TAUXPage:
    if (auxTemp_i2c == 0)
    {
      --whichScreen;
      break;
    }
    else return;

  default: return;
  }
  goto again;

}


void errorMessage(char *m1, char *m2, char *m3)
/*     Some sort of error condition has occurred. We display 3 lines and force the display to
 *   this page.
 * Parameters:
 *  m1, m2, m3: Strings for the 3 lines or NULL for blank.
 * External References:
 *   whichScreen: We'll force it to this page for at least one iteration.
 *   errorPage: indicates the error page (constant)
 * Returned values: none
 * Errors detected: none
 */
{
  if (m1) strncpy(msg1, m1, 23);
  else m1[0] = 0;

  if (m2) strncpy(msg2, m2, 23);
  else m2[0] = 0;

  if (m3) strncpy(msg3, m3, 23);
  else m3[0] = 0;

  // We have an error, force.
  whichScreen = errorPage;

  batteryIcon();
}



void clearErrorMessages(void)
{
  msg1[0] = msg2[0] = msg3[0] = 0;
}



void errorScreen(void)
{

  display.clearDisplay();
  display.setCursor(0, 0);
  display.setTextSize(2);
  display.print("  ERROR");

  display.setTextSize(1);
  display.setCursor(0, 17);
  display.print(msg1);
  display.setCursor(0, 27);
  display.print(msg2);
  display.setCursor(0, 37);
  display.print(msg3);
}



void initScreens(void)
/*     Set up the screens.
 */
{
  // Clear error messages.
  clearErrorMessages();

  // Start page.
  whichScreen = startPage;

  // We update each screen after some time.
  whenLastShown = millis();

  // Show start splash screen.
  showScreen();
}


// EOF
