/* ply-frame-buffer.c - framebuffer abstraction
 *
 * Copyright (C) 2006, 2007, 2008 Red Hat, Inc.
 *               2008 Charlie Brej <cbrej@cs.man.ac.uk>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 *
 * Written by: Charlie Brej <cbrej@cs.man.ac.uk>
 *             Kristian Høgsberg <krh@redhat.com>
 *             Ray Strode <rstrode@redhat.com>
 */

#include "ply-frame-buffer.h"

#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <values.h>
#include <unistd.h>

#include <linux/fb.h>

#include "ply-list.h"
#include "ply-utils.h"

#ifndef PLY_FRAME_BUFFER_DEFAULT_FB_DEVICE_NAME
#define PLY_FRAME_BUFFER_DEFAULT_FB_DEVICE_NAME "/dev/fb0"
#endif

struct _ply_frame_buffer {
  char *device_name;
  int   device_fd;

  char *map_address;
  size_t size;

  uint32_t *shadow_buffer;

  uint32_t red_bit_position;
  uint32_t green_bit_position;
  uint32_t blue_bit_position;
  uint32_t alpha_bit_position;

  uint32_t bits_for_red;
  uint32_t bits_for_green;
  uint32_t bits_for_blue;
  uint32_t bits_for_alpha;

  int32_t dither_red;
  int32_t dither_green;
  int32_t dither_blue;

  unsigned int bytes_per_pixel;
  unsigned int row_stride;

  ply_frame_buffer_area_t area;
  ply_list_t *areas_to_flush;

  void (*flush_area)(ply_frame_buffer_t      *buffer,
                     ply_frame_buffer_area_t *area_to_flush);

  int pause_count;
};

static bool ply_frame_buffer_open_device(ply_frame_buffer_t  *buffer);
static void ply_frame_buffer_close_device(ply_frame_buffer_t *buffer);
static bool ply_frame_buffer_query_device(ply_frame_buffer_t *buffer);
static bool ply_frame_buffer_map_to_device(ply_frame_buffer_t *buffer);
static inline uint_fast32_t
  ply_frame_buffer_pixel_value_to_device_pixel_value(
    ply_frame_buffer_t *buffer,
    uint32_t            pixel_value);

static bool ply_frame_buffer_open_device(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);
  assert(buffer->device_name != NULL);

  buffer->device_fd = open(buffer->device_name, O_RDWR);

  if (buffer->device_fd < 0) {
    return false;
  }

  return true;
}

static void ply_frame_buffer_close_device(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);

  if (buffer->map_address != MAP_FAILED) {
    munmap(buffer->map_address, buffer->size);
    buffer->map_address = MAP_FAILED;
  }

  if (buffer->device_fd >= 0) {
    close(buffer->device_fd);
    buffer->device_fd = -1;
  }
}

static void flush_area_to_any_device(ply_frame_buffer_t      *buffer,
                                     ply_frame_buffer_area_t *area_to_flush) {
  unsigned long row, column;
  char *row_buffer;
  size_t bytes_per_row;
  unsigned long x1, y1, x2, y2;

  x1 = area_to_flush->x;
  y1 = area_to_flush->y;
  x2 = x1 + area_to_flush->width;
  y2 = y1 + area_to_flush->height;

  bytes_per_row = area_to_flush->width * buffer->bytes_per_pixel;
  row_buffer = malloc(buffer->row_stride * buffer->bytes_per_pixel);
  for (row = y1; row < y2; row++) {
    unsigned long offset;

    for (column = x1; column < x2; column++) {
      uint32_t pixel_value;
      uint_fast32_t device_pixel_value;

      pixel_value = buffer->shadow_buffer[row * buffer->area.width + column];

      device_pixel_value =
        ply_frame_buffer_pixel_value_to_device_pixel_value(buffer,
                                                           pixel_value);

      memcpy(row_buffer + column * buffer->bytes_per_pixel,
             &device_pixel_value,
             buffer->bytes_per_pixel);
    }

    offset = row * buffer->row_stride * buffer->bytes_per_pixel +
      x1 * buffer->bytes_per_pixel;
    memcpy(buffer->map_address + offset,
           row_buffer + x1 * buffer->bytes_per_pixel,
           area_to_flush->width * buffer->bytes_per_pixel);
  }
  free(row_buffer);
}

