/* ply-image.c - png file loader
 *
 * Copyright (C) 2006, 2007 Red Hat, Inc.
 * Copyright (C) 2003 University of Southern California
 *
 * 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.
 *
 * Some implementation taken from the cairo library.
 *
 * Shamelessly taken and unmercifully hacked for temporary use
 * in Chrome OS.
 *
 * Written by: Charlie Brej <cbrej@cs.man.ac.uk>
 *             Kristian Høgsberg <krh@redhat.com>
 *             Ray Strode <rstrode@redhat.com>
 *             Carl D. Worth <cworth@cworth.org>
 */

#include <assert.h>
#include <errno.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>

// <png.h> depends on <math.h> but doesn't include it.  Boo!
//
// Also, <png.h> includes <setjmp.h> and is designed to break if we
// re-include it.  Boo!
#include <math.h>
#include <png.h>

#include "ply-frame-buffer.h"
#include "ply-gamma.h"
#include "ply-utils.h"


typedef union {
  uint32_t *as_pixels;
  png_byte *as_png_bytes;
  char *address;
} ply_image_layout_t;

typedef struct {
  char  *filename;
  FILE  *fp;

  ply_image_layout_t layout;
  size_t size;

  png_uint_32 width;
  png_uint_32 height;
} ply_image_t;


static bool ply_image_open_file(ply_image_t *image) {
  assert(image != NULL);

  image->fp = fopen(image->filename, "r");

  return image->fp != NULL;
}

static void ply_image_close_file(ply_image_t *image) {
  assert(image != NULL);

  if (image->fp == NULL)
    return;
  fclose(image->fp);
  image->fp = NULL;
}

static ply_image_t *ply_image_new(const char *filename) {
  ply_image_t *image;

  assert(filename != NULL);

  image = calloc(1, sizeof(*image));

  image->filename = strdup(filename);
  image->fp = NULL;
  image->layout.address = NULL;
  image->size = -1;
  image->width = -1;
  image->height = -1;

  return image;
}

static void ply_image_free(ply_image_t *image) {
  if (image == NULL)
    return;

  assert(image->filename != NULL);

  if (image->layout.address != NULL) {
    free(image->layout.address);
    image->layout.address = NULL;
  }

  free(image->filename);
  free(image);
}

/*
 * The following function courtesy of Intel Moblin's
 * plymouth-lite port.
 */
static void transform_to_rgb32(png_struct   *png,
                               png_row_info *row_info,
                               png_byte     *data) {
  unsigned int i;

  for (i = 0; i < row_info->rowbytes; i += 4) {
    uint8_t  red, green, blue, alpha;
    uint32_t pixel_value;

    red = data[i + 0];
    green = data[i + 1];
    blue = data[i + 2];
    alpha = data[i + 3];
    pixel_value = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
    memcpy(data + i, &pixel_value, sizeof(pixel_value));
  }
}

