#include "vacuum_ui.h"
#include <string.h>
void vui_init(vui_state*s){if(s){memset(s,0,sizeof(*s));s->level=1;}}
vui_output vui_step(vui_state*s,const vui_input*in,uint32_t now){
 vui_output o={0};if(!s)return o;
 if(!in){s->run_requested=false;s->hold_active=false;s->hold_consumed=true;return o;}
 bool discontinuity=!s->have_sample||(uint32_t)(now-s->last_ms)>100u;
 s->last_ms=now;s->have_sample=true;
 if(discontinuity){
  s->previous_power=in->power_pressed;s->previous_plus=in->plus_pressed;s->previous_minus=in->minus_pressed;
  s->run_requested=false;s->hold_active=false;s->hold_consumed=in->plus_pressed||in->minus_pressed;
  o.level=s->level;return o;
 }
 bool power=in->power_pressed&&!s->previous_power;
 bool plus=in->plus_pressed&&!s->previous_plus;
 bool minus=in->minus_pressed&&!s->previous_minus;
 s->previous_power=in->power_pressed;s->previous_plus=in->plus_pressed;s->previous_minus=in->minus_pressed;
 if(!in->plus_pressed&&!in->minus_pressed)s->hold_consumed=false;
 if(in->fault||in->learning_busy){s->run_requested=false;s->hold_active=false;s->hold_consumed=true;}
 else if(power){s->run_requested=!s->run_requested;s->hold_active=false;s->hold_consumed=true;}
 else if(in->plus_pressed&&in->minus_pressed){
  if(!s->hold_consumed){
   if(!s->hold_active){s->hold_active=true;s->both_since=now;}
   else if((uint32_t)(now-s->both_since)>5000u){
    s->hold_consumed=true;s->hold_active=false;
    if(in->learning_resources_ready){s->run_requested=false;o.learning_request=true;}
   }
  }
 }else{
  s->hold_active=false;
  if(plus&&!in->minus_pressed&&s->level<4u)++s->level;
  if(minus&&!in->plus_pressed&&s->level>1u)--s->level;
 }
 o.level=s->level;o.run_requested=s->run_requested;return o;
}
bool vui_lookup_duty(uint8_t level,const uint16_t table[4],bool valid,uint16_t*duty){
 if(!duty)return false;*duty=0;
 if(!valid||!table||level<1u||level>4u)return false;
 for(unsigned i=0;i<4;i++)if(table[i]>1000u||(i&&table[i]<=table[i-1]))return false;
 /* Increasing control duty is a candidate electrical convention only.
    Physical driver must implement validated fan polarity. */
 *duty=table[level-1];return true;
}