static void flush_area_to_xrgb32_device(
    ply_frame_buffer_t *buffer, ply_frame_buffer_area_t *area_to_flush) {
  unsigned long x1, y1, x2, y2, y;
  char *dst, *src;

  x1 = area_to_flush->x;
  y1 = area_to_flush->y;
  x2 = x1 + area_to_flush->width;
  y2 = y1 + area_to_flush->height;

  dst = &buffer->map_address[(y1 * buffer->row_stride + x1) * 4];
  src = (char *) &buffer->shadow_buffer[y1 * buffer->area.width + x1];

  if (area_to_flush->width == buffer->row_stride) {
    memcpy(dst, src, area_to_flush->width * area_to_flush->height * 4);
    return;
  }

  for (y = y1; y < y2; y++) {
    memcpy(dst, src, area_to_flush->width * 4);
    dst += buffer->row_stride * 4;
    src += buffer->area.width * 4;
  }
}


static bool ply_frame_buffer_query_device(ply_frame_buffer_t *buffer) {
  struct fb_var_screeninfo variable_screen_info;
  struct fb_fix_screeninfo fixed_screen_info;

  assert(buffer != NULL);
  assert(buffer->device_fd >= 0);

  if (ioctl(buffer->device_fd, FBIOGET_VSCREENINFO, &variable_screen_info) < 0)
    return false;

  if (ioctl(buffer->device_fd, FBIOGET_FSCREENINFO, &fixed_screen_info) < 0)
    return false;

  /* Normally the pixel is divided into channels between the color components.
   * Each channel directly maps to a color channel on the hardware.
   *
   * There are some odd ball modes that use an indexed palette instead.  In
   * those cases (pseudocolor, direct color, etc), the pixel value is just an
   * index into a lookup table of the real color values.
   *
   * We don't support that.
   */
  if (fixed_screen_info.visual != FB_VISUAL_TRUECOLOR) {
    int rc = -1;
    int i;
    int depths[] = {32, 24, 16, 0};

    // ply_trace("Visual was %s, trying to find usable mode.\n",
    // p_visual(fixed_screen_info.visual));

    for (i = 0; depths[i] != 0; i++) {
      variable_screen_info.bits_per_pixel = depths[i];
      variable_screen_info.activate |= FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;

      rc = ioctl(buffer->device_fd, FBIOPUT_VSCREENINFO,
                 &variable_screen_info);
      if (rc >= 0) {
        if (ioctl(buffer->device_fd, FBIOGET_FSCREENINFO,
                  &fixed_screen_info) < 0)
          return false;
        if (fixed_screen_info.visual == FB_VISUAL_TRUECOLOR)
          break;
      }
    }

    if (ioctl(buffer->device_fd, FBIOGET_VSCREENINFO,
              &variable_screen_info) < 0)
      return false;

    if (ioctl(buffer->device_fd, FBIOGET_FSCREENINFO,
              &fixed_screen_info) < 0)
      return false;
  }

  if (fixed_screen_info.visual != FB_VISUAL_TRUECOLOR ||
      variable_screen_info.bits_per_pixel < 16) {
    return false;
  }

  buffer->area.x = variable_screen_info.xoffset;
  buffer->area.y = variable_screen_info.yoffset;
  buffer->area.width = variable_screen_info.xres;
  buffer->area.height = variable_screen_info.yres;

  buffer->red_bit_position = variable_screen_info.red.offset;
  buffer->bits_for_red = variable_screen_info.red.length;

  buffer->green_bit_position = variable_screen_info.green.offset;
  buffer->bits_for_green = variable_screen_info.green.length;

  buffer->blue_bit_position = variable_screen_info.blue.offset;
  buffer->bits_for_blue = variable_screen_info.blue.length;

  buffer->alpha_bit_position = variable_screen_info.transp.offset;
  buffer->bits_for_alpha = variable_screen_info.transp.length;

  buffer->bytes_per_pixel = variable_screen_info.bits_per_pixel >> 3;
  buffer->row_stride = fixed_screen_info.line_length / buffer->bytes_per_pixel;
  buffer->size = buffer->area.height * buffer->row_stride *
      buffer->bytes_per_pixel;
  
  buffer->dither_red = 0;
  buffer->dither_green = 0;
  buffer->dither_blue = 0;

  if (buffer->bytes_per_pixel == 4 &&
      buffer->red_bit_position == 16 && buffer->bits_for_red == 8 &&
      buffer->green_bit_position == 8 && buffer->bits_for_green == 8 &&
      buffer->blue_bit_position == 0 && buffer->bits_for_blue == 8)
    buffer->flush_area = flush_area_to_xrgb32_device;
  else
    buffer->flush_area = flush_area_to_any_device;

  return true;
}

