/* vi.c - You can't spell "evil" without "vi".
 *
 * Copyright 2015 Rob Landley <rob@landley.net>
 * Copyright 2019 Jarno Mäkipää <jmakip87@gmail.com>
 *
 * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/vi.html

USE_VI(NEWTOY(vi, "<1>1", TOYFLAG_USR|TOYFLAG_BIN))

config VI
  bool "vi"
  default n
  help
    usage: vi FILE
    Visual text editor. Predates the existence of standardized cursor keys,
    so the controls are weird and historical.
*/

#define FOR_vi
#include "toys.h"

GLOBALS(
    int cur_col;
    int cur_row;
    int scr_row;
    int drawn_row;
    int drawn_col;
    unsigned screen_height;
    unsigned screen_width;
    int vi_mode;
    int count0;
    int count1;
    int vi_mov_flag;
    int modified;
    char vi_reg;
    char *last_search;
    int tabstop;
    int list;
)

struct str_line {
  int alloc_len;
  int str_len;
  char *str_data;
};
//yank buffer
struct yank_buf {
  char reg;
  int alloc;
  char* data;
};


//lib dllist uses next and prev kinda opposite what im used to so I just
//renamed both ends to up and down
struct linelist {
  struct linelist *up;//next
  struct linelist *down;//prev
  struct str_line *line;
};

static void draw_page();

//utf8 support
static int utf8_lnw(int* width, char* str, int bytes);
static int utf8_dec(char key, char *utf8_scratch, int *sta_p);
static int utf8_len(char *str);
static int utf8_width(char *str, int bytes);
static char* utf8_last(char* str, int size);


static int cur_left(int count0, int count1, char* unused);
static int cur_right(int count0, int count1, char* unused);
static int cur_up(int count0, int count1, char* unused);
static int cur_down(int count0, int count1, char* unused);
static void check_cursor_bounds();
static void adjust_screen_buffer();
static int search_str(char *s);

static int vi_yank(char reg, struct linelist *row, int col, int flags);
static int vi_delete(char reg, struct linelist *row, int col, int flags);

//inserted line not yet pushed to buffer
struct str_line *il;
struct linelist *text; //file loaded into buffer
struct linelist *scr_r;//current screen coord 0 row
struct linelist *c_r;//cursor position row

struct yank_buf yank; //single yank

// TT.vi_mov_flag is used for special cases when certain move
// acts differently depending is there DELETE/YANK or NOP
// Also commands such as G does not default to count0=1
// 0x1 = Command needs argument (f,F,r...)
// 0x2 = Move 1 right on yank/delete/insert (e, $...)
// 0x4 = yank/delete last line fully
// 0x10000000 = redraw after cursor needed
// 0x20000000 = full redraw needed
// 0x40000000 = count0 not given
// 0x80000000 = move was reverse

void dlist_insert_nomalloc(struct double_list **list, struct double_list *new)
{
  if (*list) {
    new->next = *list;
    new->prev = (*list)->prev;
    if ((*list)->prev) (*list)->prev->next = new;
    (*list)->prev = new;
  } else *list = new->next = new->prev = new;
}


// Add an entry to the end of a doubly linked list
struct double_list *dlist_insert(struct double_list **list, char *data)
{
  struct double_list *new = xmalloc(sizeof(struct double_list));
  new->data = data;
  dlist_insert_nomalloc(list, new);

  return new;
}
//TODO implement
void linelist_unload()
{

}

void write_file(char *filename)
{
  struct linelist *lst = text;
  FILE *fp = 0;
  if (!filename)
    filename = (char*)*toys.optargs;
  fp = fopen(filename, "w");
  if (!fp) return;
  while (lst) {
    fprintf(fp, "%s\n", lst->line->str_data);
    lst = lst->down;
  }
  fclose(fp);
}

int linelist_load(char *filename)
{
  struct linelist *lst = c_r;//cursor position or 0
  FILE *fp = 0;
  if (!filename)
    filename = (char*)*toys.optargs;

  fp = fopen(filename, "r");
  if (!fp) {
    char *line = xzalloc(80);
    ssize_t alc = 80;
    lst = (struct linelist*)dlist_add((struct double_list**)&lst,
        xzalloc(sizeof(struct str_line)));
    lst->line->alloc_len = alc;
    lst->line->str_len = 0;
    lst->line->str_data = line;
    text = lst;
    dlist_terminate(text->up);
    return 1;
  }

  for (;;) {
    char *line = xzalloc(80);
    ssize_t alc = 80;
    ssize_t len;
    if ((len = getline(&line, (void *)&alc, fp)) == -1) {
      if (errno == EINVAL || errno == ENOMEM) {
        printf("error %d\n", errno);
      }
      free(line);
      break;
    }
    lst = (struct linelist*)dlist_add((struct double_list**)&lst,
        xzalloc(sizeof(struct str_line)));
    lst->line->alloc_len = alc;
    lst->line->str_len = len;
    lst->line->str_data = line;

    if (lst->line->str_data[len-1] == '\n') {
      lst->line->str_data[len-1] = 0;
      lst->line->str_len--;
    }
    if (text == 0) text = lst;
  }

  if (text) dlist_terminate(text->up);

  fclose(fp);
  return 1;

}

int vi_yy(char reg, int count0, int count1)
{
  struct linelist *pos = c_r;
  int col = TT.cur_col;
  TT.cur_col = 0;
  TT.vi_mov_flag |= 0x4;

  if (count0>1) cur_down(count0-1, 1, 0);

  vi_yank(reg, pos, 0, 0);

  TT.cur_col = col, c_r = pos;
  return 1;
}

