// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2009 Corey Tabaka
// Copyright (c) 2016 Travis Geiselbrecht
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#if WITH_LEGACY_PC_CONSOLE

#include <lib/io.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <arch/kernel_aspace.h>
#include <arch/x86.h>
#include <platform/console.h>
#include <platform/pc.h>

/* memory mapped framebuffer */
#define FB (0xB8000U + KERNEL_ASPACE_BASE)

/* CGA values */
#define CURSOR_START 0x0A
#define CURSOR_END 0x0B
#define VIDEO_ADDRESS_MSB 0x0C
#define VIDEO_ADDRESS_LSB 0x0D
#define CURSOR_POS_MSB 0x0E
#define CURSOR_POS_LSB 0x0F

/* curr settings */
static unsigned char curr_x;
static unsigned char curr_y;
static unsigned char curr_start;
static unsigned char curr_end;
static unsigned char curr_attr = 0x7;

/* video page buffer */
#define VPAGE_SIZE 2048
#define PAGE_MAX 8

static int active_page = 0;
static int visual_page = 0;

static int curs_x[PAGE_MAX];
static int curs_y[PAGE_MAX];

static struct { int x1, y1, x2, y2; } view_window = {0, 0, 79, 24};

void platform_init_console(void) {
  curr_save();
  window(0, 0, 79, 24);
  clear();
  place(0, 0);
}

void set_visual_page(int page) {
  unsigned short page_offset = page * VPAGE_SIZE;
  visual_page = page;

  outp(CGA_INDEX_REG, VIDEO_ADDRESS_LSB);
  outp(CGA_DATA_REG, page_offset & 0xFF);
  outp(CGA_INDEX_REG, VIDEO_ADDRESS_MSB);
  outp(CGA_DATA_REG, (page_offset >> 8) & 0xFF);
}

void set_active_page(int page) {
  curs_x[active_page] = curr_x;
  curs_y[active_page] = curr_y;
  curr_x = curs_x[page];
  curr_y = curs_y[page];
  active_page = page;
}

int get_visual_page(void) { return visual_page; }

int get_active_page(void) { return active_page; }

void place(int x, int y) {
  unsigned short cursor_word = x + y * 80 + active_page * VPAGE_SIZE;

  /*
   * program CGA using index reg, then data reg
   */
  outp(CGA_INDEX_REG, CURSOR_POS_LSB);
  outp(CGA_DATA_REG, cursor_word & 0xFF);
  outp(CGA_INDEX_REG, CURSOR_POS_MSB);
  outp(CGA_DATA_REG, (cursor_word >> 8) & 0xFF);

  curr_x = x;
  curr_y = y;
}

void cursor(int start, int end) {
  outp(CGA_INDEX_REG, CURSOR_START);
  outp(CGA_DATA_REG, start);
  outp(CGA_INDEX_REG, CURSOR_END);
  outp(CGA_DATA_REG, end);
}

void curr_save(void) {
#if 0
    /* grab some info from the bios data area (these should be defined in memmap.h */
    curr_attr = *((unsigned char *)FB + 159);
    curr_x = *((unsigned char *)0x00450);
    curr_y = *((unsigned char *)0x00451);
    curr_end = *((unsigned char *)0x00460);
    curr_start = *((unsigned char *)0x00461);
#endif
  active_page = visual_page = 0;
}

void curr_restore(void) {
#if 0
    *((unsigned char *)0x00450) = curr_x;
    *((unsigned char *)0x00451) = curr_y;
#endif

  place(curr_x, curr_y);
  cursor(curr_start, curr_end);
}

void window(int x1, int y1, int x2, int y2) {
  view_window.x1 = x1;
  view_window.y1 = y1;
  view_window.x2 = x2;
  view_window.y2 = y2;

  // place(x1, y1);
}

void _clear(char c, char attr, int x1, int y1, int x2, int y2) {
  register int i, j;
  unsigned short w = attr;

  w <<= 8;
  w |= c;
  for (i = x1; i <= x2; i++) {
    for (j = y1; j <= y2; j++) {
      *((unsigned short*)(uintptr_t)(FB + 2 * i + 160 * j + 2 * active_page * VPAGE_SIZE)) = w;
    }
  }

  place(x1, y1);
  curr_y = y1;
  curr_x = x1;
}

void clear() {
  _clear(' ', curr_attr, view_window.x1, view_window.y1, view_window.x2, view_window.y2);
}

void _scroll(char attr, int x1, int y1, int x2, int y2) {
  register int x, y;
  unsigned short xattr = attr << 8, w;
  unsigned char* v = (unsigned char*)(uintptr_t)(FB + active_page * (2 * VPAGE_SIZE));

  for (y = y1 + 1; y <= y2; y++) {
    for (x = x1; x <= x2; x++) {
      w = *((unsigned short*)(v + 2 * (y * 80 + x)));
      *((unsigned short*)(v + 2 * ((y - 1) * 80 + x))) = w;
    }
  }

  for (x = x1; x <= x2; x++) {
    *((unsigned short*)(v + 2 * ((y - 1) * 80 + x))) = xattr;
  }
}

void scroll(void) {
  _scroll(curr_attr, view_window.x1, view_window.y1, view_window.x2, view_window.y2);
}

void cputc(char c) {
  static unsigned short scan_x, x, y;
  unsigned char* v = (unsigned char*)(uintptr_t)(FB + active_page * (2 * VPAGE_SIZE));
  x = curr_x;
  y = curr_y;

  switch (c) {
    case '\t':
      x += 8;
      if (x >= view_window.x2 + 1) {
        x = view_window.x1;
        if (y == view_window.y2) {
          scroll();
        } else {
          y++;
        }
      } else {
        scan_x = 0;

        while ((scan_x + 8) < x) {
          scan_x += 8;
        }

        x = scan_x;
      }
      break;

    case '\r':
      x = view_window.x1;
      break;

    case '\n':
      if (y == view_window.y2) {
        scroll();
      } else {
        y++;
      }
      break;

    case '\b':
      x--;
      break;

    default:
      *(v + 2 * (x + y * 80)) = c;
      x++;

      if (x >= view_window.x2 + 1) {
        x = view_window.x1;
        if (y == view_window.y2) {
          scroll();
        } else {
          y++;
        }
      }
  }

  place(x, y);
}

void cputs(char* s) {
  char c;
  while (*s != '\0') {
    c = *s++;
    cputc(c);
  }
}

void puts_xy(int x, int y, char attr, char* s) {
  unsigned char* v =
      (unsigned char*)(uintptr_t)(FB + (80 * y + x) * 2 + active_page * (2 * VPAGE_SIZE));
  while (*s != 0) {
    *v = *s;
    s++;
    v++;
    *v = attr;
    v++;
  }
}

void putc_xy(int x, int y, char attr, char c) {
  unsigned char* v =
      (unsigned char*)(uintptr_t)(FB + (80 * y + x) * 2 + active_page * (2 * VPAGE_SIZE));
  *v = c;
  v++;
  *v = attr;
}

int printf_xy(int x, int y, char attr, char* fmt, ...) {
  char cbuf[200];
  va_list parms;
  int result;

  va_start(parms, fmt);
  result = vsnprintf(cbuf, sizeof(cbuf), fmt, parms);
  va_end(parms);

  puts_xy(x, y, attr, cbuf);

  return result;
}

#endif