static bool ply_image_load(ply_image_t *image) {
  png_struct *png;
  png_info *info;
  png_uint_32 width, height, bytes_per_row, row;
  int bits_per_pixel, color_type, interlace_method;
  png_byte **rows;

  assert(image != NULL);

  if (!ply_image_open_file(image))
    return false;

  png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
  assert(png != NULL);

  info = png_create_info_struct(png);
  assert(info != NULL);

  png_init_io(png, image->fp);

  if (setjmp(png_jmpbuf(png)) != 0) {
    ply_image_close_file(image);
    return false;
  }

  png_read_info(png, info);
  png_get_IHDR(png, info,
               &width, &height, &bits_per_pixel,
               &color_type, &interlace_method, NULL, NULL);
  bytes_per_row = 4 * width;

  if (color_type == PNG_COLOR_TYPE_PALETTE)
    png_set_palette_to_rgb(png);

  if ((color_type == PNG_COLOR_TYPE_GRAY) && (bits_per_pixel < 8))
    png_set_gray_1_2_4_to_8(png);

  if (png_get_valid(png, info, PNG_INFO_tRNS))
    png_set_tRNS_to_alpha(png);

  if (bits_per_pixel == 16)
    png_set_strip_16(png);

  if (bits_per_pixel < 8)
    png_set_packing(png);

  if ((color_type == PNG_COLOR_TYPE_GRAY) ||
      (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
    png_set_gray_to_rgb(png);

  if (interlace_method != PNG_INTERLACE_NONE)
    png_set_interlace_handling(png);

  png_set_filler(png, 0xff, PNG_FILLER_AFTER);

  png_set_read_user_transform_fn(png, transform_to_rgb32);

  png_read_update_info(png, info);

  rows = malloc(height * sizeof(*rows));
  image->layout.address = malloc(height * bytes_per_row);

  for (row = 0; row < height; row++)
    rows[row] = &image->layout.as_png_bytes[row * bytes_per_row];

  png_read_image(png, rows);

  free(rows);
  png_read_end(png, info);
  ply_image_close_file(image);
  png_destroy_read_struct(&png, &info, NULL);

  image->width = width;
  image->height = height;

  return true;
}

static uint32_t *ply_image_get_data(ply_image_t *image) {
  assert(image != NULL);

  return image->layout.as_pixels;
}

static long ply_image_get_width(ply_image_t *image) {
  assert(image != NULL);

  return image->width;
}

static long ply_image_get_height(ply_image_t *image) {
  assert(image != NULL);

  return image->height;
}

static ply_image_t *ply_image_from_file(const char *path) {
  ply_image_t *image = ply_image_new(path);

  if (!ply_image_load(image)) {
    perror(path);
    exit(errno);
  }
  return image;
}

static bool center_image = true;
static ply_frame_buffer_area_t image_location, image_offset;
static uint32_t clear_color;

static void ply_frame_buffer_show_file(
    ply_frame_buffer_t *buffer, const char *path) {
  ply_image_t *image;
  uint32_t *data;
  ply_frame_buffer_area_t area, buffer_area;
  bool fill_succeeded;

  image = ply_image_from_file(path);

  area.width = ply_image_get_width(image);
  area.height = ply_image_get_height(image);
  data = ply_image_get_data(image);

  if (center_image) {
    ply_frame_buffer_get_size(buffer, &buffer_area);
    area.x = (long) (buffer_area.width - area.width) / 2;
    area.y = (long) (buffer_area.height - area.height) / 2;
  } else {
    area.x = image_location.x;
    area.y = image_location.y;
  }

  area.x += image_offset.x;
  area.y += image_offset.y;
  fill_succeeded = ply_frame_buffer_fill(buffer, &area, data);

  if (!fill_succeeded)
    fprintf(stderr, "image was not displayed\n");

  ply_image_free(image);
}


static int usage(void) {
  fprintf(stderr,
          "usage: ply-image --clear <hexcolor>\n"
          "       ply-image [--gamma <gammafile>] "
          "[--location <x>,<y> | --offset <[+|-]x>,<[+|-]y>] "
          "<frame> [<frame> ...]\n");
  exit(EXIT_FAILURE);
}


static bool parse_color(const char *arg) {
  char *endptr;

  clear_color = strtol(arg, &endptr, 16);
  if (endptr == arg || *endptr != '\0') {
    return false;
  }

  return true;
}

static bool parse_xy(const char *arg, ply_frame_buffer_area_t *area) {
  char *endptr;
  long x, y;

  x = strtol(arg, &endptr, 10);
  if (endptr == arg || *endptr != ',') {
    return false;
  }

  arg = endptr + 1;
  y = strtol(arg, &endptr, 10);
  if (endptr == arg || *endptr != '\0') {
    return false;
  }

  area->x = x;
  area->y = y;

  return true;
}

static bool parse_location(const char *arg) {
  bool result = parse_xy(arg, &image_location);
  if (result)
    center_image = false;
  return result;
}

static bool parse_offset(const char *arg) {
  return parse_xy(arg, &image_offset);
}


#define MS_PER_SEC      1000
#define NS_PER_SEC      (1000 * 1000 * 1000)
#define NS_PER_MS       (NS_PER_SEC / MS_PER_SEC)
#define FRAMES_PER_SEC  20

/* Frame rate as milliseconds per frame */
static long frame_interval_ms = MS_PER_SEC / FRAMES_PER_SEC;

static bool set_frame_interval(const char *arg) {
  char *endptr;

  long interval = strtol(arg, &endptr, 10);
  if (endptr == arg || *endptr != '\0') {
    return false;
  }

  frame_interval_ms = interval;
  return true;
}


/*
 * Animate the series of images named on the command line.  The
 * animation is timed so that the average time per frame is
 * frame_interval_ms milliseconds.
 */
static void process_images(
    ply_frame_buffer_t *buffer, int argc, char *argv[]) {
  struct timespec curr_time, last_time;
  int64_t sleep_ns = 0;

  clock_gettime(CLOCK_MONOTONIC, &last_time);
  while (argc > 0) {
    if (sleep_ns > 0) {
      struct timespec sleep_time;
      sleep_time.tv_sec = sleep_ns / NS_PER_SEC;
      sleep_time.tv_nsec = sleep_ns % NS_PER_SEC;
      nanosleep(&sleep_time, NULL);
    } else {
      sleep_ns = 0;
    }

    ply_frame_buffer_show_file(buffer, argv[0]);

    clock_gettime(CLOCK_MONOTONIC, &curr_time);
    sleep_ns += frame_interval_ms * NS_PER_MS +
        NS_PER_SEC * (last_time.tv_sec - curr_time.tv_sec) +
        last_time.tv_nsec - curr_time.tv_nsec;
    last_time = curr_time;

    argc--;
    argv++;
  }
}


#define FLAG_CLEAR      'c'
#define FLAG_FRAME      'f'
#define FLAG_GAMMA      'g'
#define FLAG_HELP       'h'
#define FLAG_LOCATION   'l'
#define FLAG_OFFSET     'o'

static struct option command_options[] = {
  { "clear", required_argument, NULL, FLAG_CLEAR },
  { "frame-interval", required_argument, NULL, FLAG_FRAME },
  { "gamma", required_argument, NULL, FLAG_GAMMA },
  { "help", no_argument, NULL, FLAG_HELP },
  { "location", required_argument, NULL, FLAG_LOCATION },
  { "offset", required_argument, NULL, FLAG_OFFSET },
  { NULL, 0, NULL, 0 },
};


int main(int argc, char **argv) {
  int clear = 0;
  bool location_assigned = false, offset_assigned = false;
  ply_frame_buffer_t *buffer;

  /*
   * TODO(jrbarnette): The command line parsing here and throughout
   * the code is a bit rudimentary, especially w.r.t. error
   * checking.  This command is only invoked in a handful of places
   * in Chromium OS; outside of those cases, you should be grateful
   * any time the error message isn't
   *   Segmentation fault (core dumped)
   * :-)
   */
  for (;;) {
    int c = getopt_long(argc, argv, "", command_options, NULL);
    if (c == -1) {
      break;
    }

    if (c == FLAG_HELP) {
      usage();
    }

    if (c == FLAG_CLEAR) {
      clear = 1;
      if (!parse_color(optarg)) {
        usage();
      }
      continue;
    }

    if (c == FLAG_FRAME) {
      if (!set_frame_interval(optarg)) {
        usage();
      }
      continue;
    }

    if (c == FLAG_GAMMA) {
      // Not all platforms necessarily have a gamma ramp file, so we
      // ignore errors from this call.
      (void) ply_gamma_set(optarg);
      continue;
    }

    if (c == FLAG_LOCATION) {
      if (!parse_location(optarg)) {
        usage();
      }
      location_assigned = true;
      continue;
    }

    if (c == FLAG_OFFSET) {
      if (!parse_offset(optarg)) {
        usage();
      }
      offset_assigned = true;
      continue;
    }
  }

  if (location_assigned && offset_assigned) {
    fprintf(stderr,
            "--location and --offset should not be assigned at same time.\n");
    usage();
  }

  buffer = ply_frame_buffer_new(NULL);
  if (!ply_frame_buffer_open(buffer)) {
    perror("could not open framebuffer");
    return errno;
  }

  if (clear) {
    ply_frame_buffer_clear(buffer, clear_color);
  }

  process_images(buffer, argc - optind, argv + optind);
  return EXIT_SUCCESS;
}
