#include "display.hpp"

#include "pico/stdlib.h"
#include "hardware/i2c.h"

#include "aps6404.hpp"
#include "swd_load.hpp"
#include "pico-stick.h"

#include "config.h"

// pins
static constexpr uint CS     = 17;
static constexpr uint D0     = 19;
static constexpr uint VSYNC  = 16;
static constexpr uint RAM_SEL = 8;

static constexpr uint I2C_SDA = 6;
static constexpr uint I2C_SCL = 7;

// i2c
static constexpr uint I2C_ADDR = 0x0D;
static constexpr uint I2C_REG_SET_RES = 0xFC;
static constexpr uint I2C_REG_START = 0xFD;
static constexpr uint I2C_REG_STOP = 0xFF;

static constexpr uint32_t base_address = 0x10000;

static const blit::Size resolutions[]{
  {640, 480},
  {720, 480},
  {720, 400},
  {720, 576},
};

static pimoroni::APS6404 ram(CS, D0, pio1);
static uint8_t ram_bank = 0;

static bool display_enabled = false;
static uint8_t need_mode_change = 2;
static int cur_resolution = 0;

static volatile bool do_render = false;

static uint16_t blend_buf[512];

static uint32_t batch_start_addr = 0, batch_next_off = ~0u;
static uint16_t *batch_ptr = nullptr;
static uint16_t *batch_start = nullptr, *batch_end = blend_buf + std::size(blend_buf) / 2;

static void vsync_callback(uint gpio, uint32_t events){
  if(!do_render) {
    ram_bank ^= 1;
    gpio_put(RAM_SEL, ram_bank);

    do_render = true;
  }
}

// these three are copied from blend.cpp
inline uint32_t alpha(uint32_t a1, uint32_t a2) {
  return ((a1 + 1) * (a2 + 1)) >> 8;
}

inline uint32_t alpha(uint32_t a1, uint32_t a2, uint32_t a3) {
  return ((a1 + 1) * (a2 + 1) * (a3 + 1)) >> 16;
}

inline uint8_t blend(uint8_t s, uint8_t d, uint8_t a) {
  return d + ((a * (s - d) + 127) >> 8);
}

inline uint16_t pack_rgb555(uint8_t r, uint8_t g, uint8_t b) {
  return (b >> 3) | ((g >> 3) << 5) | ((r >> 3) << 10);
}

inline void unpack_rgb555(uint16_t rgb555, uint8_t &r, uint8_t &g, uint8_t &b) {
  r = (rgb555 >> 10) & 0x1F; r = r << 3;
  g = (rgb555 >>  5) & 0x1F; g = g << 3;
  b =  rgb555        & 0x1F; b = b << 3;
}

static void flush_batch() {
  if(batch_ptr)
    ram.write(batch_start_addr, (uint32_t *)batch_start, (batch_ptr - batch_start) * 2);

  batch_ptr = nullptr;
  batch_next_off = ~0u;
}

inline void blend_rgba_rgb555(const blit::Pen* s, uint32_t off, uint8_t a, uint32_t c) {
  flush_batch();
  do {
    auto step = std::min(c, uint32_t(std::size(blend_buf)));

    ram.read_blocking(base_address + off * 2, (uint32_t*)blend_buf, (step + 1) >> 1);

    auto *ptr = blend_buf;
    for(unsigned i = 0; i < step; i++) {
      uint8_t r, g, b;
      unpack_rgb555(*ptr, r, g, b);

      *ptr++ = pack_rgb555(blend(s->r, r, a), blend(s->g, g, a), blend(s->b, b, a));
    }

    ram.write(base_address + off * 2, (uint32_t *)blend_buf, step * 2);

    off += step;
    c -= step;
  } while(c);
}

[[gnu::always_inline]]
inline void copy_rgba_rgb555(const blit::Pen* s, uint32_t off, uint32_t c) {
  auto pen555 = pack_rgb555(s->r, s->g, s->b);

  constexpr size_t cache_size = std::size(blend_buf) / 2;

  if(c >= cache_size) {
    // big fill, skip the batch buf
    flush_batch();

    uint32_t val = pen555 | pen555 << 16;
    do {
      auto step = std::min(c, UINT32_C(512));
      ram.write_repeat(base_address + off * 2, val, step * 2);
      off += step;
      c -= step;
    } while(c);
  } else {
    // batching
    if(batch_next_off != off || batch_ptr + c > batch_end) {
      flush_batch();

      batch_start_addr = base_address + off * 2;
      batch_next_off = off;

      // double-buffered
      batch_ptr = batch_start = batch_start == blend_buf ? blend_buf + cache_size : blend_buf;
      batch_end = batch_ptr + cache_size;
    }

    // write to cache buf
    batch_next_off += c;

    do {
      *batch_ptr++ = pen555;
    } while(--c);
  }
}

