// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @defgroup graphics Graphics
 *
 * @{
 */

/**
 * @file
 * @brief  Graphics drawing library
 */
#include <assert.h>
#include <err.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <zircon/compiler.h>
#include <zircon/syscalls.h>

#include <gfx/gfx.h>

#define TRACE 0

#if TRACE
#define xprintf(fmt...) printf(fmt)
#else
#define xprintf(fmt...) \
  do {                  \
  } while (0)
#endif

// Convert a 32bit ARGB image to its respective gamma corrected grayscale value.
static uint32_t ARGB8888_to_Luma(uint32_t in) {
  uint8_t out;

  uint32_t blue = (in & 0xFF) * 74;
  uint32_t green = ((in >> 8) & 0xFF) * 732;
  uint32_t red = ((in >> 16) & 0xFF) * 218;

  uint32_t intensity = red + blue + green;

  out = (intensity >> 10) & 0xFF;

  return out;
}

static uint32_t ARGB8888_to_RGB565(uint32_t in) {
  uint16_t out;

  out = (in >> 3) & 0x1f;            // b
  out |= ((in >> 10) & 0x3f) << 5;   // g
  out |= ((in >> 19) & 0x1f) << 11;  // r

  return out;
}

static uint32_t ARGB8888_to_RGB332(uint32_t in) {
  uint8_t out = 0;

  out = (in >> 6) & 0x3;           // b
  out |= ((in >> 13) & 0x7) << 2;  // g
  out |= ((in >> 21) & 0x7) << 5;  // r

  return out;
}

static uint32_t ARGB8888_to_RGB2220(uint32_t in) {
  uint8_t out = 0;

  out = ((in >> 6) & 0x3) << 2;
  out |= ((in >> 14) & 0x3) << 4;
  out |= ((in >> 22) & 0x3) << 6;

  return out;
}

/**
 * @brief  Copy a rectangle of pixels from one part of the display to another.
 */
void gfx_copyrect(gfx_surface* surface, unsigned x, unsigned y, unsigned width, unsigned height,
                  unsigned x2, unsigned y2) {
  // trim
  if (x >= surface->width)
    return;
  if (x2 >= surface->width)
    return;
  if (y >= surface->height)
    return;
  if (y2 >= surface->height)
    return;
  if (width == 0 || height == 0)
    return;

  // clip the width to src or dest
  if (x + width > surface->width)
    width = surface->width - x;
  if (x2 + width > surface->width)
    width = surface->width - x2;

  // clip the height to src or dest
  if (y + height > surface->height)
    height = surface->height - y;
  if (y2 + height > surface->height)
    height = surface->height - y2;

  surface->copyrect(surface, x, y, width, height, x2, y2);
}

void gfx_copylines(gfx_surface* dst, gfx_surface* src, unsigned srcy, unsigned dsty,
                   unsigned height) {
  if ((dst->stride != src->stride) || (dst->format != src->format)) {
    return;
  }
  if ((srcy >= src->height) || ((src->height - srcy) < height)) {
    return;
  }
  if ((dsty >= dst->height) || (dst->height - dsty) < height) {
    return;
  }
  memcpy(dst->ptr + dsty * dst->stride * dst->pixelsize,
         src->ptr + srcy * src->stride * src->pixelsize, height * src->stride * src->pixelsize);
}

/**
 * @brief  Fill a rectangle on the screen with a constant color.
 */
void gfx_fillrect(gfx_surface* surface, unsigned x, unsigned y, unsigned width, unsigned height,
                  unsigned color) {
  xprintf("surface %p, x %u y %u w %u h %u c %u\n", surface, x, y, width, height, color);
  // trim
  if (unlikely(x >= surface->width))
    return;
  if (y >= surface->height)
    return;
  if (width == 0 || height == 0)
    return;

  // clip the width
  if (x + width > surface->width)
    width = surface->width - x;

  // clip the height
  if (y + height > surface->height)
    height = surface->height - y;

  surface->fillrect(surface, x, y, width, height, color);
}

/**
 * @brief  Write a single pixel to the screen.
 */
void gfx_putpixel(gfx_surface* surface, unsigned x, unsigned y, unsigned color) {
  if (unlikely(x >= surface->width))
    return;
  if (y >= surface->height)
    return;

  surface->putpixel(surface, x, y, color);
}

static void putpixel16(gfx_surface* surface, unsigned x, unsigned y, unsigned color) {
  uint16_t* dest = &((uint16_t*)surface->ptr)[x + y * surface->stride];

  // colors come in in ARGB 8888 form, flatten them
  *dest = (uint16_t)(surface->translate_color(color));
}

static void putpixel32(gfx_surface* surface, unsigned x, unsigned y, unsigned color) {
  uint32_t* dest = &((uint32_t*)surface->ptr)[x + y * surface->stride];

  *dest = color;
}

static void putpixel8(gfx_surface* surface, unsigned x, unsigned y, unsigned color) {
  uint8_t* dest = &((uint8_t*)surface->ptr)[x + y * surface->stride];

  // colors come in in ARGB 8888 form, flatten them
  *dest = (uint8_t)(surface->translate_color(color));
}

#define MKPUTCHAR(FUNC, TYPE)                                                           \
  static void FUNC(gfx_surface* surface, const gfx_font* font, unsigned ch, unsigned x, \
                   unsigned y, unsigned fg, unsigned bg) {                              \
    TYPE* dest = &((TYPE*)surface->ptr)[x + y * surface->stride];                       \
    const uint16_t* cdata = font->data + ch * font->height;                             \
    unsigned fw = font->width;                                                          \
    for (unsigned i = font->height; i > 0; i--) {                                       \
      uint16_t xdata = *cdata++;                                                        \
      for (unsigned j = fw; j > 0; j--) {                                               \
        *dest++ = (xdata & 1) ? fg : bg;                                                \
        xdata >>= 1;                                                                    \
      }                                                                                 \
      dest += (surface->stride - fw);                                                   \
    }                                                                                   \
  }

MKPUTCHAR(putchar8, uint8_t)
MKPUTCHAR(putchar16, uint16_t)
MKPUTCHAR(putchar32, uint32_t)

void gfx_putchar(gfx_surface* surface, const gfx_font* font, unsigned ch, unsigned x, unsigned y,
                 unsigned fg, unsigned bg) {
  if (unlikely(ch > 127)) {
    return;
  }
  if (unlikely(x > (surface->width - font->width))) {
    return;
  }
  if (unlikely(y > (surface->height - font->height))) {
    return;
  }
  if (surface->translate_color) {
    fg = surface->translate_color(fg);
    bg = surface->translate_color(bg);
  }
  surface->putchar(surface, font, ch, x, y, fg, bg);
}

static void copyrect8(gfx_surface* surface, unsigned x, unsigned y, unsigned width, unsigned height,
                      unsigned x2, unsigned y2) {
  // copy
  const uint8_t* src = &((const uint8_t*)surface->ptr)[x + y * surface->stride];
  uint8_t* dest = &((uint8_t*)surface->ptr)[x2 + y2 * surface->stride];
  unsigned stride_diff = surface->stride - width;

  if (dest < src) {
    unsigned i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest++;
        src++;
      }
      dest += stride_diff;
      src += stride_diff;
    }
  } else {
    // copy backwards
    src += (height - 1) * surface->stride + (width - 1);
    dest += (height - 1) * surface->stride + (width - 1);

    unsigned i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest--;
        src--;
      }
      dest -= stride_diff;
      src -= stride_diff;
    }
  }
}