static bool ply_frame_buffer_map_to_device(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);
  assert(buffer->device_fd >= 0);
  assert(buffer->size > 0);

  buffer->map_address = mmap(NULL, buffer->size, PROT_WRITE,
                             MAP_SHARED, buffer->device_fd, 0);

  return buffer->map_address != MAP_FAILED;
}

static inline uint_fast32_t 
    ply_frame_buffer_pixel_value_to_device_pixel_value(
      ply_frame_buffer_t *buffer, uint32_t pixel_value) {
  uint8_t r, g, b, a;
  int orig_r, orig_g, orig_b, orig_a;
  int i;
  
  orig_a = pixel_value >> 24; 
  a = orig_a >> (8 - buffer->bits_for_alpha);

  orig_r = ((pixel_value >> 16) & 0xff) - buffer->dither_red; 
  r = CLAMP(orig_r, 0, 255) >> (8 - buffer->bits_for_red);

  orig_g = ((pixel_value >> 8) & 0xff) - buffer->dither_green;
  g = CLAMP(orig_g, 0, 255) >> (8 - buffer->bits_for_green);

  orig_b = (pixel_value & 0xff) - buffer->dither_blue;
  b = CLAMP(orig_b, 0, 255) >> (8 - buffer->bits_for_blue);
  
  uint8_t new_r = r << (8 - buffer->bits_for_red);
  uint8_t new_g = g << (8 - buffer->bits_for_green);
  uint8_t new_b = b << (8 - buffer->bits_for_blue);
  for (i=buffer->bits_for_red;   i<8; i*=2) new_r |= new_r >> i;
  for (i=buffer->bits_for_green; i<8; i*=2) new_g |= new_g >> i;
  for (i=buffer->bits_for_blue;  i<8; i*=2) new_b |= new_b >> i;
  
  buffer->dither_red = new_r - orig_r;
  buffer->dither_green = new_g - orig_g;
  buffer->dither_blue = new_b - orig_b;
  

  return ((a << buffer->alpha_bit_position)
          | (r << buffer->red_bit_position)
          | (g << buffer->green_bit_position)
          | (b << buffer->blue_bit_position));
}


static inline void 
    ply_frame_buffer_place_value_at_pixel(ply_frame_buffer_t *buffer,
                                          int                 x,
                                          int                 y,
                                          uint32_t            pixel_value) {
  buffer->shadow_buffer[y * buffer->area.width + x] = pixel_value;
}


ply_frame_buffer_t *ply_frame_buffer_new(const char *device_name) {
  ply_frame_buffer_t *buffer;

  buffer = calloc(1, sizeof(ply_frame_buffer_t));

  if (device_name != NULL)
    buffer->device_name = strdup(device_name);
  else if (getenv("FRAMEBUFFER") != NULL)
    buffer->device_name = strdup(getenv("FRAMEBUFFER"));
  else
    buffer->device_name = 
      strdup(PLY_FRAME_BUFFER_DEFAULT_FB_DEVICE_NAME);

  buffer->map_address = MAP_FAILED;
  buffer->shadow_buffer = NULL;
  buffer->areas_to_flush = ply_list_new();

  buffer->pause_count = 0;

  return buffer;
}