template<int h_repeat = 1>
static void pen_rgba_rgb555_picovision(const blit::Pen* pen, const blit::Surface* dest, uint32_t off, uint32_t c) {
  if(!pen->a) return;

  uint8_t* m = dest->mask ? dest->mask->data + off : nullptr;

  uint16_t a = alpha(pen->a, dest->alpha);

  off *= h_repeat;
  c *= h_repeat;

  if (!m) {
    // no mask
    if (a >= 255) {
      // no alpha, just copy
      copy_rgba_rgb555(pen, off, c);
    }
    else {
      // alpha, blend
      blend_rgba_rgb555(pen, off, a, c);
    }
  } else {
    // mask enabled, slow blend
    do {
      uint16_t ma = alpha(a, *m++);
      blend_rgba_rgb555(pen, off, ma, 1);
      off++;
    } while (--c);
  }
}

template<int h_repeat = 1>
static void blit_rgb555(uint16_t *s, const blit::Surface* dest, uint32_t doff, uint32_t cnt, int32_t src_step) {
  if(h_repeat == 1 && src_step == 1 && !dest->mask && dest->alpha == 255) {
    // copy
    ram.write(base_address + doff * 2, (uint32_t *)s, cnt * 2);
    return;
  }

  do {
    auto step = std::min(cnt, uint32_t(std::size(blend_buf)));

    auto *ptr = blend_buf;

    if(dest->alpha < 255) {
      // read and blend
      ram.read_blocking(base_address + doff * 2, (uint32_t*)blend_buf, (step + 1) >> 1);

      for(unsigned i = 0; i < step; i += h_repeat) {
        uint8_t r, g, b, sr, sg, sb;
        uint8_t a = dest->alpha;
        unpack_rgb555(*s, sr, sg, sb);
        unpack_rgb555(*ptr, r, g, b);
        auto col = pack_rgb555(blend(sr, r, a), blend(sg, g, a), blend(sb, b, a));

        for(int j = 0; j < h_repeat; j++)
          *ptr++ = col;

        s += src_step;
      }
    } else {
      ram.wait_for_finish_blocking(); // make sure to always wait

      for(unsigned i = 0; i < step; i += h_repeat) {
        for(int j = 0; j < h_repeat; j++)
          *ptr++ = *s;

        s += src_step;
      }
    }

    ram.write(base_address + doff * 2, (uint32_t *)blend_buf, step * 2);
    doff += step;
    cnt -= step;
  } while(cnt);
}

template<int h_repeat = 1>
static void blit_rgba_rgb555_picovision(const blit::Surface* src, uint32_t soff, const blit::Surface* dest, uint32_t doff, uint32_t cnt, int32_t src_step) {
  uint8_t* s = src->palette ? src->data + soff : src->data + (soff * src->pixel_stride);
  uint8_t* m = dest->mask ? dest->mask->data + doff : nullptr;

  doff *= h_repeat;
  cnt *= h_repeat;

  flush_batch();

  if(src->format == blit::PixelFormat::BGR555)
    return blit_rgb555<h_repeat>((uint16_t *)s, dest, doff, cnt, src_step);

  do {
    auto step = std::min(cnt, uint32_t(std::size(blend_buf)));

    // TODO: only if needed
    if(src->format != blit::PixelFormat::RGB)
      ram.read_blocking(base_address + doff * 2, (uint32_t*)blend_buf, (step + 1) >> 1);

    auto *ptr = blend_buf;
    for(unsigned i = 0; i < step; i += h_repeat) {
      auto pen = src->palette ? &src->palette[*s] : (blit::Pen *)s;

      uint16_t a = src->format == blit::PixelFormat::RGB ? 255 : pen->a;
      a = m ? alpha(a, *m++, dest->alpha) : alpha(a, dest->alpha);

      for(int j = 0; j < h_repeat; j++) {
        if(a >= 255) {
          *ptr++ = pack_rgb555(pen->r, pen->g, pen->b);
        } else if (a > 1) {
          uint8_t r, g, b;
          unpack_rgb555(*ptr, r, g, b);
          *ptr++ = pack_rgb555(blend(pen->r, r, a), blend(pen->g, g, a), blend(pen->b, b, a));
        }else{
          ptr++;
        }
      }

      s += (src->pixel_stride) * src_step;
    }

    ram.write(base_address + doff * 2, (uint32_t *)blend_buf, step * 2);

    doff += step;
    cnt -= step;

  } while(cnt);
}

template<int h_repeat = 1>
static blit::Pen get_pen_rgb555_picovision(const blit::Surface *surf, uint32_t offset) {
  uint32_t tmp;
  ram.read_blocking(base_address + offset * h_repeat * 2, &tmp, 1);

  uint8_t r, g, b;
  unpack_rgb555(tmp, r, g, b);
  return {r, g, b};
}