int vi_dd(char reg, int count0, int count1)
{
  struct linelist *pos = c_r;
  TT.cur_col = 0;
  TT.vi_mov_flag |= 0x4;
  if (count0>1) cur_down(count0-1, 1, 0);

  vi_delete(reg, pos, 0, 0);
  check_cursor_bounds();
  return 1;
}

static int vi_x(char reg, int count0, int count1)
{
  char *last = 0, *cpos = 0, *start = 0;
  int len = 0;
  struct linelist *pos = c_r;
  int col = TT.cur_col;
  if (!c_r) return 0;

  start = c_r->line->str_data;
  len = c_r->line->str_len;

  last = utf8_last(start, len);
  cpos = start+TT.cur_col;
  if (cpos == last) {
    cur_left(count0-1, 1, 0);
    col = strlen(start);
  }
  else {
    cur_right(count0-1, 1, 0);
    cpos = start+TT.cur_col;
    if (cpos == last) TT.vi_mov_flag |= 2;
    else cur_right(1, 1, 0);
  }

  vi_delete(reg, pos, col, 0);
  check_cursor_bounds();
  return 1;
}

//move commands does not behave correct way yet.
int vi_movw(int count0, int count1, char* unused)
{
  int count = count0*count1;
  const char *empties = " \t\n\r";
  const char *specials = ",.=-+*/(){}<>[]";
//  char *current = 0;
  if (!c_r)
    return 0;
  if (TT.cur_col == c_r->line->str_len-1 || !c_r->line->str_len)
    goto next_line;
  if (strchr(empties, c_r->line->str_data[TT.cur_col]))
    goto find_non_empty;
  if (strchr(specials, c_r->line->str_data[TT.cur_col])) {
    for (;strchr(specials, c_r->line->str_data[TT.cur_col]); ) {
      TT.cur_col++;
      if (TT.cur_col == c_r->line->str_len-1)
        goto next_line;
    }
  } else for (;!strchr(specials, c_r->line->str_data[TT.cur_col]) &&
      !strchr(empties, c_r->line->str_data[TT.cur_col]);) {
      TT.cur_col++;
      if (TT.cur_col == c_r->line->str_len-1)
        goto next_line;
  }

  for (;strchr(empties, c_r->line->str_data[TT.cur_col]); ) {
    TT.cur_col++;
find_non_empty:
    if (TT.cur_col == c_r->line->str_len-1) {
next_line:
      //we could call j and g0
      if (!c_r->down) return 0;
      c_r = c_r->down;
      TT.cur_col = 0;
      if (!c_r->line->str_len) break;
    }
  }
  count--;
  if (count>0)
    return vi_movw(count, 1, 0);

  check_cursor_bounds();
  return 1;
}

static int vi_movb(int count0, int count1, char* unused)
{
  int count = count0*count1;
  if (!c_r)
    return 0;
  if (!TT.cur_col) {
      if (!c_r->up) return 0;
      c_r = c_r->up;
      TT.cur_col = (c_r->line->str_len) ? c_r->line->str_len-1 : 0;
      goto exit_function;
  }
  if (TT.cur_col)
      TT.cur_col--;
  while (c_r->line->str_data[TT.cur_col] <= ' ') {
    if (TT.cur_col) TT.cur_col--;
    else goto exit_function;
  }
  while (c_r->line->str_data[TT.cur_col] > ' ') {
    if (TT.cur_col)TT.cur_col--;
    else goto exit_function;
  }
  TT.cur_col++;
exit_function:
  count--;
  if (count>1)
    return vi_movb(count, 1, 0);
  TT.vi_mov_flag |= 0x80000000;
  check_cursor_bounds();
  return 1;
}

static int vi_move(int count0, int count1, char *unused)
{
  int count = count0*count1;
  if (!c_r)
    return 0;
  if (TT.cur_col < c_r->line->str_len)
    TT.cur_col++;
  if (c_r->line->str_data[TT.cur_col] <= ' ' || count > 1)
    vi_movw(count, 1, 0); //find next word;
  while (c_r->line->str_data[TT.cur_col] > ' ')
    TT.cur_col++;
  if (TT.cur_col) TT.cur_col--;

  TT.vi_mov_flag |= 2;
  check_cursor_bounds();
  return 1;
}


static void i_insert(char* str, int len)
{
  char *t = xzalloc(c_r->line->alloc_len);
  char *s = c_r->line->str_data;
  int sel = c_r->line->str_len-TT.cur_col;
  strncpy(t, &s[TT.cur_col], sel);
  t[sel+1] = 0;
  if (c_r->line->alloc_len < c_r->line->str_len+len+5) {
    c_r->line->str_data = xrealloc(c_r->line->str_data,
      (c_r->line->alloc_len+len)<<1);

    c_r->line->alloc_len = (c_r->line->alloc_len+len)<<1;
    memset(&c_r->line->str_data[c_r->line->str_len], 0,
        c_r->line->alloc_len-c_r->line->str_len);

    s = c_r->line->str_data;
  }
  strncpy(&s[TT.cur_col], str, len);
  strcpy(&s[TT.cur_col+len], t);
  TT.cur_col += len;
  if (TT.cur_col) TT.cur_col--;

  c_r->line->str_len += len;
  free(t);

  TT.vi_mov_flag |= 0x30000000;
}

