#include <jag_parse.h>

uint8_t main_buffer[BUF_LEN];

uint16_t start = 0;
uint16_t end = 0;

uint16_t length = 0;



void free_buf () {
  start = 0;
  end = 0;
  length = 0;
}


int add_to_buf(uint8_t *input, uint16_t input_length) {
  
  if (BUF_LEN - length < input_length)
    return 0;

  uint16_t space_end = BUF_LEN - end;

  if (input_length <= space_end) {
    memcpy(main_buffer + end, input, input_length);
  } else {
    memcpy(main_buffer + end, input, space_end);
    memcpy(main_buffer, input + space_end, input_length - space_end);
  }

  end = (end + input_length) % BUF_LEN;
  length += input_length;

  return 1;
}


uint16_t next_pos(uint16_t starting_position) {
  return (starting_position + 1) % BUF_LEN;
}


keypress parse_input() {

  if(length == 0)
    return NO_KEY;

  keypress output = UNKNOWN;

  uint8_t next_char = tolower(main_buffer[start]);
  uint16_t next_position = next_pos(start);


  if (next_char == '\033') {

    if (length < ARROW_LEN) {
      output = INCOMPLETE;
      next_position = start;
    } else {

      length--;

      if (main_buffer[next_position] == '[') {
        next_position = next_pos(next_position);

        length--;

        uint8_t escape_code = main_buffer[next_position];

        switch(escape_code) {
          case 'A':
            output = UP_ARROW;
            break;
          case 'B':
            output = DOWN_ARROW;
            break;
          case 'C':
            output = RIGHT_ARROW;
            break;
          case 'D':
            output = LEFT_ARROW;
            break;
          default:
            break;
        }
        
        length--;

        next_position = next_pos(next_position);
      } else {
        output = ESCAPE_KEY;
      }
    }

  } else {

    length--;

    switch (next_char) {
      case '\n':
        output = ENTER_KEY;
        break;
      case 'a':
        output = A_KEY;
        break;
      case 'd':
        output = D_KEY;
        break;
      case 'p':
        output = P_KEY;
        break;
      case 'q':
        output = Q_KEY;
        break;
      case 's':
        output = S_KEY;
        break;
      case 'w':
        output = W_KEY;
        break;
      default:
        break;
    }
  }

  start = next_position;

  return output;
}

void break_unfinished() {
  while (length--)
    start = next_pos(start);
}