static void fillrect8(gfx_surface* surface, unsigned x, unsigned y, unsigned width, unsigned height,
                      unsigned color) {
  uint8_t* dest = &((uint8_t*)surface->ptr)[x + y * surface->stride];
  unsigned stride_diff = surface->stride - width;

  uint8_t color8 = (uint8_t)(surface->translate_color(color));

  unsigned i, j;
  for (i = 0; i < height; i++) {
    for (j = 0; j < width; j++) {
      *dest = color8;
      dest++;
    }
    dest += stride_diff;
  }
}

static void copyrect16(gfx_surface* surface, unsigned x, unsigned y, unsigned width,
                       unsigned height, unsigned x2, unsigned y2) {
  // copy
  const uint16_t* src = &((const uint16_t*)surface->ptr)[x + y * surface->stride];
  uint16_t* dest = &((uint16_t*)surface->ptr)[x2 + y2 * surface->stride];
  unsigned stride_diff = surface->stride - width;

  if (dest < src) {
    unsigned i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest++;
        src++;
      }
      dest += stride_diff;
      src += stride_diff;
    }
  } else {
    // copy backwards
    src += (height - 1) * surface->stride + (width - 1);
    dest += (height - 1) * surface->stride + (width - 1);

    unsigned i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest--;
        src--;
      }
      dest -= stride_diff;
      src -= stride_diff;
    }
  }
}

