
// --------------------------------------------
// 概要   : 设置处理
// --------------------------------------------
void setup() {
    randomSeed(analogRead(0));
    resetTimer();
    artecRobotSetup();
    artecRobotMain();
}

void loop() {}

// --------------------------------------------
// 概要   : 从列表中删除处理
// 自变量 : struct _cell_t *p  列表的光标
//        : int pos           从列表中删除的位置
// 返回值 : 成功：0，错误：-1
// --------------------------------------------
int listDelete(struct cell_t* p, int pos)
{
  // 删除位置小于0时，返回错误（什么也不做）
  if (pos <= 0) { return (-1); }

  // 删除位置大于列表长度时，返回错误（什么也不做）
  int l = listLength(p);        // 获取列表长度
  if (l < pos) { return (-1); } 

  cell_t *target, *before;      // 要删除的要素及其前一个要素
  target = p->next;             // 设定第二个要素
  before = NULL;

  if (target == NULL) return (-1);  // 删除要素不存在时，返回错误

  // 移动至删除目标要素
  before = p;
  for (int i = 0;i < pos-1;i++) {
    if (target->next == NULL) return (-1);  // 删除目标要素不存在时，返回错误
    before = target;        // 保存删除目标要素的前一个要素
    target = target->next;  // 更新删除目标要素 
  }

  // 存在删除目标要素时
  before->next = target->next;  // 将目标下一个要素设定为目标前一个要素
  delete target;  // 删除目标
  return(0);
}

// --------------------------------------------
// 概要   : 添加至列表处理
// 自变量 : struct _cell_t *p  列表的光标
//        : int    data        添加数据
// 返回值 : 成功：0，错误：-1
// --------------------------------------------
int listAdd(struct cell_t* p, float data)
{
  cell_t *elm, *last;

  // 确保列表要素
  elm = new cell_t;

  // 要素确保失败时
  if(elm == NULL) {
    // 返回错误
    return(-1);
  }

  // 将列表终端设定为last
  last = p;
  for (;;) {
    if (last->next == NULL) break;
    last = last->next;
  }

  // 添加至列表终端的要素的设定
  elm->data = data;
  elm->next = NULL;
  last->next = elm;

  return(0);
}

// --------------------------------------------
// 概要   : 获取列表长度
// 自变量 : struct _cell_t *p  列表的光标
// 返回值 : 列表长度
// --------------------------------------------
int listLength(struct cell_t* p)
{
  struct cell_t *last;

  // 移动至列表终端
  last = p;
  int length = 0;
  for (;;) {
    if (last->next == NULL) break;
    last = last->next;
    length++;
  }

  // 添加至列表终端的要素的设定
  return(length);
}

// --------------------------------------------
// 概要   : 获取列表要素
// 自变量 : struct _cell_t *p  列表的光标
//        : int    pos         列表要素的获取位置
// 返回值 : 返回值：列表要素不存在时返回0
// --------------------------------------------
float listItem(struct cell_t *p, int pos)
{
  // 获取位置小于0时，返回0
  if (pos <= 0) { return (0); }

  // 获取位置大于列表长度时，返回0
  int l = listLength(p);    // 获取列表长度
  if (l < pos) { return (0); }

  struct cell_t *target;    // 要获取的要素
  target = p;               // 设定第ー个要素

  // 移动至获取目标要素
  for (int i = 0;i < pos;i++) {
    target = target->next;  // 更新获取目标要素
  }

  return target->data;
}

