/* hexedit.c - Hexadecimal file editor
 *
 * Copyright 2015 Rob Landley <rob@landley.net>
 *
 * No standard

USE_HEXEDIT(NEWTOY(hexedit, "<1>1r", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))

config HEXEDIT
  bool "hexedit"
  default y
  help
    usage: hexedit FILE

    Hexadecimal file editor/viewer. All changes are written to disk immediately.

    -r	Read only (display but don't edit)

    Keys:
    Arrows         Move left/right/up/down by one line/column
    PgUp/PgDn      Move up/down by one page
    Home/End       Start/end of line (start/end of file with ctrl)
    0-9, a-f       Change current half-byte to hexadecimal value
    ^J or :        Jump (+/- for relative offset, otherwise absolute address)
    ^F or /        Find string (^G/n: next, ^D/p: previous match)
    u              Undo
    x              Toggle bw/color display
    q/^C/^Q/Esc    Quit
*/

#define FOR_hexedit
#include "toys.h"

GLOBALS(
  char *data, *search, keybuf[16], input[80];
  long long len, base, pos;
  int numlen, undo, undolen, mode;
  unsigned rows, cols;
)

#define UNDO_LEN (sizeof(toybuf)/(sizeof(long long)+1))

static void show_error(char *what)
{
  tty_jump(0, TT.rows);
  printf("\e[41m\e[37m\e[K\e[1m%s\e[0m", what);
  xflush(1);
  msleep(500);
}

// TODO: support arrow keys, insertion, and scrolling (and reuse in vi)
static int prompt(char *prompt, char *initial_value)
{
  int yes = 0, key, len = strlen(initial_value);

  strcpy(TT.input, initial_value);
  while (1) {
    tty_jump(0, TT.rows);
    tty_esc("K");
    printf("\e[1m%s: \e[0m%s", prompt, TT.input);
    tty_esc("?25h");
    xflush(1);

    key = scan_key(TT.keybuf, -1);
    if (key < 0 || key == 27) break;
    if (key == '\r') {
      yes = len; // Hitting enter with no input counts as cancellation.
      break;
    }

    if (key == 0x7f && (len > 0)) TT.input[--len] = 0;
    else if (key == 'U'-'@') while (len > 0) TT.input[--len] = 0;
    else if (key >= ' ' && key < 0x7f && len < sizeof(TT.input))
      TT.input[len++] = key;
  }

  tty_esc("?25l");
  return yes;
}

// Render all characters printable, using color to distinguish.
static void draw_char(int ch)
{
  if (ch >= ' ' && ch < 0x7f) {
    putchar(ch);
    return;
  }

  if (TT.mode) {
    if (ch>127) {
      tty_esc("2m");
      ch &= 127;
    }
    if (ch<32 || ch==127) {
      tty_esc("7m");
      if (ch==127) ch = 32;
      else ch += 64;
    }
    xputc(ch);
  } else {
    if (ch < ' ') printf("\e[31m%c", ch + '@');
    else tty_esc("35m?");
  }
  tty_esc("0m");
}

static void draw_status(void)
{
  char line[80];

  tty_jump(0, TT.rows);
  tty_esc("K");

  snprintf(line, sizeof(line), "\"%s\"%s, %#llx/%#llx", *toys.optargs,
    FLAG(r) ? " [readonly]" : "", TT.pos, TT.len);
  draw_trim(line, -1, TT.cols);
}

static void draw_byte(int byte)
{
  if (byte) printf("%02x", byte);
  else printf("\e[2m00\e[0m");
}

static void draw_line(long long yy)
{
  int x, xx = 16;

  yy = (TT.base+yy)*16;
  if (yy+xx>=TT.len) xx = TT.len-yy;

  if (yy<TT.len) {
    printf("\r\e[%dm%0*llx\e[0m ", 33*!TT.mode, TT.numlen, yy);
    for (x=0; x<xx; x++) {
      putchar(' ');
      draw_byte(TT.data[yy+x]);
    }
    printf("%*s", 2+3*(16-xx), "");
    for (x=0; x<xx; x++) draw_char(TT.data[yy+x]);
    printf("%*s", 16-xx, "");
  }
  tty_esc("K");
}

