// 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;
  }
  memmove(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;
}

zx_status_t 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 ZX_OK;
}

/**
 * @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);
}
