#include <U8g2lib.h>
#include <Wire.h>
#include <math.h>


//!!!!!UNO板默认A4为SDA,A5为SCL
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, SCL, SDA, /* reset=*/ U8X8_PIN_NONE); //这是比较常用的0.9寸的OLED显示器的驱动

/************结构体定义********************/
/*****************************************/
/*******菜单变量******/
typedef struct
{
  char* str;
  byte len;
}SETTING_LIST;  //给一个默认的字符长度,是因为中文无法strlen得到长度值

SETTING_LIST list[] = 
{
  {"list_a", 6},
  {"add", 3},
  {"lisc", 4},
  {"lixv_1", 6},
  {"lixfdd_2", 8},
};

/******按键扫描值记录********/
typedef struct
{
  byte val;
  byte last_val;
}KEY_T;

KEY_T key[2] = {0};

/********按键状态判断*******/

typedef struct
{
  byte id;
  byte press;
  byte update_flag;
  byte res;
}KEY_MSG;

KEY_MSG key_msg = {0};
/***********变量配置************/

short x, x_trg; //x当前位置数值,x_trg 目标坐标值
short y, y_trg;
int state;

short frame_len, frame_len_trg;  //选中框的宽度
short frame_y, frame_y_trg;      //选中框的高度

char ui_select = 0;  //表示当前选中第几行菜单

/**************函数定义*************/

byte get_io_val(byte ch)
{
  if(ch == 0)
  {
    return digitalRead(2);
  }
  else
  {
    return digitalRead(3);
  }
}

void key_init(void)
{
  for(int i = 0;i<2;i++)
  {
    key[i].val = key[i].last_val = get_io_val(i);
  }
}

void key_scan(void)
{
  for(int i = 0;i<2;i++)
  {
    key[i].val =  get_io_val(i);
    if(key[i].val != key[i].last_val)
    {
      key[i].last_val = key[i].val;
      if(key[i].val == 0)
      {
        key_msg.id = i;
        key_msg.press = 1;
        key_msg.update_flag = 1;
      }
    }
  }
}

/***********UI移动函数***********/
int ui_run(short *a,short *a_trg, u8 step, u8 slow_cnt)
{
  u8 temp;
  temp = abs(*a_trg - *a) > slow_cnt ? step : 1;
  if(*a < *a_trg)
  {
    *a += temp;
  }
  else if( *a > *a_trg)
  {
    *a -= temp;    
  }
  else
  {
    return 0;  //如果到达目标值,返回0
  }
  return 1;   //未到达目标值,返回1
}


/**************配置函数*****************/
void setup(void) 
{
 	pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  key_init();
  u8g2.begin();
  u8g2.setFont(u8g2_font_ncenB08_tr); //设置字体
  x = 0;
  y = 10;
  //x_trg = 64;
  y_trg = 10;

  frame_len = frame_len_trg = list[ui_select].len*6;
}


/**************UI显示函数*****************/
void ui_show(void)
{
  int list_len = sizeof(list) / sizeof(SETTING_LIST);
  u8g2.clearBuffer();         // 清除内部缓冲区
  for(int i = 0; i < list_len; i++)
  {
    u8g2.drawStr(x+2, y+i*10, list[i].str);  // 第一段输出位置,为了防止显示内容与框框重合,所以x往右偏移2个像素
  }
  // ui_run(&x, &x_trg);

  u8g2.drawRFrame(x, frame_y, frame_len, 12 ,3 );

/**
 * 绘制圆角空心方形,左上角坐标为(x,y),宽度为w,高度为h,圆角半径为r
 * @param x 左上角的x坐标
 * @param y 左上角的y坐标
 * @param w 方形的宽度
 * @param h 方形的高度
 * @param r 圆角半径
 */
//void U8G2::drawRFrame(u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r)

//  ui_run(&y, &y_trg)  //这里实现,框不动,字动
  ui_run(&frame_y, &frame_y_trg, 4, 2);  //这里实现框动,字不动
  ui_run(&frame_len, &frame_len_trg, 6, 3);
  u8g2.sendBuffer();          // transfer internal memory to the display
}

/***************UI运动处理****************/
void ui_proc(void)
{
  int list_len = sizeof(list) / sizeof(SETTING_LIST);
  if(key_msg.update_flag && key_msg.press)
  {
    key_msg.update_flag = 0;
    if(key_msg.id)
    {
      ui_select ++;
      //frame_y += 10;
      if(ui_select >= list_len)
      {
        ui_select = list_len - 1;
      }
    }
    else{
      ui_select --;
      //frame_y -= 10;
      if(ui_select < 0)
      {
        ui_select = 0;
      }
    }
    frame_y_trg = ui_select*10;
    frame_len_trg = list[ui_select].len*6;
  }
  ui_show();
}

void loop()
{
  // put your main code here, to run repeatedly:
key_scan();
ui_proc();

}