/* 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 FILENAME

    Hexadecimal file editor.

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

#define FOR_hexedit
#include "toys.h"

GLOBALS(
  char *data;
  long long len, base;
  int numlen, undo, undolen;
  unsigned height;
)

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

// Render all characters printable, using color to distinguish.
static void draw_char(char broiled)
{
  if (broiled<32 || broiled>=127) {
    if (broiled>127) {
      tty_esc("2m");
      broiled &= 127;
    }
    if (broiled<32 || broiled==127) {
      tty_esc("7m");
      if (broiled==127) broiled = 32;
      else broiled += 64;
    }
    printf("%c", broiled);
    tty_esc("0m");
  } else printf("%c", broiled);
}

static void draw_tail(void)
{
  int i = 0, width = 0, w, len;
  char *start = *toys.optargs, *end;

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

  // First time, make sure we fit in 71 chars (advancing start as necessary).
  // Second time, print from start to end, escaping nonprintable chars.
  for (i=0; i<2; i++) {
    for (end = start; *end;) {
      wchar_t wc;

      len = mbrtowc(&wc, end, 99, 0);
      if (len<0 || wc<32 || (w = wcwidth(wc))<0) {
        len = w = 1;
        if (i) draw_char(*end);
      } else if (i) fwrite(end, len, 1, stdout);
      end += len;

      if (!i) {
        width += w;
        while (width > 71) {
          len = mbrtowc(&wc, start, 99, 0);
          if (len<0 || wc<32 || (w = wcwidth(wc))<0) len = w = 1;
          width -= w;
          start += len;
        }
      }
    }
  }
}

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%0*llX ", TT.numlen, yy);
    for (x=0; x<xx; x++) printf(" %02X", 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.height; y++) {
    if (y) printf("\r\n");
    draw_line(y);
  }
  draw_tail();
}

// 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
  tty_jump(2+TT.numlen+3*xx, yy);
  tty_esc("0m");
  if (side!=2) tty_esc("7m");
  if (side>1) printf("%02X", cc);
  else for (i=0; i<2;) {
    if (side==i) tty_esc("32m");
    printf("%X", (cc>>(4*(1&++i)))&15);
  }
  tty_esc("0m");
  tty_jump(TT.numlen+17*3+xx, yy);
  draw_char(cc);
}

void hexedit_main(void)
{
  long long pos = 0, y;
  int x, i, side = 0, key, ro = toys.optflags&FLAG_r,
      fd = xopen(*toys.optargs, ro ? O_RDONLY : O_RDWR);
  char keybuf[16];

  // Terminal setup
  TT.height = 25;
  terminal_size(0, &TT.height);
  if (TT.height) TT.height--;
  sigatexit(tty_sigreset);
  tty_esc("0m");
  tty_esc("?25l");
  fflush(0);
  set_terminal(1, 1, 0);

  if ((TT.len = fdlength(fd))<0) 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 (pos = TT.len, TT.numlen = 0; pos; pos >>= 4, TT.numlen++);
  TT.numlen += (4-TT.numlen)&3;

  TT.data = mmap(0, TT.len, PROT_READ|(PROT_WRITE*!ro), MAP_SHARED, fd, 0);
  draw_page();

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

    i = 0;
    while (y<TT.base) {
      if (TT.base-y>(TT.height/2)) {
        TT.base = y;
        draw_page();
      } else {
        TT.base--;
        i++;
        tty_esc("1T");
        tty_jump(0, 0);
        draw_line(0);
      }
    }
    while (y>=TT.base+TT.height) {
      if (y-(TT.base+TT.height)>(TT.height/2)) {
        TT.base = y-TT.height-1;
        draw_page();
      } else {
        TT.base++;
        i++;
        tty_esc("1S");
        tty_jump(0, TT.height-1);
        draw_line(TT.height-1);
      }
    }
    if (i) draw_tail();
    y -= TT.base;

    // Display cursor and flush output
    highlight(x, y, ro ? 3 : side);
    xprintf("");

    // Wait for next key
    key = scan_key(keybuf, 1);
    // Exit for q, ctrl-c, ctrl-d, escape, or EOF
    if (key==-1 || key==3 || key==4 || key==27 || key=='q') break;
    highlight(x, y, 2);

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

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

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

      if (++side==2) {
        highlight(x, y, side);
        side = 0;
        ++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;
        pos = ll[--TT.undo];
        TT.data[pos] = toybuf[sizeof(long long)*UNDO_LEN+TT.undo];
      }
    } else if (key==KEY_UP) pos -= 16;
    else if (key==KEY_DOWN) pos += 16;
    else if (key==KEY_RIGHT) {
      if (x<15) pos++;
    } else if (key==KEY_LEFT) {
      if (x) pos--;
    } else if (key==KEY_PGUP) pos -= 16*TT.height;
    else if (key==KEY_PGDN) pos += 16*TT.height;
    else if (key==KEY_HOME) pos = 0;
    else if (key==KEY_END) pos = TT.len-1;
  }
  munmap(TT.data, TT.len);
  close(fd);
  tty_reset();
}