static void fillrect16(gfx_surface* surface, unsigned x, unsigned y, unsigned width,
                       unsigned height, unsigned color) {
  uint16_t* dest = &((uint16_t*)surface->ptr)[x + y * surface->stride];
  unsigned stride_diff = surface->stride - width;

  uint16_t color16 = (uint16_t)(surface->translate_color(color));

  unsigned i, j;
  for (i = 0; i < height; i++) {
    for (j = 0; j < width; j++) {
      *dest = color16;
      dest++;
    }
    dest += stride_diff;
  }
}

static void copyrect32(gfx_surface* surface, unsigned x, unsigned y, unsigned width,
                       unsigned height, unsigned x2, unsigned y2) {
  // copy
  const uint32_t* src = &((const uint32_t*)surface->ptr)[x + y * surface->stride];
  uint32_t* dest = &((uint32_t*)surface->ptr)[x2 + y2 * surface->stride];
  unsigned stride_diff = surface->stride - width;

  if (dest < src) {
    unsigned i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest++;
        src++;
      }
      dest += stride_diff;
      src += stride_diff;
    }
  } else {
    // copy backwards
    src += (height - 1) * surface->stride + (width - 1);
    dest += (height - 1) * surface->stride + (width - 1);

    unsigned i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest--;
        src--;
      }
      dest -= stride_diff;
      src -= stride_diff;
    }
  }
}

static void fillrect32(gfx_surface* surface, unsigned x, unsigned y, unsigned width,
                       unsigned height, unsigned color) {
  uint32_t* dest = &((uint32_t*)surface->ptr)[x + y * surface->stride];
  unsigned stride_diff = surface->stride - width;

  unsigned i, j;
  for (i = 0; i < height; i++) {
    for (j = 0; j < width; j++) {
      *dest = color;
      dest++;
    }
    dest += stride_diff;
  }
}

void gfx_line(gfx_surface* surface, unsigned x1, unsigned y1, unsigned x2, unsigned y2,
              unsigned color) {
  if (unlikely(x1 >= surface->width))
    return;
  if (unlikely(x2 >= surface->width))
    return;

  if (y1 >= surface->height)
    return;
  if (y2 >= surface->height)
    return;

  int dx = x2 - x1;
  int dy = y2 - y1;

  int sdx = (0 < dx) - (dx < 0);
  int sdy = (0 < dy) - (dy < 0);

  unsigned dxabs = (dx > 0) ? dx : -dx;
  unsigned dyabs = (dy > 0) ? dy : -dy;

  unsigned x = dyabs >> 1;
  unsigned y = dxabs >> 1;

  unsigned px = x1;
  unsigned py = y1;

  if (dxabs >= dyabs) {
    // mostly horizontal line.
    for (unsigned i = 0; i < dxabs; i++) {
      y += dyabs;
      if (y >= dxabs) {
        y -= dxabs;
        py += sdy;
      }
      px += sdx;
      surface->putpixel(surface, px, py, color);
    }
  } else {
    // mostly vertical line.
    for (unsigned i = 0; i < dyabs; i++) {
      x += dxabs;
      if (x >= dyabs) {
        x -= dyabs;
        px += sdx;
      }
      py += sdy;
      surface->putpixel(surface, px, py, color);
    }
  }
}

uint32_t alpha32_add_ignore_destalpha(uint32_t dest, uint32_t src) {
  uint32_t cdest[3];
  uint32_t csrc[3];

  uint32_t srca;
  uint32_t srcainv;

  srca = (src >> 24) & 0xff;
  if (srca == 0) {
    return dest;
  } else if (srca == 255) {
    return src;
  }
  srca++;
  srcainv = (255 - srca);

  cdest[0] = (dest >> 16) & 0xff;
  cdest[1] = (dest >> 8) & 0xff;
  cdest[2] = (dest >> 0) & 0xff;

  csrc[0] = (src >> 16) & 0xff;
  csrc[1] = (src >> 8) & 0xff;
  csrc[2] = (src >> 0) & 0xff;

  //    if (srca > 0)
  //        printf("s %d %d %d d %d %d %d a %d ai %d\n", csrc[0], csrc[1], csrc[2], cdest[0],
  //        cdest[1], cdest[2], srca, srcainv);

  uint32_t cres[3];

  cres[0] = ((csrc[0] * srca) / 256) + ((cdest[0] * srcainv) / 256);
  cres[1] = ((csrc[1] * srca) / 256) + ((cdest[1] * srcainv) / 256);
  cres[2] = ((csrc[2] * srca) / 256) + ((cdest[2] * srcainv) / 256);

  return (srca << 24) | (cres[0] << 16) | (cres[1] << 8) | (cres[2]);
}

/**
 * @brief  Copy pixels from source to dest.
 *
 * Currently does not support alpha channel.
 */