//new line at split pos;
void i_split()
{
  int alloc = 0, len = 0, idx = 0;
  struct str_line *l = xmalloc(sizeof(struct str_line));
  alloc = c_r->line->alloc_len;

  if (TT.cur_col) len = c_r->line->str_len-TT.cur_col-1;
  else len = c_r->line->str_len;
  if (len < 0) len = 0;

  l->str_data = xzalloc(alloc);
  l->alloc_len = alloc;
  l->str_len = len;
  idx = c_r->line->str_len - len;

  strncpy(l->str_data, &c_r->line->str_data[idx], len);
  memset(&l->str_data[len], 0, alloc-len);

  c_r->line->str_len -= len;
  if (c_r->line->str_len <= 0) c_r->line->str_len = 0;

  len = c_r->line->str_len;

  memset(&c_r->line->str_data[len], 0, alloc-len);
  c_r = (struct linelist*)dlist_insert((struct double_list**)&c_r, (char*)l);
  c_r->line = l;
  TT.cur_col = 0;
}


static int vi_zero(int count0, int count1, char *unused)
{
  TT.cur_col = 0;
  TT.vi_mov_flag |= 0x80000000;
  return 1;
}

static int vi_eol(int count0, int count1, char *unused)
{
  int count = count0*count1;
  for (;count > 1 && c_r->down; count--)
    c_r = c_r->down;

  if (c_r && c_r->line->str_len)
    TT.cur_col = c_r->line->str_len-1;
  TT.vi_mov_flag |= 2;
  check_cursor_bounds();
  return 1;
}

//TODO check register where to push from
static int vi_push(char reg, int count0, int count1)
{
  char *start = yank.data, *end = yank.data+strlen(yank.data);
  struct linelist *cursor = c_r;
  int col = TT.cur_col;
  //insert into new lines
  if (*(end-1) == '\n') for (;start != end;) {
    TT.vi_mov_flag |= 0x10000000;
    char *next = strchr(start, '\n');
    TT.cur_col = (c_r->line->str_len) ? c_r->line->str_len-1: 0;
    i_split();
    if (next) {
      i_insert(start, next-start);
      start = next+1;
    } else start = end; //??
  }

  //insert into cursor
  else for (;start != end;) {
    char *next = strchr(start, '\n');
    if (next) {
      TT.vi_mov_flag |= 0x10000000;
      i_insert(start, next-start);
      i_split();
      start = next+1;
    } else {
      i_insert(start, strlen(start));
      start = end;
    }
  }
  //if row changes during push original cursor position is kept
  //vi inconsistancy
  if (c_r != cursor) c_r = cursor, TT.cur_col = col;

  return 1;
}

static int vi_find_c(int count0, int count1, char *symbol)
{
  int count = count0*count1;
  if (c_r && c_r->line->str_len) {
    while (count--) {
        char* pos = strstr(&c_r->line->str_data[TT.cur_col], symbol);
        if (pos) {
          TT.cur_col = pos-c_r->line->str_data;
          return 1;
        }
    }
  }
  return 0;
}

static int vi_find_cb(int count0, int count1, char *symbol)
{
  //do backward search
  return 1;
}

//if count is not spesified should go to last line
static int vi_go(int count0, int count1, char *symbol)
{
  int prev_row = TT.cur_row;
  c_r = text;

  if (TT.vi_mov_flag&0x40000000) for (;c_r && c_r->down; c_r = c_r->down);
  else for (;c_r && c_r->down && --count0; c_r = c_r->down);

  TT.cur_col = 0;
  check_cursor_bounds();  //adjusts cursor column
  if (prev_row>TT.cur_row) TT.vi_mov_flag |= 0x80000000;

  return 1;
}

//need to refactor when implementing yank buffers
static int vi_delete(char reg, struct linelist *row, int col, int flags)
{
  struct linelist *start = 0, *end = 0;
  int col_s = 0, col_e = 0, bytes = 0;

  vi_yank(reg, row, col, flags);

  if (TT.vi_mov_flag&0x80000000) {
    start = c_r, end = row;
    col_s = TT.cur_col, col_e = col;
  } else {
    start = row, end = c_r;
    col_s = col, col_e = TT.cur_col;
  }
  if (start == end) goto last_line_delete;
  if (!col_s) goto full_line_delete;

  memset(start->line->str_data+col_s, 0, start->line->str_len-col_s);
  row->line->str_len = col_s;
  col_s = 0;
  start = start->down;

full_line_delete:
  TT.vi_mov_flag |= 0x10000000;
  for (;start != end;) {
    struct linelist* lst = start;
    //struct linelist *lst = dlist_pop(&start);
    start = start->down;
    if (lst->down) lst->down->up = lst->up;
    if (lst->up) lst->up->down = lst->down;
    if (scr_r == lst) scr_r = lst->down ? lst->down : lst->up;
    if (text == lst) text = lst->down;
    free(lst->line->str_data);
    free(lst->line);
    free(lst);
  }
last_line_delete:
  TT.vi_mov_flag |= 0x10000000;
  if (TT.vi_mov_flag&2) col_e = start->line->str_len;
  if (TT.vi_mov_flag&4) {
    if (!end->down && !end->up)
      col_e = start->line->str_len;
    else {
      col_e = 0, col_s = 0;
      if (end->down) end->down->up = end->up;
      if (end->up) end->up->down = end->down;
      if (scr_r == end) scr_r = end->down ? end->down : end->up;
      //if (text == end) text = end->down;
      start = end->down ? end->down : end->up;
      free(end->line->str_data);
      free(end->line);
      free(end);

    }
  }
  if (col_s < col_e) {
    bytes = col_s + start->line->str_len - col_e;
    memmove(start->line->str_data+col_s, start->line->str_data+col_e,
        start->line->str_len-col_e);
    memset(start->line->str_data+bytes, 0, start->line->str_len-bytes);
    start->line->str_len = bytes;
  }
  c_r = start;
  TT.cur_col = col_s;
  return 1;
}

