/* 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. 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
    Pg Up/Pg Dn   Move up/down by one page
    0-9, a-f      Change current half-byte to hexadecimal value
    u             Undo
    q/^c/^d/<esc> Quit
*/

#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 int draw_char(FILE *fp, wchar_t broiled)
{
  if (fp) {
    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", (int)broiled);
      tty_esc("0m");
    } else printf("%c", (int)broiled);
  }

  return 1;
}

static void draw_tail(void)
{
  tty_jump(0, TT.height);
  tty_esc("K");

  draw_trim(*toys.optargs, -1, 71);
}

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(stdout, 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(stdout, 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];

  *keybuf = 0;

  // 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);
  xset_terminal(1, 1, 0);

  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 (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);
    xflush();

    // 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];
      }
    }
    if (key>=256) {
      key -= 256;

      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();
}
