// File: andrakis[P]alisp/contrib/linenoise-ng/src/linenoise.cpp
// Function: dynamicRefresh(PromptBase&, char32_t*, int, int)
static void dynamicRefresh(PromptBase& pi, char32_t* buf32, int len, int pos) {
  // calculate the position of the end of the prompt
  int xEndOfPrompt, yEndOfPrompt;
  calculateScreenPosition(0, 0, pi.promptScreenColumns, pi.promptChars,
                          xEndOfPrompt, yEndOfPrompt);
  pi.promptIndentation = xEndOfPrompt;

  // calculate the position of the end of the input line
  int xEndOfInput, yEndOfInput;
  calculateScreenPosition(xEndOfPrompt, yEndOfPrompt, pi.promptScreenColumns,
                          calculateColumnPosition(buf32, len), xEndOfInput,
                          yEndOfInput);

  // calculate the desired position of the cursor
  int xCursorPos, yCursorPos;
  calculateScreenPosition(xEndOfPrompt, yEndOfPrompt, pi.promptScreenColumns,
                          calculateColumnPosition(buf32, pos), xCursorPos,
                          yCursorPos);

#ifdef _WIN32
  // position at the start of the prompt, clear to end of previous input
  CONSOLE_SCREEN_BUFFER_INFO inf;
  GetConsoleScreenBufferInfo(console_out, &inf);
  inf.dwCursorPosition.X = 0;
  inf.dwCursorPosition.Y -= pi.promptCursorRowOffset /*- pi.promptExtraLines*/;
  SetConsoleCursorPosition(console_out, inf.dwCursorPosition);
  DWORD count;
  FillConsoleOutputCharacterA(console_out, ' ',
                              pi.promptPreviousLen + pi.promptPreviousInputLen,
                              inf.dwCursorPosition, &count);
  pi.promptPreviousLen = pi.promptIndentation;
  pi.promptPreviousInputLen = len;

  // display the prompt
  if (!pi.write()) return;

  // display the input line
  if (write32(1, buf32, len) == -1) return;

  // position the cursor
  GetConsoleScreenBufferInfo(console_out, &inf);
  inf.dwCursorPosition.X = xCursorPos;  // 0-based on Win32
  inf.dwCursorPosition.Y -= yEndOfInput - yCursorPos;
  SetConsoleCursorPosition(console_out, inf.dwCursorPosition);
#else  // _WIN32
  char seq[64];
  int cursorRowMovement = pi.promptCursorRowOffset - pi.promptExtraLines;
  if (cursorRowMovement > 0) {  // move the cursor up as required
    snprintf(seq, sizeof seq, "\x1b[%dA", cursorRowMovement);
    if (write(1, seq, strlen(seq)) == -1) return;
  }
  // position at the start of the prompt, clear to end of screen
  snprintf(seq, sizeof seq, "\x1b[1G\x1b[J");  // 1-based on VT100
  if (write(1, seq, strlen(seq)) == -1) return;

  // display the prompt
  if (!pi.write()) return;

  // display the input line
  if (write32(1, buf32, len) == -1) return;

  // we have to generate our own newline on line wrap
  if (xEndOfInput == 0 && yEndOfInput > 0)
    if (write(1, "\n", 1) == -1) return;

  // position the cursor
  cursorRowMovement = yEndOfInput - yCursorPos;
  if (cursorRowMovement > 0) {  // move the cursor up as required
    snprintf(seq, sizeof seq, "\x1b[%dA", cursorRowMovement);
    if (write(1, seq, strlen(seq)) == -1) return;
  }
  // position the cursor within the line
  snprintf(seq, sizeof seq, "\x1b[%dG", xCursorPos + 1);  // 1-based on VT100
  if (write(1, seq, strlen(seq)) == -1) return;
#endif

  pi.promptCursorRowOffset =
      pi.promptExtraLines + yCursorPos;  // remember row for next pass
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movl 0x34(%rax), %edx
movq -0x8(%rbp), %rax
movl 0x18(%rax), %ecx
xorl %esi, %esi
leaq -0x1c(%rbp), %r8
leaq -0x20(%rbp), %r9
movl %esi, %edi
callq 0x1d7f0
movl -0x1c(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x24(%rax)
movl -0x1c(%rbp), %eax
movl %eax, -0x8c(%rbp)
movl -0x20(%rbp), %eax
movl %eax, -0x88(%rbp)
movq -0x8(%rbp), %rax
movl 0x34(%rax), %eax
movl %eax, -0x84(%rbp)
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x1d8a0
movl -0x8c(%rbp), %edi
movl -0x88(%rbp), %esi
movl -0x84(%rbp), %edx
movl %eax, %ecx
leaq -0x24(%rbp), %r8
leaq -0x28(%rbp), %r9
callq 0x1d7f0
movl -0x1c(%rbp), %eax
movl %eax, -0x80(%rbp)
movl -0x20(%rbp), %eax
movl %eax, -0x7c(%rbp)
movq -0x8(%rbp), %rax
movl 0x34(%rax), %eax
movl %eax, -0x78(%rbp)
movq -0x10(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0x1d8a0
movl -0x80(%rbp), %edi
movl -0x7c(%rbp), %esi
movl -0x78(%rbp), %edx
movl %eax, %ecx
leaq -0x2c(%rbp), %r8
leaq -0x30(%rbp), %r9
callq 0x1d7f0
movq -0x8(%rbp), %rax
movl 0x30(%rax), %eax
movq -0x8(%rbp), %rcx
subl 0x20(%rcx), %eax
movl %eax, -0x74(%rbp)
cmpl $0x0, -0x74(%rbp)
jle 0x1fd5e
leaq -0x70(%rbp), %rdi
movl -0x74(%rbp), %ecx
movl $0x40, %esi
leaq 0x1ccc2(%rip), %rdx     # 0x3c9e4
movb $0x0, %al
callq 0x86f0
leaq -0x70(%rbp), %rax
movq %rax, -0x98(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x8210
movq -0x98(%rbp), %rsi
movq %rax, %rdx
movl $0x1, %edi
callq 0x8190
cmpq $-0x1, %rax
jne 0x1fd5c
jmp 0x1febd
jmp 0x1fd5e
leaq -0x70(%rbp), %rdi
movl $0x40, %esi
leaq 0x1ceef(%rip), %rdx     # 0x3cc5d
movb $0x0, %al
callq 0x86f0
leaq -0x70(%rbp), %rax
movq %rax, -0xa0(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x8210
movq -0xa0(%rbp), %rsi
movq %rax, %rdx
movl $0x1, %edi
callq 0x8190
cmpq $-0x1, %rax
jne 0x1fda8
jmp 0x1febd
movq -0x8(%rbp), %rdi
callq 0x23ee0
testb $0x1, %al
jne 0x1fdba
jmp 0x1febd
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movl $0x1, %edi
callq 0x1d8e0
cmpl $-0x1, %eax
jne 0x1fdd5
jmp 0x1febd
cmpl $0x0, -0x24(%rbp)
jne 0x1fe04
cmpl $0x0, -0x28(%rbp)
jle 0x1fe04
movl $0x1, %edi
leaq 0x1ce3f(%rip), %rsi     # 0x3cc2c
movl $0x1, %edx
callq 0x8190
cmpq $-0x1, %rax
jne 0x1fe02
jmp 0x1febd
jmp 0x1fe04
movl -0x28(%rbp), %eax
subl -0x30(%rbp), %eax
movl %eax, -0x74(%rbp)
cmpl $0x0, -0x74(%rbp)
jle 0x1fe5f
leaq -0x70(%rbp), %rdi
movl -0x74(%rbp), %ecx
movl $0x40, %esi
leaq 0x1cbbe(%rip), %rdx     # 0x3c9e4
movb $0x0, %al
callq 0x86f0
leaq -0x70(%rbp), %rax
movq %rax, -0xa8(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x8210
movq -0xa8(%rbp), %rsi
movq %rax, %rdx
movl $0x1, %edi
callq 0x8190
cmpq $-0x1, %rax
jne 0x1fe5d
jmp 0x1febd
jmp 0x1fe5f
leaq -0x70(%rbp), %rdi
movl -0x2c(%rbp), %ecx
addl $0x1, %ecx
movl $0x40, %esi
leaq 0x1cb7e(%rip), %rdx     # 0x3c9f3
movb $0x0, %al
callq 0x86f0
leaq -0x70(%rbp), %rax
movq %rax, -0xb0(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x8210
movq -0xb0(%rbp), %rsi
movq %rax, %rdx
movl $0x1, %edi
callq 0x8190
cmpq $-0x1, %rax
jne 0x1feac
jmp 0x1febd
movq -0x8(%rbp), %rax
movl 0x20(%rax), %ecx
addl -0x30(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x30(%rax)
addq $0xb0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)