static void write_frame_setup(uint16_t width, uint16_t height, blit::PixelFormat format, uint8_t h_repeat, uint8_t v_repeat) {
  constexpr int buf_size = 32;
  uint32_t buf[buf_size];

  int dv_format = 1; // 555

  uint32_t full_width = width * h_repeat;
  buf[0] = 0x4F434950; // "PICO"

  // setup
  buf[1] = 0x01000101 + ((uint32_t)v_repeat << 16);
  buf[2] = full_width << 16;
  buf[3] = (uint32_t)height << 16;

  // frame table header
  buf[4] = 0x00000001; // 1 frame, start at frame 0
  buf[5] = 0x00010000 + height + ((uint32_t)ram_bank << 24); // frame rate divider 1
  buf[6] = 0x00000001; // 1 palette, don't advance, 0 sprites

  ram.write(0, buf, 7 * 4);
  ram.wait_for_finish_blocking();

  // write frame table
  uint frame_table_addr = 4 * 7;

  for(int y = 0; y < height; y += buf_size) {
    int step = std::min(buf_size, height - y);
    for(int i = 0; i < step; i++) {
      uint32_t line_addr = base_address + (y + i) * width * blit::pixel_format_stride[int(format)];
      buf[i] = dv_format << 27 | h_repeat << 24 | line_addr;
    }

    ram.write(frame_table_addr, buf, step * 4);
    ram.wait_for_finish_blocking();
    frame_table_addr += 4 * step;
  }
}

void init_display() {
  gpio_init(RAM_SEL);
  gpio_put(RAM_SEL, 0);
  gpio_set_dir(RAM_SEL, GPIO_OUT);

  gpio_init(VSYNC);
  gpio_set_dir(VSYNC, GPIO_IN);
  gpio_set_irq_enabled_with_callback(VSYNC, GPIO_IRQ_EDGE_RISE, true, vsync_callback);

  sleep_ms(200);
  swd_load_program(section_addresses, section_data, section_data_len, std::size(section_data_len), 0x20000001, 0x15004000, true);

  // init RAM
  ram.init();
  sleep_us(100);

  gpio_put(RAM_SEL, 1);
  ram.init();
  sleep_us(100);

  ram_bank = 0;
  gpio_put(RAM_SEL, 0);
  sleep_ms(100);

  static_assert(i2c_default == i2c1);
  uint8_t resolution = 0; // 640x480
  uint8_t buf[2] = {I2C_REG_SET_RES, resolution};
  i2c_write_blocking(i2c1, I2C_ADDR, buf, 2, false);
}

static int find_resolution(const blit::Size &bounds) {
  int i = 0;

  for(auto &res : resolutions) {
    if(bounds == res || bounds == res / 2 || bounds == res / 4)
      return i;

    i++;
  }

  return -1;
}

void update_display(uint32_t time) {
  if(!do_render)
    return;

  blit::render(time);

  flush_batch();

  ram.wait_for_finish_blocking();

  // handle mode change
  if(need_mode_change) {
    auto new_res = find_resolution(cur_surf_info.bounds);

    // resolution switch
    if(new_res != cur_resolution) {
      // if display was already enabled, we're too late so stop and restart
      if(display_enabled) {
        uint8_t buf[2] = {I2C_REG_STOP, 1};
        i2c_write_blocking(i2c1, I2C_ADDR, buf, 2, false);

        display_enabled = false;

        sleep_ms(50); // wait a bit
      }

      uint8_t buf[2] = {I2C_REG_SET_RES, uint8_t(new_res)};
      i2c_write_blocking(i2c1, I2C_ADDR, buf, 2, false);
      cur_resolution = new_res;
    }

    auto &base_bounds = resolutions[new_res];

    uint8_t h_repeat = base_bounds.w / cur_surf_info.bounds.w, v_repeat = base_bounds.h / cur_surf_info.bounds.h;

    uint16_t final_w = cur_surf_info.bounds.w;

    if(h_repeat > 2) {
      h_repeat = 2;
      final_w = base_bounds.w / 2;
    }

    write_frame_setup(final_w,  cur_surf_info.bounds.h,  cur_surf_info.format, h_repeat, v_repeat);
    need_mode_change--;
  }

  // enable display after first render
  if(!display_enabled) {
    // swap banks now
    ram_bank ^= 1;
    gpio_put(RAM_SEL, ram_bank);

    uint8_t buf[2] = {I2C_REG_START, 1};
    i2c_write_blocking(i2c1, I2C_ADDR, buf, 2, false);
    display_enabled = true;
  } else
    do_render = false;
}

void init_display_core1() {
}

void update_display_core1() {
}

bool display_render_needed() {
  return do_render;
}

bool display_mode_supported(blit::ScreenMode new_mode, const blit::SurfaceTemplate &new_surf_template) {
  if(new_surf_template.format != blit::PixelFormat::BGR555)
    return false;

  if(find_resolution(new_surf_template.bounds) != -1)
    return true;

  return false;
}

void display_mode_changed(blit::ScreenMode new_mode, blit::SurfaceTemplate &new_surf_template) {
  if(new_surf_template.bounds.w <= 160) {
    new_surf_template.pen_blend = pen_rgba_rgb555_picovision<2>;
    new_surf_template.blit_blend = blit_rgba_rgb555_picovision<2>;
    new_surf_template.pen_get = get_pen_rgb555_picovision<2>;
  } else {
    new_surf_template.pen_blend = pen_rgba_rgb555_picovision;
    new_surf_template.blit_blend = blit_rgba_rgb555_picovision;
    new_surf_template.pen_get = get_pen_rgb555_picovision;
  }

  need_mode_change = 2; // make sure to update both banks

  if(!display_enabled)
    do_render = true;
}