void gfx_surface_blend(struct gfx_surface* target, struct gfx_surface* source, unsigned destx,
                       unsigned desty) {
  gfx_blend(target, source, 0, 0, source->width, source->height, destx, desty);
}

/**
 * @brief  Copy pixels from source to dest.
 */
void gfx_blend(gfx_surface* target, gfx_surface* source, unsigned srcx, unsigned srcy,
               unsigned width, unsigned height, unsigned destx, unsigned desty) {
  assert(target->format == source->format);

  xprintf("target %p, source %p, srcx %u, srcy %u, width %u, height %u, destx %u, desty %u\n",
          target, source, srcx, srcy, width, height, destx, desty);

  if (destx >= target->width)
    return;
  if (desty >= target->height)
    return;

  if (srcx >= source->width)
    return;
  if (srcy >= source->height)
    return;

  if (destx + width > target->width)
    width = target->width - destx;
  if (desty + height > target->height)
    height = target->height - desty;

  if (srcx + width > source->width)
    width = source->width - srcx;
  if (srcy + height > source->height)
    height = source->height - srcy;

  // XXX total hack to deal with various blends
  if (source->format == ZX_PIXEL_FORMAT_RGB_565 && target->format == ZX_PIXEL_FORMAT_RGB_565) {
    // 16 bit to 16 bit
    const uint16_t* src = &((const uint16_t*)source->ptr)[srcx + srcy * source->stride];
    uint16_t* dest = &((uint16_t*)target->ptr)[destx + desty * target->stride];
    unsigned dest_stride_diff = target->stride - width;
    unsigned source_stride_diff = source->stride - width;

    xprintf("w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff,
            source_stride_diff);

    unsigned i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest++;
        src++;
      }
      dest += dest_stride_diff;
      src += source_stride_diff;
    }
  } else if (source->format == ZX_PIXEL_FORMAT_ARGB_8888 &&
             target->format == ZX_PIXEL_FORMAT_ARGB_8888) {
    // both are 32 bit modes, both alpha
    const uint32_t* src = &((const uint32_t*)source->ptr)[srcx + srcy * source->stride];
    uint32_t* dest = &((uint32_t*)target->ptr)[destx + desty * target->stride];
    unsigned dest_stride_diff = target->stride - width;
    unsigned source_stride_diff = source->stride - width;

    xprintf("w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff,
            source_stride_diff);

    unsigned i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        // XXX ignores destination alpha
        *dest = alpha32_add_ignore_destalpha(*dest, *src);
        dest++;
        src++;
      }
      dest += dest_stride_diff;
      src += source_stride_diff;
    }
  } else if (source->format == ZX_PIXEL_FORMAT_RGB_x888 &&
             target->format == ZX_PIXEL_FORMAT_RGB_x888) {
    // both are 32 bit modes, no alpha
    const uint32_t* src = &((const uint32_t*)source->ptr)[srcx + srcy * source->stride];
    uint32_t* dest = &((uint32_t*)target->ptr)[destx + desty * target->stride];
    unsigned dest_stride_diff = target->stride - width;
    unsigned source_stride_diff = source->stride - width;

    xprintf("w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff,
            source_stride_diff);

    unsigned i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest++;
        src++;
      }
      dest += dest_stride_diff;
      src += source_stride_diff;
    }
  } else if (source->format == ZX_PIXEL_FORMAT_MONO_8 && target->format == ZX_PIXEL_FORMAT_MONO_8) {
    // both are 8 bit modes, no alpha
    const uint8_t* src = &((const uint8_t*)source->ptr)[srcx + srcy * source->stride];
    uint8_t* dest = &((uint8_t*)target->ptr)[destx + desty * target->stride];
    unsigned dest_stride_diff = target->stride - width;
    unsigned source_stride_diff = source->stride - width;

    xprintf("w %u h %u dstride %u sstride %u\n", width, height, dest_stride_diff,
            source_stride_diff);

    unsigned i, j;
    for (i = 0; i < height; i++) {
      for (j = 0; j < width; j++) {
        *dest = *src;
        dest++;
        src++;
      }
      dest += dest_stride_diff;
      src += source_stride_diff;
    }
  } else {
    xprintf("gfx_surface_blend: unimplemented colorspace combination (source %d target %d)\n",
            source->format, target->format);
    assert(0);
  }
}

/**
 * @brief  Ensure all graphics rendering is sent to display
 */
void gfx_flush(gfx_surface* surface) {
  if (surface->flags & GFX_FLAG_FLUSH_CPU_CACHE)
    zx_cache_flush(surface->ptr, surface->len, ZX_CACHE_FLUSH_DATA);

  if (surface->flush)
    surface->flush(0, surface->height - 1);
}