// --------------------------------------------
// 概要   : 插入至列表处理
// 自变量 : struct _cell_t *p   列表的光标
//        : int pos             插入位置
//        : float data          插入的数据
// 返回值 : 成功：0，错误：-1
// --------------------------------------------
int listInsert(struct cell_t *p, int pos, float data)
{
  // 插入位置小于0时，返回错误（什么也不做）
  if (pos <= 0) { return (-1); }

  // 插入位置大于列表长度时+1，返回错误（什么也不做）
  int l = listLength(p);  // 获取列表长度
  if (l+1 < pos) { return (-1); } 

  // 插入位置为列表终端时
  if (l+1 == pos) {
    // 添加至列表的终端
    listAdd(p, data);

    return (0);
  }

  struct cell_t *item, *target, *before;	// 插入要素、插入位置的要素及其之前的要素

  // 确保列表要素
  item = new cell_t;

  // 要素确保失败时(返回错误)
  if(item == NULL) { return(-1); }

  target = p;

  // 移动至插入目标要素
  for (int i = 0;i < pos;i++) {
    before = target;        // 保存插入目标要素的前一个要素
    target = target->next;  // 更新插入目标要素
  }

  // 插入目标要素存在时
  item->data = data;    // 设定要素的数据
  item->next = target;  // 设定下一个要素
  before->next = item;  // 将目标下一个要素设定为前一个要素

  return(0);
}

// --------------------------------------------
// 概要   : 列表要素的替换处理
// 自变量 : struct _cell_t *p  列表的光标
//        : int pos            替换的位置
//        : float data         替换的数据
// 返回值 : 成功：0，错误：-1
// --------------------------------------------
int listReplace(struct cell_t *p, int pos, float data)
{
  // 替换位置小于0时，返回错误（什么也不做）
  if (pos <= 0) { return (-1); }

  // 替换位置大于列表长度时，返回错误（什么也不做）
  int l = listLength(p);  // 获取列表长度
  if (l < pos) { return (-1); } 

  struct cell_t *target;  // 替换的要素

  target = p;

  // 移动至替换目标要素
  for (int i = 0;i < pos;i++) {
    target = target->next;  // 更新替换目标要素
  }

  // 替换目标要素存在时
  target->data = data;      // 设定要素的数据
  return(0);
}

// --------------------------------------------
// 概要   : 列表的要素中存在指定数据吗？
// 自变量 : struct _cell_t *p  列表的光标
//        : float data         检索的数据
// 返回值 : 存在：true，不存在：false
// --------------------------------------------
bool listIsContain(struct cell_t *p, float data)
{
  struct cell_t *elm = p;

  // 对列表所有要素进行数据检索
  for (;;) {
    // 到达列表终端后break
    if (elm->next == NULL) break;
    // 获取列表下一个要素
    elm = elm->next;
    // 列表中data存在时，返回true
    if (elm->data == data) return true;
  }

  // 列表中data不存在时，返回false
  return false;
}

// --------------------------------------------
// 概要   : 取整处理
//        : float  arg    自变量
// 返回值 : 运算结果
// --------------------------------------------
int scratchRound(float arg)
{
  return round(arg);
}

// --------------------------------------------
// 概要   : 运算处理
// 自变量 : byte   opeID  操作ID
//        : float  arg    自变量
// 返回值 : 运算结果
// --------------------------------------------
float math(byte opeID, float arg)              // 运算处理
{
  float result;

  switch (opeID) {
    case SQRT:
      result = sqrt(arg);
    break;

    case ABS:     // |n|
      result = abs(arg);
    break;

    case SIN:     // sin(n)
    {
      float rad = arg * PI / 180.0;
      result = sin(rad);
    }
    break;

    case COS:     // cos(n)
    {
      float rad = arg * PI / 180.0;
      result = cos(rad);
    }
    break;

    case TAN:     // tan(n)
    {
      float rad = arg * PI / 180.0;
      result = tan(rad);
    }
    break;

/*
    case ASIN:    // arcsin(n)
    case ACOS:    // arccos(n)
    case ATAN:    // arctan(n)
    break;
*/

    case LN:      // loge
      result = log(arg);
    break;

    case LOG:     // log10
      result = log10(arg);
    break;

    case POWE:    // e^
      result = exp(arg);
    break;

    case POW10:   // 10^
      result = pow(10, arg);
    break;

    default:
      result = 0;
    break;
  }

  return result;
}

// --------------------------------------------
// 概要    : 读取计时器值
// 返回值  : 计时器值(sec)
// --------------------------------------------
float getTimer()
{
  return ((millis() - StartTime) / 1000.0);
}

// --------------------------------------------
// 概要    : 重置计时器值
// --------------------------------------------
void resetTimer()
{
  StartTime = millis();
}