static int vi_D(char reg, int count0, int count1)
{
  int prev_col = TT.cur_col;
  struct linelist *pos = c_r;
  if (!count0) return 1;
  vi_eol(1, 1, 0);
  vi_delete(reg, pos, prev_col, 0);
  count0--;
  if (count0 && c_r->down) {
    c_r = c_r->down;
    vi_dd(reg, count0, 1);
  }
  check_cursor_bounds();
  return 1;
}

static int vi_join(char reg, int count0, int count1)
{
  while (count0--) {
    if (c_r && c_r->down) {
      int size = c_r->line->str_len+c_r->down->line->str_len;
      if (size > c_r->line->alloc_len) {
        if (size > c_r->down->line->alloc_len) {
          c_r->line->str_data = xrealloc(c_r->line->str_data,
            c_r->line->alloc_len*2+il->alloc_len*2);
          memmove(&c_r->line->str_data[c_r->line->str_len],
              c_r->down->line->str_data,c_r->down->line->str_len);
          c_r->line->str_len = size;
          c_r = c_r->down;
          c_r->line->alloc_len = c_r->line->alloc_len*2+2*il->alloc_len;
          vi_dd(0,1,1);
        } else {
          memmove(&c_r->down->line->str_data[c_r->line->str_len],
              c_r->down->line->str_data,c_r->down->line->str_len);
          memmove(c_r->down->line->str_data,c_r->line->str_data,
              c_r->line->str_len);
          c_r->down->line->str_len = size;
          vi_dd(0,1,1);
        }
      } else {
          memmove(&c_r->line->str_data[c_r->line->str_len],
              c_r->down->line->str_data,c_r->down->line->str_len);
          c_r->line->str_len = size;
          c_r = c_r->down;
          vi_dd(0,1,1);
      }
      c_r = c_r->up;

    }
  }
  return 1;
}

static int vi_find_next(char reg, int count0, int count1)
{
  if (TT.last_search) search_str(TT.last_search);
  return 1;
}

static int vi_change(char reg, struct linelist *row, int col, int flags)
{
  vi_delete(reg, row, col, flags);
  TT.vi_mode = 2;
  return 1;
}

//TODO search yank buffer by register
//now only supports default register
static int vi_yank(char reg, struct linelist *row, int col, int flags)
{
  struct linelist *start = 0, *end = 0;
  int col_s = 0, col_e = 0, bytes = 0;

  memset(yank.data, 0, yank.alloc);
  if (TT.vi_mov_flag&0x80000000) {
    start = c_r, end = row;
    col_s = TT.cur_col, col_e = col;
  } else {
    start = row, end = c_r;
    col_s = col, col_e = TT.cur_col;
  }
  if (start == end) goto last_line_yank;
  if (!col_s) goto full_line_yank;

  if (yank.alloc < start->line->alloc_len) {
    yank.data = xrealloc(yank.data, start->line->alloc_len*2);
    yank.alloc = start->line->alloc_len*2;
  }

  sprintf(yank.data, "%s\n", start->line->str_data+col_s);
  col_s = 0;
  start = start->down;

full_line_yank:
  for (;start != end;) {
    while (yank.alloc-1 < strlen(yank.data)+start->line->str_len)
      yank.data = xrealloc(yank.data, yank.alloc*2), yank.alloc *= 2;


    sprintf(yank.data+strlen(yank.data), "%s\n", start->line->str_data);
    start = start->down;
  }
last_line_yank:
  while (yank.alloc-1 < strlen(yank.data)+end->line->str_len)
    yank.data = xrealloc(yank.data, yank.alloc*2), yank.alloc *= 2;

  if (TT.vi_mov_flag & 0x4)
    sprintf(yank.data+strlen(yank.data), "%s\n", start->line->str_data);
  else {
    bytes = strlen(yank.data)+col_e-col_s;
    strncpy(yank.data+strlen(yank.data), end->line->str_data+col_s, col_e-col_s);
    yank.data[bytes] = 0;
  }
  return 1;
}

//NOTES
//vi-mode cmd syntax is
//("[REG])[COUNT0]CMD[COUNT1](MOV)
//where:
//-------------------------------------------------------------
//"[REG] is optional buffer where deleted/yanked text goes REG can be
//  atleast 0-9, a-z or default "
//[COUNT] is optional multiplier for cmd execution if there is 2 COUNT
//  operations they are multiplied together
//CMD is operation to be executed
//(MOV) is movement operation, some CMD does not require MOV and some
//  have special cases such as dd, yy, also movements can work without
//  CMD
//ex commands can be even more complicated than this....
//
struct vi_cmd_param {
  const char* cmd;
  unsigned flags;
  int (*vi_cmd)(char, struct linelist*, int, int);//REG,row,col,FLAGS
};
struct vi_mov_param {
  const char* mov;
  unsigned flags;
  int (*vi_mov)(int, int, char*);//COUNT0,COUNT1,params
};
//special cases without MOV and such
struct vi_special_param {
  const char *cmd;
  int (*vi_special)(char, int, int);//REG,COUNT0,COUNT1
};
struct vi_special_param vi_special[] =
{
  {"dd", &vi_dd},
  {"yy", &vi_yy},
  {"D", &vi_D},
  {"J", &vi_join},
  {"n", &vi_find_next},
  {"x", &vi_x},
  {"p", &vi_push}
};
//there is around ~47 vi moves
//some of them need extra params
//such as f and '
struct vi_mov_param vi_movs[] =
{
  {"0", 0, &vi_zero},
  {"b", 0, &vi_movb},
  {"e", 0, &vi_move},
  {"G", 0, &vi_go},
  {"h", 0, &cur_left},
  {"j", 0, &cur_down},
  {"k", 0, &cur_up},
  {"l", 0, &cur_right},
  {"w", 0, &vi_movw},
  {"$", 0, &vi_eol},
  {"f", 1, &vi_find_c},
  {"F", 1, &vi_find_cb},
};
//change and delete unfortunately behave different depending on move command,
//such as ce cw are same, but dw and de are not...
//also dw stops at w position and cw seem to stop at e pos+1...
//so after movement we need to possibly set up some flags before executing
//command, and command needs to adjust...
struct vi_cmd_param vi_cmds[] =
{
  {"c", 1, &vi_change},
  {"d", 1, &vi_delete},
  {"y", 1, &vi_yank},
};