/**
 * @brief  Ensure that a sub-region of the display is up to date.
 */
void gfx_flush_rows(struct gfx_surface* surface, unsigned start, unsigned end) {
  if (start > end) {
    unsigned temp = start;
    start = end;
    end = temp;
  }

  if (start >= surface->height)
    return;
  if (end >= surface->height)
    end = surface->height - 1;

  if (surface->flags & GFX_FLAG_FLUSH_CPU_CACHE) {
    uint32_t runlen = surface->stride * surface->pixelsize;
    zx_cache_flush(surface->ptr + start * runlen, (end - start + 1) * runlen, ZX_CACHE_FLUSH_DATA);
  }

  if (surface->flush)
    surface->flush(start, end);
}

/**
 * @brief  Create a new graphics surface object
 */
gfx_surface* gfx_create_surface(void* ptr, unsigned width, unsigned height, unsigned stride,
                                unsigned format, uint32_t flags) {
  gfx_surface* surface = calloc(1, sizeof(*surface));
  if (surface == NULL)
    return NULL;
  if (gfx_init_surface(surface, ptr, width, height, stride, format, flags)) {
    free(surface);
    return NULL;
  }
  return surface;
}

int gfx_init_surface(gfx_surface* surface, void* ptr, unsigned width, unsigned height,
                     unsigned stride, unsigned format, uint32_t flags) {
  assert(width > 0);
  assert(height > 0);
  assert(stride >= width);

  surface->flags = flags;
  surface->format = format;
  surface->width = width;
  surface->height = height;
  surface->stride = stride;
  surface->alpha = MAX_ALPHA;

  // set up some function pointers
  switch (format) {
    case ZX_PIXEL_FORMAT_RGB_565:
      surface->translate_color = &ARGB8888_to_RGB565;
      surface->copyrect = &copyrect16;
      surface->fillrect = &fillrect16;
      surface->putpixel = &putpixel16;
      surface->putchar = &putchar16;
      surface->pixelsize = 2;
      surface->len = (surface->height * surface->stride * surface->pixelsize);
      break;
    case ZX_PIXEL_FORMAT_RGB_x888:
    case ZX_PIXEL_FORMAT_ARGB_8888:
      surface->translate_color = NULL;
      surface->copyrect = &copyrect32;
      surface->fillrect = &fillrect32;
      surface->putpixel = &putpixel32;
      surface->putchar = &putchar32;
      surface->pixelsize = 4;
      surface->len = (surface->height * surface->stride * surface->pixelsize);
      break;
    case ZX_PIXEL_FORMAT_MONO_8:
      surface->translate_color = &ARGB8888_to_Luma;
      surface->copyrect = &copyrect8;
      surface->fillrect = &fillrect8;
      surface->putpixel = &putpixel8;
      surface->putchar = &putchar8;
      surface->pixelsize = 1;
      surface->len = (surface->height * surface->stride * surface->pixelsize);
      break;
    case ZX_PIXEL_FORMAT_RGB_332:
      surface->translate_color = &ARGB8888_to_RGB332;
      surface->copyrect = &copyrect8;
      surface->fillrect = &fillrect8;
      surface->putpixel = &putpixel8;
      surface->putchar = &putchar8;
      surface->pixelsize = 1;
      surface->len = (surface->height * surface->stride * surface->pixelsize);
      break;
    case ZX_PIXEL_FORMAT_RGB_2220:
      surface->translate_color = &ARGB8888_to_RGB2220;
      surface->copyrect = &copyrect8;
      surface->fillrect = &fillrect8;
      surface->putpixel = &putpixel8;
      surface->putchar = &putchar8;
      surface->pixelsize = 1;
      surface->len = (surface->height * surface->stride * surface->pixelsize);
      break;
    default:
      xprintf("invalid graphics format\n");
      return ZX_ERR_INVALID_ARGS;
  }

  if (ptr == NULL) {
    // allocate a buffer
    ptr = malloc(surface->len);
    if (ptr == NULL) {
      return ZX_ERR_NO_MEMORY;
    }
    assert(ptr);
    surface->flags |= GFX_FLAG_FREE_ON_DESTROY;
  }
  surface->ptr = ptr;
  return 0;
}

/**
 * @brief  Destroy a graphics surface and free all resources allocated to it.
 *
 * @param  surface  Surface to destroy.  This pointer is no longer valid after
 *    this call.
 */
void gfx_surface_destroy(struct gfx_surface* surface) {
  if (surface->flags & GFX_FLAG_FREE_ON_DESTROY)
    free(surface->ptr);
  free(surface);
}
