/*!
 * \file console.c
 * \brief
 *    A simple serial console implementation for out thermostat
 *
 * Author: Christos Choutouridis AEM: 8997
 * email : <cchoutou@ece.auth.gr>
 */
#include "console.h"

static char _buffer[COM_BUFFER_SIZE];
static int  _cursor;

static char _ans[512];

/*!
 * Parse and respond funcionality for serial console
 * \param buffer  Pointer to buffer
 */
void parse (char* buffer) {
   int i;
   float_t s;

   if ((strncmp((const void*)buffer, "help", 4) == 0) ||
       (strncmp((const void*)buffer, "?", 1) == 0) ) {
      i  = sprintf (_ans,     "\r\nThermostat commands:\r\n");
      i += sprintf (&_ans[i], "info              : Get information\r\n");
      i += sprintf (&_ans[i], "set Tset  <val>   : Set Thermostat\'s temperature\r\n");
      i += sprintf (&_ans[i], "set Thyst <val>   : Set Thermostat\'s hysteresis\r\n");
      i += sprintf (&_ans[i], "set Pset  <val>   : Set Proximity\r\n");
      i += sprintf (&_ans[i], "set Physt <val>   : Set Proximity\'s hysteresis\r\n");
      i += sprintf (&_ans[i], "set mode heating  : Set Thermostat to heating mode\r\n");
      i += sprintf (&_ans[i], "set mode cooling  : Set Thermostat to cooling mode\r\n");
      i += sprintf (&_ans[i], "\r\n");
      _ans[i] =0;
   }
   else if (strncmp((const void*)buffer, "info", 4) == 0) {
      i  = sprintf (_ans,     "\r\nThermostat data:\r\n");
      i += sprintf (&_ans[i], "Tcur   = %4.1f\r\n", temp_get_current ());
      i += sprintf (&_ans[i], "Tav    = %4.1f\r\n", app_data.Tav);
      i += sprintf (&_ans[i], "Mode   = %s\r\n", (settings.mode == HEATING) ? "Heating" : "Cooling");
      i += sprintf (&_ans[i], "Output = %s\r\n", (app_data.flag_output) ? "On" : "Off");
      i += sprintf (&_ans[i], "Tset   = %4.1f, Hyst = %4.1f\r\n", settings.Tset, settings.Thyst);
      i += sprintf (&_ans[i], "Pset   = %4.1f, Hyst = %4.1f\r\n", settings.Pset, settings.Physt);
      i += sprintf (&_ans[i], "\r\n");
      _ans[i] =0;
   }
   else if (strncmp((const void*)buffer, "set ", 4) == 0) {
      if (strncmp((const void*)&buffer[4], "Tset ", 5) == 0) {
         sscanf((const void*)&buffer[9], "%f", &s);
         if (s > -20 && s < 80) {
            settings.Tset = s;
            i = sprintf (_ans, "OK\r\n");
         }
         else
            i = sprintf (_ans, "Error\r\n");
         _ans[i] =0;
      }
      else if (strncmp((const void*)&buffer[4], "Thyst ", 6) == 0) {
         sscanf((const void*)&buffer[10], "%f", &s);
         if (s > 0 && s < 20) {
            settings.Thyst = s;
            i = sprintf (_ans, "OK\r\n");
         }
         else
            i = sprintf (_ans, "Error\r\n");
         _ans[i] =0;
      }
      else if (strncmp((const void*)&buffer[4], "Pset ", 5) == 0) {
         sscanf((const void*)&buffer[9], "%f", &s);
         if (s > 0 && s < 100)
            settings.Pset = s;
         i = sprintf (_ans, "OK\r\n");
         _ans[i] =0;
      }
      else if (strncmp((const void*)&buffer[4], "Physt ", 6) == 0) {
         sscanf((const void*)&buffer[10], "%f", &s);
         if (s > 0 && s < 50) {
            settings.Physt = s;
            i = sprintf (_ans, "OK\r\n");
         }
         else
            i = sprintf (_ans, "Error\r\n");
         _ans[i] =0;
      }
      else if (strncmp((const void*)&buffer[4], "mode ", 5) == 0) {
         if (strncmp((const void*)&buffer[9], "heating", 7) == 0) {
            settings.mode = HEATING;
            i = sprintf (_ans, "OK\r\n");
            _ans[i] =0;
         }
         else if (strncmp((const void*)&buffer[9], "cooling", 7) == 0) {
            settings.mode = COOLING;
            i = sprintf (_ans, "OK\r\n");
            _ans[i] =0;
         }
      }
      else {
         i = sprintf (_ans, "Error\r\n");
         _ans[i] =0;
      }
   }
   else {
      i = sprintf (_ans, "Error\r\n");
      _ans[i] =0;
   }
   COM_Transmit((uint8_t*)_ans, i);
}

/*!
 * A simple terminal with echo
 */
void console (void) {
   int ch;

   if (COM_CheckReceive()) {
      ch = COM_getchar();        // get character
      COM_putchar((char)ch);     // Echo back
      _buffer[_cursor++] = ch;   // store

      // Backspace, delete
      if (ch == 0x08 || ch == 0x7F)
            --_cursor;

      if (ch == 0 || ch == '\n' || ch == '\r') {
         COM_putchar('\n');     // Echo an extra '\n'
         _buffer[_cursor -1] = 0;
         _cursor =0;
         parse(_buffer);
      }
      if (_cursor >= COM_BUFFER_SIZE) {
         _buffer[_cursor -1] = 0;
         _cursor =0;
         parse(_buffer);
      }
   }
}