int run_vi_cmd(char *cmd)
{
  int i = 0, val = 0;
  char *cmd_e;
  int (*vi_cmd)(char, struct linelist*, int, int) = 0;
  int (*vi_mov)(int, int, char*) = 0;

  TT.count0 = 0, TT.count1 = 0, TT.vi_mov_flag = 0;
  TT.vi_reg = '"';

  if (*cmd == '"') {
    cmd++;
    TT.vi_reg = *cmd; //TODO check validity
    cmd++;
  }
  errno = 0;
  val = strtol(cmd, &cmd_e, 10);
  if (errno || val == 0) val = 1, TT.vi_mov_flag |= 0x40000000;
  else cmd = cmd_e;
  TT.count0 = val;

  for (i = 0; i < ARRAY_LEN(vi_special); i++) {
    if (strstr(cmd, vi_special[i].cmd)) {
      return vi_special[i].vi_special(TT.vi_reg, TT.count0, TT.count1);
    }
  }

  for (i = 0; i < ARRAY_LEN(vi_cmds); i++) {
    if (!strncmp(cmd, vi_cmds[i].cmd, strlen(vi_cmds[i].cmd))) {
      vi_cmd = vi_cmds[i].vi_cmd;
      cmd += strlen(vi_cmds[i].cmd);
      break;
    }
  }
  errno = 0;
  val = strtol(cmd, &cmd_e, 10);
  if (errno || val == 0) val = 1;
  else cmd = cmd_e;
  TT.count1 = val;

  for (i = 0; i < ARRAY_LEN(vi_movs); i++) {
    if (!strncmp(cmd, vi_movs[i].mov, strlen(vi_movs[i].mov))) {
      vi_mov = vi_movs[i].vi_mov;
      TT.vi_mov_flag |= vi_movs[i].flags;
      cmd++;
      if (TT.vi_mov_flag&1 && !(*cmd)) return 0;
      break;
    }
  }
  if (vi_mov) {
    int prev_col = TT.cur_col;
    struct linelist *pos = c_r;
    if (vi_mov(TT.count0, TT.count1, cmd)) {
      if (vi_cmd) return (vi_cmd(TT.vi_reg, pos, prev_col, TT.vi_mov_flag));
      else return 1;
    } else return 0; //return some error
  }
  return 0;
}

static int search_str(char *s)
{
  struct linelist *lst = c_r;
  char *c = strstr(&c_r->line->str_data[TT.cur_col+1], s);

  if (TT.last_search != s) {
    free(TT.last_search);
    TT.last_search = xstrdup(s);
  }

  if (c) {
    TT.cur_col = c-c_r->line->str_data;
  } else for (; !c;) {
    lst = lst->down;
    if (!lst) return 1;
    c = strstr(lst->line->str_data, s);
  }
  c_r = lst;
  TT.cur_col = c-c_r->line->str_data;
  check_cursor_bounds();
  return 0;
}

int run_ex_cmd(char *cmd)
{
  if (cmd[0] == '/') {
    search_str(&cmd[1]);
  } else if (cmd[0] == '?') {
    // TODO: backwards search.
  } else if (cmd[0] == ':') {
    if (!strcmp(&cmd[1], "q") || !strcmp(&cmd[1], "q!")) {
      // TODO: if no !, check whether file modified.
      //exit_application;
      return -1;
    }
    else if (strstr(&cmd[1], "wq")) {
      write_file(0);
      return -1;
    }
    else if (strstr(&cmd[1], "w")) {
      write_file(0);
      return 1;
    }
    else if (strstr(&cmd[1], "set list")) {
      TT.list = 1;
      TT.vi_mov_flag |= 0x30000000;
      return 1;
    }
    else if (strstr(&cmd[1], "set nolist")) {
      TT.list = 0;
      TT.vi_mov_flag |= 0x30000000;
      return 1;
    }
  }
  return 0;

}