static void draw_page(void)
{
  int y;

  tty_jump(0, 0);
  for (y = 0; y<TT.rows; y++) {
    if (y) printf("\r\n");
    draw_line(y);
  }
  draw_status();
}

// side: 0 = editing left, 1 = editing right, 2 = clear, 3 = read only
static void highlight(int xx, int yy, int side)
{
  char cc = TT.data[16*(TT.base+yy)+xx];
  int i;

  // Display cursor in hex area.
  tty_jump(2+TT.numlen+3*xx, yy);
  tty_esc("0m");
  if (side!=2) tty_esc("7m");
  if (side>1) draw_byte(cc);
  else for (i=0; i<2;) {
    if (side==i) tty_esc("32m");
    printf("%x", (cc>>(4*(1&++i)))&15);
  }
  tty_jump(TT.numlen+17*3+xx, yy);

  // Display cursor in text area.
  if (side!=2) tty_esc("7m");
  draw_char(cc);
}

static void find_next(int pos)
{
  char *p;

  p = memmem(TT.data+pos, TT.len-pos, TT.search, strlen(TT.search));
  if (p) TT.pos = p - TT.data;
  else show_error("No match!");
}

static void find_prev(int pos)
{
  size_t len = strlen(TT.search);

  for (; pos >= 0; pos--) {
    if (!memcmp(TT.data+pos, TT.search, len)) {
      TT.pos = pos;
      return;
    }
  }
  show_error("No match!");
}

