void Controller::event_neverdim(const char *event,const char *value) {
    if(m_never_dim == false) {
      flashstorage_keyval_set("NEVERDIM","true");
      tick_item("Never Dim" ,true);
      m_never_dim=true;
    } else {
      flashstorage_keyval_set("NEVERDIM","false");
      tick_item("Never Dim" ,false);
      m_never_dim=false;
    }
}
void Controller::event_cpm_cps_auto(const char *event,const char *value) {
    if(m_cpm_cps_switch == false) {
      m_cpm_cps_switch = true;
      flashstorage_keyval_set("CPMCPSAUTO","true");
      tick_item("CPM/CPS Auto",true);
    } else {
      m_cpm_cps_switch = false;
      flashstorage_keyval_set("CPMCPSAUTO","false");
      tick_item("CPM/CPS Auto",false);
    }
}
void serial_setkeyval_run(char *line) {

  char key[200];
  char val[200];

  int eqpos=-1;
  int len=strlen(line);
  for(int n=0;n<len;n++) {
    if(line[n] == '=') {
      eqpos = n;
    }
  }
  
  if(eqpos==-1) return;

  for(int n=0;n<eqpos;n++) {
    key[n]=line[n];
    key[n+1]=0;
  }

  eqpos+=1;
  for(int n=eqpos;n<=len ;n++) {
    val[n-eqpos]=line[n];
    val[n-eqpos+1]=0;
  }
  
  flashstorage_keyval_set(key,val);
}
/**
 * Debug: sets a setting (key/value) / part 2
 */
void serial_setkeyval_run(char *line) {

  char key[200];
  char val[200];

  int eqpos=-1;
  int len=strlen(line);
  for(int n=0;n<len;n++) {
    if(line[n] == '=') {
      eqpos = n;
    }
  }

  if(eqpos==-1) return;
  if(eqpos==0) {		// = on a line ends the command
    flashstorage_keyval_update();
    command_stack_pop();
    return;
  }
  for(int n=0;n<eqpos;n++) {
    key[n]=line[n];
    key[n+1]=0;
  }

  eqpos+=1;
  for(int n=eqpos;n<=len ;n++) {
    val[n-eqpos]=line[n];
    val[n-eqpos+1]=0;
  }

  flashstorage_keyval_set(key,val);
}
void serial_setdevicetag_run(char *line) {

  char devicetag[100];

  sscanf(line,"%s\r\n",&devicetag);

  flashstorage_keyval_set("DEVICETAG",devicetag);
}
void Controller::event_save_pulsewidth(const char *event,const char *value) {
  int p1 = m_gui->get_item_state_uint8("PULSEWIDTH1");
  char sp[50];
  sprintf(sp,"%d",p1);
  flashstorage_keyval_set("PULSEWIDTH",sp);
  system_geiger->set_pulsewidth(p1);
  system_geiger->pulse_timer_init();
  m_gui->jump_to_screen(0);
}
void Controller::event_save_brightness(const char *event,const char *value) {
    uint8 b = m_gui->get_item_state_uint8("BRIGHTNESS");

    int br;
    if(b<= 5) br = (b*2) +1;
    if(b>  5) br = b+6;
    display_set_brightness(br);

    char sbright[50];
    sprintf(sbright,"%u",br);
    flashstorage_keyval_set("BRIGHTNESS",sbright);

    m_dim_off=false;
    m_gui->jump_to_screen(0);
}
void Controller::event_save_utcoff(const char *event,const char *value) {
    int h1 = m_gui->get_item_state_uint8("OFFHOUR1");
    int h2 = m_gui->get_item_state_uint8("OFFHOUR2");
    int m1 = m_gui->get_item_state_uint8("OFFMIN1");
    int m2 = m_gui->get_item_state_uint8("OFFMIN2");

    int utcoffset = (((h1*10)+h2)*60) + (m1*10) + m2;
    if(m_gui->get_item_state_uint8("SIGN:-,+,") == 0) {
      utcoffset = 0-utcoffset;
    }
    realtime_setutcoffset_mins(utcoffset);

    char sutcoffset[50];
    sprintf(sutcoffset,"%d",utcoffset);
    flashstorage_keyval_set("UTCOFFSETMINS",sutcoffset);

    m_gui->jump_to_screen(0);
}
void Controller::save_loginterval() {
  int l1 = m_gui->get_item_state_uint8("LOGINTER1");
  int l2 = m_gui->get_item_state_uint8("LOGINTER2");
  int l3 = m_gui->get_item_state_uint8("LOGINTER3");
  int32_t log_interval_mins = (l1*100) + (l2*10) + l3;
  m_log_interval_seconds = log_interval_mins*60;

  char sloginterval[50];
  sprintf(sloginterval,"%"PRIu32"",m_log_interval_seconds);
  flashstorage_keyval_set("LOGINTERVAL",sloginterval);
  uint32_t current_time = realtime_get_unixtime();

if(m_log_interval_seconds > 0){
  rtc_set_alarm(RTC,current_time+m_log_interval_seconds);
}else{
     rtc_disable_alarm(RTC);
}

  m_gui->jump_to_screen(0);

}
void Controller::save_warncpm() {
  m_warning_raised = false;
  int w1 = m_gui->get_item_state_uint8("WARNCPM1");
  int w2 = m_gui->get_item_state_uint8("WARNCPM2");
  int w3 = m_gui->get_item_state_uint8("WARNCPM3");
  int w4 = m_gui->get_item_state_uint8("WARNCPM4");
  int w5 = m_gui->get_item_state_uint8("WARNCPM5");

  int32_t warn_cpm = 0;
  warn_cpm += w1*10000;
  warn_cpm += w2*1000;
  warn_cpm += w3*100;
  warn_cpm += w4*10;
  warn_cpm += w5*1;

  m_warncpm = warn_cpm;

  char swarncpm[50];
  sprintf(swarncpm,"%"PRIi32"",warn_cpm);
  flashstorage_keyval_set("WARNCPM",swarncpm);

  m_gui->jump_to_screen(0);
}
void Controller::event_rem(const char *event,const char *value) {
  flashstorage_keyval_set("SVREM","REM");
  tick_item("\x80Sv" ,false);
  tick_item("\x80R",true);
}
void Controller::event_geiger_beep(const char *event,const char *value) {
  system_geiger->toggle_beep();
  if(system_geiger->is_beeping()) { flashstorage_keyval_set("GEIGERBEEP","true");  tick_item("Geiger Beep",true);  }
                       else { flashstorage_keyval_set("GEIGERBEEP","false"); tick_item("Geiger Beep",false); }
}
void Controller::event_english(const char *event,const char *value) {
    m_gui->set_language(LANGUAGE_ENGLISH);
    flashstorage_keyval_set("LANGUAGE","English");
    tick_item("English" ,true);
    tick_item("Japanese",false);
}
/**
 * Called by serial_eventloop, this calls the relevant commands.
 *
 * This calls the next command in the stack. By default, the command
 * is cmd_main_menu.
 *
 * New in 12.17 onwards: we accept json-formatted commands as well. Those
 * commands are parsed & dispatched below.
 *
 * Important remark: the CLI does not support multiple commands in one
 * line. For instance { "get": "guid", "get": "rtc" } will not work.
 *
 * JSON commands are as follow:
 *
 * Settings not linked to setting keys
 * "set" {
 *      "rtc": integer (Unix timestamp)
 *      "devicetag": string (device tag)
 *      }
 *
 *  Get/set settings keys (Work in progress not implemented yet):
 * "setkey" { "name": string, "value": value }
 * "getkey": "name"
 *
 *  Getting values not linked to setting keys
 * "get":
 *    - "guid"
 *    - "rtc"
 *    - "devicetag"
 *    - "settings"
 *    - "cpm"
 *
 */