void vi_main(void)
{
  char keybuf[16];
  char utf8_code[8];
  int utf8_dec_p = 0;
  char vi_buf[16];
  int vi_buf_pos = 0;
  il = xzalloc(sizeof(struct str_line));
  il->str_data = xzalloc(80);
  il->alloc_len = 80;
  keybuf[0] = 0;
  memset(vi_buf, 0, 16);
  memset(utf8_code, 0, 8);
  linelist_load(0);
  scr_r = text;
  c_r = text;
  TT.cur_row = 0;
  TT.cur_col = 0;
  TT.screen_width = 80;
  TT.screen_height = 24;
  TT.vi_mode = 1;
  TT.tabstop = 8;
  yank.data = xzalloc(128);
  yank.alloc = 128;
  terminal_size(&TT.screen_width, &TT.screen_height);
  TT.screen_height -= 2; //TODO this is hack fix visual alignment
  set_terminal(0, 1, 0, 0);
  //writes stdout into different xterm buffer so when we exit
  //we dont get scroll log full of junk
  tty_esc("?1049h");
  tty_esc("H");
  xflush(1);
  TT.vi_mov_flag = 0x20000000;
  draw_page();
  while(1) {
    int key = scan_key(keybuf, -1);

  terminal_size(&TT.screen_width, &TT.screen_height);
  TT.screen_height -= 2; //TODO this is hack fix visual alignment
    // TODO: support cursor keys in ex mode too.
    if (TT.vi_mode && key>=256) {
      key -= 256;
      if (key==KEY_UP) cur_up(1, 1, 0);
      else if (key==KEY_DOWN) cur_down(1, 1, 0);
      else if (key==KEY_LEFT) cur_left(1, 1, 0);
      else if (key==KEY_RIGHT) cur_right(1, 1, 0);
      draw_page();
      continue;
    }

    switch (key) {
      case -1:
      case 3:
      case 4:
        goto cleanup_vi;
    }
    if (TT.vi_mode == 1) { //NORMAL
      switch (key) {
        case '/':
        case '?':
        case ':':
          TT.vi_mode = 0;
          il->str_data[0]=key;
          il->str_len++;
          break;
        case 'A':
          vi_eol(1, 1, 0);
          // FALLTHROUGH
        case 'a':
          if (c_r && c_r->line->str_len) TT.cur_col++;
          // FALLTHROUGH
        case 'i':
          TT.vi_mode = 2;
          break;
        case 27:
          vi_buf[0] = 0;
          vi_buf_pos = 0;
          break;
        default:
          if (key > 0x20 && key < 0x7B) {
            vi_buf[vi_buf_pos] = key;//TODO handle input better
            vi_buf_pos++;
            if (run_vi_cmd(vi_buf)) {
              memset(vi_buf, 0, 16);
              vi_buf_pos = 0;
            }
            else if (vi_buf_pos == 16) {
              vi_buf_pos = 0;
              memset(vi_buf, 0, 16);
            }

          }

          break;
      }
    } else if (TT.vi_mode == 0) { //EX MODE
      switch (key) {
        case 0x7F:
        case 0x08:
          if (il->str_len > 1) {
            il->str_data[--il->str_len] = 0;
            break;
          }
          // FALLTHROUGH
        case 27:
          TT.vi_mode = 1;
          il->str_len = 0;
          memset(il->str_data, 0, il->alloc_len);
          break;
        case 0x0D:
          if (run_ex_cmd(il->str_data) == -1)
            goto cleanup_vi;
          TT.vi_mode = 1;
          il->str_len = 0;
          memset(il->str_data, 0, il->alloc_len);
          break;
        default: //add chars to ex command until ENTER
          if (key >= 0x20 && key < 0x7F) { //might be utf?
            if (il->str_len == il->alloc_len) {
              il->str_data = realloc(il->str_data, il->alloc_len*2);
              il->alloc_len *= 2;
            }
            il->str_data[il->str_len] = key;
            il->str_len++;
          }
          break;
      }
    } else if (TT.vi_mode == 2) {//INSERT MODE
      switch (key) {
        case 27:
          i_insert(il->str_data, il->str_len);
          TT.vi_mode = 1;
          il->str_len = 0;
          memset(il->str_data, 0, il->alloc_len);
          break;
        case 0x7F:
        case 0x08:
          if (il->str_len)
            il->str_data[il->str_len--] = 0;
          break;
        case 0x09:
          il->str_data[il->str_len++] = '\t';
          break;

        case 0x0D:
          //insert newline
          //
          i_insert(il->str_data, il->str_len);
          il->str_len = 0;
          memset(il->str_data, 0, il->alloc_len);
          i_split();
          break;
        default:
          if (key >= 0x20 && utf8_dec(key, utf8_code, &utf8_dec_p)) {
            if (il->str_len+utf8_dec_p+1 >= il->alloc_len) {
              il->str_data = realloc(il->str_data, il->alloc_len*2);
              il->alloc_len *= 2;
            }
            strcpy(il->str_data+il->str_len, utf8_code);
            il->str_len += utf8_dec_p;
            utf8_dec_p = 0;
            *utf8_code = 0;

          }
          break;
      }
    }

    draw_page();

  }
cleanup_vi:
  linelist_unload();
  tty_reset();
  tty_esc("?1049l");
}

int vi_crunch(FILE* out, int cols, int wc)
{
  int ret = 0;
  if (wc < 32 && TT.list) {
    tty_esc("1m");
    ret = crunch_escape(out,cols,wc);
    tty_esc("m");
  } else if (wc == 0x09) {
    if (out) {
      int i = TT.tabstop;
      for (;i--;) fputs(" ", out);
    }
    ret = TT.tabstop;
  }
  return ret;
}

//crunch_str with n bytes restriction for printing substrings or
//non null terminated strings
int crunch_nstr(char **str, int width, int n, FILE *out, char *escmore,
  int (*escout)(FILE *out, int cols, int wc))
{
  int columns = 0, col, bytes;
  char *start, *end;

  for (end = start = *str; *end && n>0; columns += col, end += bytes, n -= bytes) {
    wchar_t wc;

    if ((bytes = utf8towc(&wc, end, 4))>0 && (col = wcwidth(wc))>=0) {
      if (!escmore || wc>255 || !strchr(escmore, wc)) {
        if (width-columns<col) break;
        if (out) fwrite(end, bytes, 1, out);

        continue;
      }
    }

    if (bytes<1) {
      bytes = 1;
      wc = *end;
    }
    col = width-columns;
    if (col<1) break;
    if (escout) {
      if ((col = escout(out, col, wc))<0) break;
    } else if (out) fwrite(end, 1, bytes, out);
  }
  *str = end;

  return columns;
}