static void free_flush_areas(ply_frame_buffer_t *buffer) {
  ply_list_node_t *node;

  node = ply_list_get_first_node(buffer->areas_to_flush);
  while (node != NULL) {
    ply_list_node_t *next_node;
    ply_frame_buffer_area_t *area_to_flush;

    area_to_flush = (ply_frame_buffer_area_t *) ply_list_node_get_data(node);

    next_node = ply_list_get_next_node(buffer->areas_to_flush, node);

    free(area_to_flush);
    ply_list_remove_node(buffer->areas_to_flush, node);

    node = next_node;
  }

  ply_list_free(buffer->areas_to_flush);
}

void ply_frame_buffer_free(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);

  if (ply_frame_buffer_device_is_open(buffer))
    ply_frame_buffer_close(buffer);

  free_flush_areas(buffer);

  free(buffer->device_name);
  free(buffer->shadow_buffer);
  free(buffer);
}

bool ply_frame_buffer_open(ply_frame_buffer_t *buffer) {
  bool is_open;

  assert(buffer != NULL);

  is_open = false;

  if (!ply_frame_buffer_open_device(buffer)) {
    goto out;
  }

  if (!ply_frame_buffer_query_device(buffer)) {
    goto out;
  }

  if (!ply_frame_buffer_map_to_device(buffer)) {
    goto out;
  }

  buffer->shadow_buffer =
    realloc(buffer->shadow_buffer,
            4 * buffer->area.width * buffer->area.height);
  is_open = true;

out:

  if (!is_open) {
    int saved_errno;

    saved_errno = errno;
    ply_frame_buffer_close_device(buffer);
    errno = saved_errno;
  }

  return is_open;
}


bool ply_frame_buffer_device_is_open(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);
  return buffer->device_fd >= 0 && buffer->map_address != MAP_FAILED;
}

char *ply_frame_buffer_get_device_name(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);
  assert(ply_frame_buffer_device_is_open(buffer));
  assert(buffer->device_name != NULL);

  return strdup(buffer->device_name);
}

void ply_frame_buffer_set_device_name(ply_frame_buffer_t *buffer,
                                      const char         *device_name) {
  assert(buffer != NULL);
  assert(!ply_frame_buffer_device_is_open(buffer));
  assert(device_name != NULL);
  assert(buffer->device_name != NULL);

  if (strcmp(buffer->device_name, device_name) != 0) {
    free(buffer->device_name);
    buffer->device_name = strdup(device_name);
  }
}

void ply_frame_buffer_close(ply_frame_buffer_t *buffer) {
  assert(buffer != NULL);

  assert(ply_frame_buffer_device_is_open(buffer));
  ply_frame_buffer_close_device(buffer);

  buffer->bytes_per_pixel = 0;
  buffer->area.x = 0;
  buffer->area.y = 0;
  buffer->area.width = 0;
  buffer->area.height = 0;
}

void ply_frame_buffer_get_size(ply_frame_buffer_t      *buffer,
                               ply_frame_buffer_area_t *size) {
  assert(buffer != NULL);
  assert(ply_frame_buffer_device_is_open(buffer));
  assert(size != NULL);

  *size = buffer->area;
}


/*
 * Fill the given frame buffer with the given image data.  The image
 * is to occupy an area of the frame buffer given by the area
 * pointer.  That image area will be clipped as necessary to fit the
 * frame buffer boundaries.
 *
 * Returns true if any part of the image was copied.  Returns false
 * if any condition (e.g. clipping) caused the entire image to be
 * skipped.
 */