void serial_process_command(char *line) {

  JSONNODE *n = json_parse(line);
  if (n == NULL) {
    // Old style commands
    (*command_stack[command_stack_size-1])(line);
  } else {
    // Dispatch:
    int err = true;
    /////
    // get
    /////
    JSONNODE *cmd = json_get_nocase(n,"get");
    if (cmd != 0 && json_type(cmd) == JSON_STRING) {
      json_char *val = json_as_string(cmd);
      if (strcmp(val, "cpm") == 0) {
        err = false;
        cmd_cpm(0);
      } else
      if (strcmp(val, "guid") == 0) {
        err = false;
        cmd_guid(0);
      } else
      if (strcmp(val,"rtc") == 0) {
        err = false;
        cmd_getrtc();
      } else
      if (strcmp(val,"devicetag") == 0) {
        err = false;
        cmd_getdevicetag(0);
      } else
      if (strcmp(val, "settings") == 0) {
        err = false;
        cmd_keyvaldump(0);
      } else
      if (strcmp(val, "version") == 0) {
        err = false;
        cmd_version(0);
      } else
      if (strcmp(val,"logstatus") == 0) {
         err = false;
         cmd_logstatus(0);
      }
      json_free(val);
    }
    /////
    // set
    /////
    cmd = json_get_nocase(n,"set");
    if (cmd !=0 && json_type(cmd) == JSON_NODE) {
      // Find what set operation we wanted:
      JSONNODE *op = json_get_nocase(cmd, "devicetag");
      if (op != 0 && json_type(op) == JSON_STRING) {
        err = false;
        json_char *tag = json_as_string(op);
        flashstorage_keyval_set("DEVICETAG",tag);
        json_keyval("ok", "devicetag");
      }
      op = json_get_nocase(cmd, "rtc");
      if (op != 0 && json_type(op) == JSON_NUMBER) {
        err = false;
        uint32_t  time = json_as_int(op);
        if (time != 0) {
          realtime_set_unixtime(time);
          json_keyval("ok", "rtc");
        }
      }
    }
    if (err) {
      json_keyval("error", "unknown command");
    }
  }
  json_delete(n);
}