static void draw_page()
{
  struct linelist *scr_buf = 0;
  unsigned y = 0;
  int x = 0;

  char *line = 0, *end = 0;
  int utf_l = 0,  bytes = 0;

  //screen coordinates for cursor
  int cy_scr = 0, cx_scr = 0;

  //variables used only for cursor handling
  int aw = 0, iw = 0, clip = 0, margin = 8;

  int scroll = 0, redraw = 0;

  adjust_screen_buffer();
  scr_buf = scr_r;
  redraw = (TT.vi_mov_flag & 0x30000000)>>28;

  scroll = TT.drawn_row-TT.scr_row;
  if (TT.drawn_row<0 || TT.cur_row<0 || TT.scr_row<0) redraw = 3;
  else if (abs(scroll)>TT.screen_height/2) redraw = 3;

  tty_jump(0, 0);
  if (redraw&2) tty_esc("2J"), tty_esc("H");   //clear screen
  else if (scroll>0) printf("\033[%dL", scroll);  //scroll up
  else if (scroll<0) printf("\033[%dM", -scroll); //scroll down

  //jump until cursor
  for (; y < TT.screen_height; y++ ) {
    if (scr_buf == c_r) break;
    scr_buf = scr_buf->down;
  }
  //draw cursor row
  /////////////////////////////////////////////////////////////
  //for long lines line starts to scroll when cursor hits margin
  line = scr_buf->line->str_data;
  bytes = TT.cur_col;
  end = line;


  tty_jump(0, y);
  tty_esc("2K");
  //find cursor position
  aw = crunch_nstr(&end, 1024, bytes, 0, "\t", vi_crunch);

  //if we need to render text that is not inserted to buffer yet
  if (TT.vi_mode == 2 && il->str_len) {
    char* iend = il->str_data; //input end
    x = 0;
    //find insert end position
    iw = crunch_str(&iend, 1024, 0, "\t", vi_crunch);
    clip = (aw+iw) - TT.screen_width+margin;

    //if clipped area is bigger than text before insert
    if (clip > aw) {
      clip -= aw;
      iend = il->str_data;

      iw -= crunch_str(&iend, clip, 0, "\t", vi_crunch);
      x = crunch_str(&iend, iw, stdout, "\t", vi_crunch);
    } else {
      iend = il->str_data;
      end = line;

      //if clipped area is substring from cursor row start
      aw -= crunch_nstr(&end, clip, bytes, 0, "\t", vi_crunch);
      x = crunch_str(&end, aw,  stdout, "\t", vi_crunch);
      x += crunch_str(&iend, iw, stdout, "\t", vi_crunch);
    }
  }
  //when not inserting but still need to keep cursor inside screen
  //margin area
  else if ( aw+margin > TT.screen_width) {
    clip = aw-TT.screen_width+margin;
    end = line;
    aw -= crunch_nstr(&end, clip, bytes, 0, "\t", vi_crunch);
    x = crunch_str(&end, aw,  stdout, "\t", vi_crunch);
  }
  else {
    end = line;
    x = crunch_nstr(&end, aw, bytes, stdout, "\t", vi_crunch);
  }
  cx_scr = x;
  cy_scr = y;
  if (scr_buf->line->str_len > bytes) {
    x += crunch_str(&end, TT.screen_width-x,  stdout, "\t", vi_crunch);
  }

  if (scr_buf) scr_buf = scr_buf->down;
  // drawing cursor row ends
  ///////////////////////////////////////////////////////////////////

  //start drawing all other rows that needs update
  ///////////////////////////////////////////////////////////////////
  y = 0, scr_buf = scr_r;

  //if we moved around in long line might need to redraw everything
  if (clip != TT.drawn_col) redraw = 3;

  for (; y < TT.screen_height; y++ ) {
    int draw_line = 0;
    if (scr_buf == c_r) {
      scr_buf = scr_buf->down;
      continue;
    } else if (redraw) draw_line++;
    else if (scroll<0 && TT.screen_height-y-1<-scroll)
      scroll++, draw_line++;
    else if (scroll>0) scroll--, draw_line++;

    tty_jump(0, y);
    if (draw_line) {

      tty_esc("2K");
      if (scr_buf) {
        if (draw_line && scr_buf->line->str_data && scr_buf->line->str_len) {
          line = scr_buf->line->str_data;
          bytes = scr_buf->line->str_len;

          aw = crunch_nstr(&line, clip, bytes, 0, "\t", vi_crunch);
          crunch_str(&line, TT.screen_width-1, stdout, "\t", vi_crunch);
          if ( *line ) printf("@");

        }
      } else if (draw_line) printf("~");
    }
    if (scr_buf) scr_buf = scr_buf->down;
  }

  TT.drawn_row = TT.scr_row, TT.drawn_col = clip;

  //finished updating visual area

  tty_jump(0, TT.screen_height);
  tty_esc("2K");
  switch (TT.vi_mode) {
    case 0:
    tty_esc("30;44m");
    printf("COMMAND|");
    break;
    case 1:
    tty_esc("30;42m");
    printf("NORMAL|");
    break;
    case 2:
    tty_esc("30;41m");
    printf("INSERT|");
    break;

  }
  //DEBUG
  tty_esc("m");
  utf_l = utf8_len(&c_r->line->str_data[TT.cur_col]);
  if (utf_l) {
    char t[5] = {0, 0, 0, 0, 0};
    strncpy(t, &c_r->line->str_data[TT.cur_col], utf_l);
    printf("utf: %d %s", utf_l, t);
  }
  printf("| %d, %d\n", cx_scr, cy_scr); //screen coord

  tty_jump(TT.screen_width-12, TT.screen_height);
  printf("| %d, %d\n", TT.cur_row, TT.cur_col);

  tty_esc("m");
  tty_jump(0, TT.screen_height+1);
  tty_esc("2K");
  if (!TT.vi_mode) {
    tty_esc("1m");
    printf("%s", il->str_data);
    tty_esc("m");
  } else tty_jump(cx_scr, cy_scr);

  xflush(1);

}