void hexedit_main(void)
{
  long long y;
  int x, i, side = 0, key, fd;

  // Terminal setup
  TT.cols = 80;
  TT.rows = 24;
  terminal_size(&TT.cols, &TT.rows);
  if (TT.rows) TT.rows--;
  xsignal(SIGWINCH, generic_signal);
  sigatexit(tty_sigreset);
  tty_esc("0m");
  tty_esc("?25l");
  xflush(1);
  xset_terminal(1, 1, 0, 0);

  if (access(*toys.optargs, W_OK)) toys.optflags |= FLAG_r;
  fd = xopen(*toys.optargs, FLAG(r) ? O_RDONLY : O_RDWR);
  if ((TT.len = fdlength(fd))<1) error_exit("bad length");
  if (sizeof(long)==32 && TT.len>SIZE_MAX) TT.len = SIZE_MAX;
  // count file length hex in digits, rounded up to multiple of 4
  for (TT.pos = TT.len, TT.numlen = 0; TT.pos; TT.pos >>= 4, TT.numlen++);
  TT.numlen += (4-TT.numlen)&3;

  TT.data=xmmap(0, TT.len, PROT_READ|(PROT_WRITE*!FLAG(r)), MAP_SHARED, fd, 0);
  close(fd);
  draw_page();

  for (;;) {
    // Scroll display if necessary
    if (TT.pos<0) TT.pos = 0;
    if (TT.pos>=TT.len) TT.pos = TT.len-1;
    x = TT.pos&15;
    y = TT.pos/16;

    while (y<TT.base) {
      if (TT.base-y>(TT.rows/2)) {
        TT.base = y;
        draw_page();
      } else {
        TT.base--;
        tty_jump(0, 0);
        tty_esc("1L");
        draw_line(0);
      }
    }
    while (y>=TT.base+TT.rows) {
      if (y-(TT.base+TT.rows)>(TT.rows/2)) {
        TT.base = y-TT.rows-1;
        draw_page();
      } else {
        TT.base++;
        tty_jump(0, 0);
        tty_esc("1M");
        tty_jump(0, TT.rows-1);
        draw_line(TT.rows-1);
      }
    }
    draw_status();
    y -= TT.base;

    // Display cursor and flush output
    highlight(x, y, FLAG(r) ? 3 : side);
    xflush(1);

    // Wait for next key
    key = scan_key(TT.keybuf, -1);

    // Window resized?
    if (key == -3) {
      toys.signal = 0;
      terminal_size(&TT.cols, &TT.rows);
      if (TT.rows) TT.rows--;
      draw_page();
      continue;
    }

    if (key == 'x') {
      TT.mode = !TT.mode;
      tty_esc("0m");
      draw_page();
      continue;
    }

    // Various popular ways to quit...
    if (key==-1||key==('C'-'@')||key==('Q'-'@')||key==27||key=='q') break;
    highlight(x, y, 2);

    if (key == ('J'-'@') || key == ':' || key == '-' || key == '+') {
      // Jump (relative or absolute)
      char initial[2] = {}, *s = 0;
      long long val;

      if (key == '-' || key == '+') *initial = key;
      if (!prompt("Jump to", initial)) continue;

      val = estrtol(TT.input, &s, 0);
      if (!errno && s && !*s) {
        if (*TT.input == '-' || *TT.input == '+') TT.pos += val;
        else TT.pos = val;
      }
      continue;
    } else if (key == ('F'-'@') || key == '/') { // Find
      if (!prompt("Find", TT.search ? TT.search : "")) continue;

      // TODO: parse hex escapes in input, and record length to support \0
      free(TT.search);
      TT.search = xstrdup(TT.input);
      find_next(TT.pos);
    } else if (TT.search && (key == ('G'-'@') || key == 'n')) { // Find next
      if (TT.pos < TT.len) find_next(TT.pos+1);
    } else if (TT.search && (key == ('D'-'@') || key == 'p')) { // Find previous
      if (TT.pos > 0) find_prev(TT.pos-1);
    }

    // Remove cursor
    highlight(x, y, 2);

    // Hex digit?
    if (key>='a' && key<='f') key-=32;
    if (!FLAG(r) && ((key>='0' && key<='9') || (key>='A' && key<='F'))) {
      if (!side) {
        long long *ll = (long long *)toybuf;

        ll[TT.undo] = TT.pos;
        toybuf[(sizeof(long long)*UNDO_LEN)+TT.undo++] = TT.data[TT.pos];
        if (TT.undolen < UNDO_LEN) TT.undolen++;
        TT.undo %= UNDO_LEN;
      }

      i = key - '0';
      if (i>9) i -= 7;
      TT.data[TT.pos] &= 15<<(4*side);
      TT.data[TT.pos] |= i<<(4*!side);

      if (++side==2) {
        highlight(x, y, side);
        side = 0;
        ++TT.pos;
      }
    } else side = 0;
    if (key=='u') {
      if (TT.undolen) {
        long long *ll = (long long *)toybuf;

        TT.undolen--;
        if (!TT.undo) TT.undo = UNDO_LEN;
        TT.pos = ll[--TT.undo];
        TT.data[TT.pos] = toybuf[sizeof(long long)*UNDO_LEN+TT.undo];
      }
    }
    if (key>=256) {
      key -= 256;

      if (key==KEY_UP) TT.pos -= 16;
      else if (key==KEY_DOWN) TT.pos += 16;
      else if (key==KEY_RIGHT) {
        if (TT.pos<TT.len) TT.pos++;
      } else if (key==KEY_LEFT) {
        if (TT.pos>0) TT.pos--;
      } else if (key==KEY_PGUP) {
        TT.pos -= 16*TT.rows;
        if (TT.pos < 0) TT.pos = 0;
        TT.base = TT.pos/16;
        draw_page();
      } else if (key==KEY_PGDN) {
        TT.pos += 16*TT.rows;
        if (TT.pos > TT.len-1) TT.pos = TT.len-1;
        TT.base = TT.pos/16;
        draw_page();
      } else if (key==KEY_HOME) TT.pos = TT.pos & ~0xf;
      else if (key==KEY_END) TT.pos = TT.pos | 0xf;
      else if (key==(KEY_CTRL|KEY_HOME)) TT.pos = 0;
      else if (key==(KEY_CTRL|KEY_END)) TT.pos = TT.len-1;
    }
  }
  munmap(TT.data, TT.len);
  tty_reset();
}