bool ply_frame_buffer_fill(ply_frame_buffer_t *buffer,
                           ply_frame_buffer_area_t *area,
                           uint32_t *data) {
  assert(buffer != NULL);
  assert(ply_frame_buffer_device_is_open(buffer));
  assert(area != NULL);
  assert(data != NULL);

  /*
   * Short-circuit if there's no intersection between the image
   * area and the frame buffer.
   */
  if (area->x + (long) area->width < 0 ||
      area->x >= (long) buffer->area.width ||
      area->y + (long) area->height < 0 ||
      area->y >= (long) buffer->area.height)
    return false;

  /*
   * There's at least some overlap; clip the image to fit.
   */
  uint32_t *src = data;
  char *dst = buffer->map_address;
  size_t width = area->width;
  size_t lines = area->height;

  if (area->x < 0) {
    // clip image on the left
    src -= area->x;
    width += area->x;
  } else {
    dst += area->x * buffer->bytes_per_pixel;
  }

  if (area->x + area->width > buffer->area.width) {
    // clip image on the right
    width -= area->x + area->width - buffer->area.width;
  }

  if (area->y < 0) {
    // clip the top of the image
    src -= area->y * area->width;
    lines += area->y;
  } else {
    dst += area->y * buffer->row_stride * buffer->bytes_per_pixel;
  }

  if (area->y + area->height > buffer->area.height) {
    // clip the bottom of the image
    lines -= area->y + area->height - buffer->area.height;
  }

  /*
   * Copy the image to the frame buffer.  There are three cases:
   * 1) The frame buffer pixels are not RGB32; in this case we must
   *    convert each image line to match the target before copying.
   *    (N.B. The only supported alternative to RGB32 is RGB 565).
   * 2) The image width is unclipped and the width matches the frame
   *    buffer width.  In this case, a single copy can cover the
   *    entire image.
   * 3) In all other cases we copy line by line.
   */
  if (buffer->bytes_per_pixel != sizeof(*data)) {
    uint16_t *src_16 = 0, *src_16_end;
    int line;

    /* Handle the 16 bpp case (specifically RGB 565 case) */
    if (buffer->bytes_per_pixel != 2)
      return false;

    /* Allocate temporary row pixel data storage for 16 bpp displays */
    src_16 = (uint16_t *) malloc(width * sizeof(*src_16));

    if (!src_16)
      return false;

    src_16_end = src_16 + width;

    for (line = 0; line < lines; line++) {
      uint32_t *src_32_temp;
      uint16_t *src_16_temp;

      for (src_32_temp = src, src_16_temp = src_16;
           src_16_temp != src_16_end;
           src_16_temp++) {
        uint32_t src_32_value = *src_32_temp++;
        *src_16_temp = (uint16_t)(
            ((src_32_value & 0x00F80000) >> 8) |
            ((src_32_value & 0x0000FC00) >> 5) |
            ((src_32_value & 0x000000F8) >> 3)
          );
      }
      memcpy(dst, src_16, width * buffer->bytes_per_pixel);

      dst += buffer->row_stride * buffer->bytes_per_pixel;
      src += area->width;
    }

    free(src_16);
  } else if (width == area->width && width == buffer->row_stride) {
    memcpy(dst, src, width * lines * sizeof(*data));
  } else {
    int line;

    for (line = 0; line < lines; line++) {
      memcpy(dst, src, width * sizeof(*data));
      dst += buffer->row_stride * sizeof(*data);
      src += area->width;
    }
  }

  return true;
}


const char *ply_frame_buffer_get_bytes(ply_frame_buffer_t *buffer) {
  return (char *) buffer->shadow_buffer;
}


void ply_frame_buffer_clear(ply_frame_buffer_t *buffer,
                            uint32_t clear_color) {
  int i;
  int fb_size = buffer->row_stride * buffer->area.height;
  uint32_t fb_clear_color;
  assert(buffer != NULL);
  assert(ply_frame_buffer_device_is_open(buffer));

  fb_clear_color =
      ply_frame_buffer_pixel_value_to_device_pixel_value(buffer,
                                                         clear_color);

  switch (buffer->bytes_per_pixel) {
    case 4: {
      uint32_t* ptr = (uint32_t*) buffer->map_address;
      for (i = 0; i < fb_size; i++)
        *ptr++ = fb_clear_color;
      break;
    }
    case 2: {
      uint16_t* ptr = (uint16_t*) buffer->map_address;
      for (i = 0; i < fb_size; i++)
        *ptr++ = fb_clear_color;
      break;
    }
    default:
      assert(0);
  }
}
