// 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 = (uint8_t)(((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) ? (TYPE)fg : (TYPE)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);
}