static void check_cursor_bounds()
{
  if (c_r->line->str_len == 0) {
    TT.cur_col = 0;
    return;
  } else if (c_r->line->str_len-1 < TT.cur_col) TT.cur_col = c_r->line->str_len-1;

  if (TT.cur_col && utf8_width(&c_r->line->str_data[TT.cur_col],
        c_r->line->str_len-TT.cur_col) <= 0)
    TT.cur_col--, check_cursor_bounds();
}

static void adjust_screen_buffer()
{
  //search cursor and screen
  struct linelist *t = text;
  int c = -1, s = -1, i = 0;
  //searching cursor and screen line numbers
  for (;((c == -1) || (s == -1)) && t != 0; i++, t = t->down) {
    if (t == c_r) c = i;
    if (t == scr_r) s = i;
  }
  //adjust screen buffer so cursor is on drawing area
  if (c <= s) scr_r = c_r, s = c; //scroll up
  else {
    //drawing does not have wrapping so no need to check width
    int distance = c-s+1;

    if (distance > (int)TT.screen_height) {
      int adj = distance-TT.screen_height;
      for (;adj; adj--) scr_r = scr_r->down, s++; //scroll down

    }
  }
  TT.cur_row = c, TT.scr_row = s;

}

//return 0 if not ASCII nor UTF-8
//this is not fully tested
//naive implementation with branches
//there is better branchless lookup table versions out there
//1 0xxxxxxx
//2 110xxxxx  10xxxxxx
//3 1110xxxx  10xxxxxx  10xxxxxx
//4 11110xxx  10xxxxxx  10xxxxxx  10xxxxxx
static int utf8_len(char *str)
{
  int len = 0;
  int i = 0;
  uint8_t *c = (uint8_t*)str;
  if (!c || !(*c)) return 0;
  if (*c < 0x7F) return 1;
  if ((*c & 0xE0) == 0xc0) len = 2;
  else if ((*c & 0xF0) == 0xE0 ) len = 3;
  else if ((*c & 0xF8) == 0xF0 ) len = 4;
  else return 0;
  c++;
  for (i = len-1; i > 0; i--) {
    if ((*c++ & 0xc0) != 0x80) return 0;
  }
  return len;
}

//get utf8 length and width at same time
static int utf8_lnw(int* width, char* str, int bytes)
{
  wchar_t wc;
  int length = 1;
  *width = 1;
  if (*str == 0x09) {
    *width = TT.tabstop;
    return 1;
  }
  length = mbtowc(&wc, str, bytes);
  switch (length) {
  case -1:
    mbtowc(0,0,4);
  case 0:
    *width = 0;
    length = 0;
    break;
  default:
  *width = wcwidth(wc);
  }
  return length;
}

//try to estimate width of next "glyph" in terminal buffer
//combining chars 0x300-0x36F shall be zero width
static int utf8_width(char *str, int bytes)
{
  wchar_t wc;
  if (*str == 0x09) return TT.tabstop;
  switch (mbtowc(&wc, str, bytes)) {
  case -1:
    mbtowc(0,0,4);
  case 0:
    return -1;
  default:
  return wcwidth(wc);
  }
  return 0;
}

static int utf8_dec(char key, char *utf8_scratch, int *sta_p)
{
  int len = 0;
  char *c = utf8_scratch;
  c[*sta_p] = key;
  if (!(*sta_p))  *c = key;
  if (*c < 0x7F) { *sta_p = 1; return 1; }
  if ((*c & 0xE0) == 0xc0) len = 2;
  else if ((*c & 0xF0) == 0xE0 ) len = 3;
  else if ((*c & 0xF8) == 0xF0 ) len = 4;
  else {*sta_p = 0; return 0; }

  (*sta_p)++;

  if (*sta_p == 1) return 0;
  if ((c[*sta_p-1] & 0xc0) != 0x80) {*sta_p = 0; return 0; }

  if (*sta_p == len) { c[(*sta_p)] = 0; return 1; }

  return 0;
}

static char* utf8_last(char* str, int size)
{
  char* end = str+size;
  int pos = size;
  int len = 0;
  int width = 0;
  while (pos >= 0) {
    len = utf8_lnw(&width, end, size-pos);
    if (len && width) return end;
    end--; pos--;
  }
  return 0;
}

static int cur_left(int count0, int count1, char* unused)
{
  int count = count0*count1;
  TT.vi_mov_flag |= 0x80000000;
  for (;count--;) {
    if (!TT.cur_col) return 1;

    TT.cur_col--;
    check_cursor_bounds();
  }
  return 1;
}

static int cur_right(int count0, int count1, char* unused)
{
  int count = count0*count1;
  for (;count--;) {
    if (c_r->line->str_len <= 1) return 1;
    if (TT.cur_col >= c_r->line->str_len-1) {
      TT.cur_col = utf8_last(c_r->line->str_data, c_r->line->str_len)
        - c_r->line->str_data;
      return 1;
    }
    TT.cur_col++;
    if (utf8_width(&c_r->line->str_data[TT.cur_col],
          c_r->line->str_len-TT.cur_col) <= 0)
      cur_right(1, 1, 0);
  }
  return 1;
}

static int cur_up(int count0, int count1, char* unused)
{
  int count = count0*count1;
  for (;count-- && c_r->up;)
    c_r = c_r->up;

  TT.vi_mov_flag |= 0x80000000;
  check_cursor_bounds();
  return 1;
}

static int cur_down(int count0, int count1, char* unused)
{
  int count = count0*count1;
  for (;count-- && c_r->down;)
    c_r = c_r->down;

  check_cursor_bounds();
  return 1;
}

