// Copyright 2020 The Wuffs Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// ----------------

/*
imageviewer is a simple GUI program for viewing images. On Linux, GUI means
X11. To run:

$CC imageviewer.c -lxcb -lxcb-image && \
  ./a.out ../../test/data/bricks-*.gif; rm -f a.out

for a C compiler $CC, such as clang or gcc.

The Space and BackSpace keys cycle through the files, if more than one was
given as command line arguments. If none were given, the program reads from
stdin.

The Return key is equivalent to the Space key.

The Escape key quits.
*/

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

// Wuffs ships as a "single file C library" or "header file library" as per
// https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
//
// To use that single file as a "foo.c"-like implementation, instead of a
// "foo.h"-like header, #define WUFFS_IMPLEMENTATION before #include'ing or
// compiling it.
#define WUFFS_IMPLEMENTATION

// Defining the WUFFS_CONFIG__MODULE* macros are optional, but it lets users of
// release/c/etc.c whitelist which parts of Wuffs to build. That file contains
// the entire Wuffs standard library, implementing a variety of codecs and file
// formats. Without this macro definition, an optimizing compiler or linker may
// very well discard Wuffs code for unused codecs, but listing the Wuffs
// modules we use makes that process explicit. Preprocessing means that such
// code simply isn't compiled.
#define WUFFS_CONFIG__MODULES
#define WUFFS_CONFIG__MODULE__BASE
#define WUFFS_CONFIG__MODULE__BMP
#define WUFFS_CONFIG__MODULE__GIF
#define WUFFS_CONFIG__MODULE__LZW
#define WUFFS_CONFIG__MODULE__WBMP

// If building this program in an environment that doesn't easily accommodate
// relative includes, you can use the script/inline-c-relative-includes.go
// program to generate a stand-alone C file.
#include "../../release/c/wuffs-unsupported-snapshot.c"

// X11 limits its image dimensions to uint16_t.
#define MAX_DIMENSION 65535

#define NUM_BACKGROUND_COLORS 3
#define SRC_BUFFER_ARRAY_SIZE (64 * 1024)

// Global variable names start with a "g_" prefix.

wuffs_base__color_u32_argb_premul g_background_colors[NUM_BACKGROUND_COLORS] = {
    0xFF000000,
    0xFFFFFFFF,
    0xFFA9009A,
};

FILE* g_file = NULL;
const char* g_filename = NULL;
uint32_t g_width = 0;
uint32_t g_height = 0;
wuffs_base__slice_u8 g_workbuf_slice = {0};
wuffs_base__slice_u8 g_pixbuf_slice = {0};
wuffs_base__pixel_buffer g_pixbuf = {0};
uint8_t g_src_buffer_array[SRC_BUFFER_ARRAY_SIZE] = {0};
wuffs_base__io_buffer g_src = {0};
wuffs_base__image_config g_image_config = {0};
wuffs_base__image_decoder* g_image_decoder = NULL;
uint32_t g_background_color_index = 0;

union {
  wuffs_bmp__decoder bmp;
  wuffs_gif__decoder gif;
  wuffs_wbmp__decoder wbmp;
} g_potential_decoders;

bool  //
read_more_src() {
  if (g_src.meta.closed) {
    printf("%s: unexpected end of file\n", g_filename);
    return false;
  }
  wuffs_base__io_buffer__compact(&g_src);
  g_src.meta.wi += fread(g_src.data.ptr + g_src.meta.wi, sizeof(uint8_t),
                         g_src.data.len - g_src.meta.wi, g_file);
  if (feof(g_file)) {
    g_src.meta.closed = true;
  } else if (ferror(g_file)) {
    printf("%s: read error\n", g_filename);
    return false;
  }
  return true;
}

bool  //
load_image_type() {
  while (g_src.meta.wi == 0) {
    if (!read_more_src()) {
      return false;
    }
  }

  wuffs_base__status status;
  switch (g_src_buffer_array[0]) {
    case '\x00':
      status = wuffs_wbmp__decoder__initialize(
          &g_potential_decoders.wbmp, sizeof g_potential_decoders.wbmp,
          WUFFS_VERSION, WUFFS_INITIALIZE__DEFAULT_OPTIONS);
      if (!wuffs_base__status__is_ok(&status)) {
        printf("%s: %s\n", g_filename, wuffs_base__status__message(&status));
        return false;
      }
      g_image_decoder =
          wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder(
              &g_potential_decoders.wbmp);
      break;

    case 'B':
      status = wuffs_bmp__decoder__initialize(
          &g_potential_decoders.bmp, sizeof g_potential_decoders.bmp,
          WUFFS_VERSION, WUFFS_INITIALIZE__DEFAULT_OPTIONS);
      if (!wuffs_base__status__is_ok(&status)) {
        printf("%s: %s\n", g_filename, wuffs_base__status__message(&status));
        return false;
      }
      g_image_decoder =
          wuffs_bmp__decoder__upcast_as__wuffs_base__image_decoder(
              &g_potential_decoders.bmp);
      break;

    case 'G':
      status = wuffs_gif__decoder__initialize(
          &g_potential_decoders.gif, sizeof g_potential_decoders.gif,
          WUFFS_VERSION, WUFFS_INITIALIZE__DEFAULT_OPTIONS);
      if (!wuffs_base__status__is_ok(&status)) {
        printf("%s: %s\n", g_filename, wuffs_base__status__message(&status));
        return false;
      }
      g_image_decoder =
          wuffs_gif__decoder__upcast_as__wuffs_base__image_decoder(
              &g_potential_decoders.gif);
      break;

    default:
      printf("%s: unrecognized file format\n", g_filename);
      return false;
  }
  return true;
}

bool  //
load_image_config() {
  // Decode the wuffs_base__image_config.
  while (true) {
    wuffs_base__status status = wuffs_base__image_decoder__decode_image_config(
        g_image_decoder, &g_image_config, &g_src);

    if (status.repr == NULL) {
      break;
    } else if (status.repr != wuffs_base__suspension__short_read) {
      printf("%s: %s\n", g_filename, wuffs_base__status__message(&status));
      return false;
    }

    if (!read_more_src()) {
      return false;
    }
  }

  // Read the dimensions.
  uint32_t w = wuffs_base__pixel_config__width(&g_image_config.pixcfg);
  uint32_t h = wuffs_base__pixel_config__height(&g_image_config.pixcfg);
  if ((w > MAX_DIMENSION) || (h > MAX_DIMENSION)) {
    printf("%s: image is too large\n", g_filename);
    return false;
  }
  g_width = w;
  g_height = h;

  // Override the image's native pixel format to be BGRA_PREMUL.
  wuffs_base__pixel_config__set(&g_image_config.pixcfg,
                                WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
                                WUFFS_BASE__PIXEL_SUBSAMPLING__NONE, w, h);

  // Allocate the work buffer memory.
  uint64_t workbuf_len =
      wuffs_base__image_decoder__workbuf_len(g_image_decoder).max_incl;
  if (workbuf_len > SIZE_MAX) {
    printf("%s: out of memory\n", g_filename);
    return false;
  }
  if (workbuf_len > 0) {
    void* p = malloc(workbuf_len);
    if (!p) {
      printf("%s: out of memory\n", g_filename);
      return false;
    }
    g_workbuf_slice.ptr = (uint8_t*)p;
    g_workbuf_slice.len = workbuf_len;
  }

  // Allocate the pixel buffer memory.
  uint64_t num_pixels = ((uint64_t)w) * ((uint64_t)h);
  if (num_pixels > (SIZE_MAX / sizeof(wuffs_base__color_u32_argb_premul))) {
    printf("%s: image is too large\n", g_filename);
    return false;
  }
  size_t n = num_pixels * sizeof(wuffs_base__color_u32_argb_premul);
  void* p = malloc(n);
  if (!p) {
    printf("%s: out of memory\n", g_filename);
    return false;
  }
  {
    uint8_t* ptr = (uint8_t*)p;
    wuffs_base__color_u32_argb_premul color =
        g_background_colors[g_background_color_index];
    for (size_t i = 0; i < num_pixels; i++) {
      wuffs_base__store_u32le__no_bounds_check(ptr, color);
      ptr += 4;
    }
  }
  g_pixbuf_slice.ptr = (uint8_t*)p;
  g_pixbuf_slice.len = n;

  // Configure the wuffs_base__pixel_buffer struct.
  wuffs_base__status status = wuffs_base__pixel_buffer__set_from_slice(
      &g_pixbuf, &g_image_config.pixcfg, g_pixbuf_slice);
  if (!wuffs_base__status__is_ok(&status)) {
    printf("%s: %s\n", g_filename, wuffs_base__status__message(&status));
    return false;
  }

  return true;
}

// This function always returns true. If we get this far, we still display a
// partial image, even if we encounter an error.
bool  //
load_image_frame() {
  while (true) {
    wuffs_base__status status = wuffs_base__image_decoder__decode_frame(
        g_image_decoder, &g_pixbuf, &g_src, WUFFS_BASE__PIXEL_BLEND__SRC_OVER,
        g_workbuf_slice, NULL);

    if (status.repr == NULL) {
      break;
    } else if (status.repr != wuffs_base__suspension__short_read) {
      printf("%s: %s\n", g_filename, wuffs_base__status__message(&status));
      return true;
    }

    if (!read_more_src()) {
      return true;
    }
  }

  uint32_t w = wuffs_base__pixel_config__width(&g_image_config.pixcfg);
  uint32_t h = wuffs_base__pixel_config__height(&g_image_config.pixcfg);
  printf("%s: ok (%" PRIu32 " x %" PRIu32 ")\n", g_filename, w, h);
  return true;
}

bool  //
load_image(const char* filename) {
  if (g_workbuf_slice.ptr != NULL) {
    free(g_workbuf_slice.ptr);
    g_workbuf_slice.ptr = NULL;
    g_workbuf_slice.len = 0;
  }
  if (g_pixbuf_slice.ptr != NULL) {
    free(g_pixbuf_slice.ptr);
    g_pixbuf_slice.ptr = NULL;
    g_pixbuf_slice.len = 0;
  }
  g_width = 0;
  g_height = 0;
  g_src.data.ptr = g_src_buffer_array;
  g_src.data.len = SRC_BUFFER_ARRAY_SIZE;
  g_src.meta.wi = 0;
  g_src.meta.ri = 0;
  g_src.meta.pos = 0;
  g_src.meta.closed = false;
  g_image_config = wuffs_base__null_image_config();
  g_image_decoder = NULL;

  g_file = stdin;
  g_filename = "<stdin>";
  if (filename) {
    FILE* f = fopen(filename, "r");
    if (f == NULL) {
      printf("%s: could not open file\n", filename);
      return false;
    }
    g_file = f;
    g_filename = filename;
  }

  bool ret = load_image_type() && load_image_config() && load_image_frame();
  if (filename) {
    fclose(g_file);
    g_file = NULL;
  }
  return ret;
}

  // ---------------------------------------------------------------------

#if defined(__linux__)
#define SUPPORTED_OPERATING_SYSTEM

#include <xcb/xcb.h>
#include <xcb/xcb_image.h>

#define XK_BackSpace 0xFF08
#define XK_Escape 0xFF1B
#define XK_Return 0xFF0D

xcb_atom_t g_atom_net_wm_name = XCB_NONE;
xcb_atom_t g_atom_utf8_string = XCB_NONE;
xcb_atom_t g_atom_wm_protocols = XCB_NONE;
xcb_atom_t g_atom_wm_delete_window = XCB_NONE;
xcb_pixmap_t g_pixmap = XCB_NONE;
xcb_keysym_t* g_keysyms = NULL;
xcb_get_keyboard_mapping_reply_t* g_keyboard_mapping = NULL;

void  //
init_keymap(xcb_connection_t* c, const xcb_setup_t* z) {
  xcb_get_keyboard_mapping_cookie_t cookie = xcb_get_keyboard_mapping(
      c, z->min_keycode, z->max_keycode - z->min_keycode + 1);
  g_keyboard_mapping = xcb_get_keyboard_mapping_reply(c, cookie, NULL);
  g_keysyms = (xcb_keysym_t*)(g_keyboard_mapping + 1);
}

xcb_window_t  //
make_window(xcb_connection_t* c, xcb_screen_t* s) {
  xcb_window_t w = xcb_generate_id(c);
  uint32_t value_mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
  uint32_t value_list[2];
  value_list[0] = s->black_pixel;
  value_list[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
  xcb_create_window(c, 0, w, s->root, 0, 0, 1024, 768, 0,
                    XCB_WINDOW_CLASS_INPUT_OUTPUT, s->root_visual, value_mask,
                    value_list);
  xcb_change_property(c, XCB_PROP_MODE_REPLACE, w, g_atom_net_wm_name,
                      g_atom_utf8_string, 8, 12, "Image Viewer");
  xcb_change_property(c, XCB_PROP_MODE_REPLACE, w, g_atom_wm_protocols,
                      XCB_ATOM_ATOM, 32, 1, &g_atom_wm_delete_window);
  xcb_map_window(c, w);
  return w;
}

bool  //
load(xcb_connection_t* c,
     xcb_screen_t* s,
     xcb_window_t w,
     xcb_gcontext_t g,
     const char* filename) {
  if (g_pixmap != XCB_NONE) {
    xcb_free_pixmap(c, g_pixmap);
  }

  if (!load_image(filename)) {
    return false;
  }

  xcb_create_pixmap(c, s->root_depth, g_pixmap, w, g_width, g_height);
  xcb_image_t* image = xcb_image_create_native(
      c, g_width, g_height, XCB_IMAGE_FORMAT_Z_PIXMAP, s->root_depth, NULL,
      g_pixbuf_slice.len, g_pixbuf_slice.ptr);
  xcb_image_put(c, g_pixmap, g, image, 0, 0, 0);
  xcb_image_destroy(image);
  return true;
}

int  //
main(int argc, char** argv) {
  xcb_connection_t* c = xcb_connect(NULL, NULL);
  const xcb_setup_t* z = xcb_get_setup(c);
  xcb_screen_t* s = xcb_setup_roots_iterator(z).data;

  {
    xcb_intern_atom_cookie_t cookie0 =
        xcb_intern_atom(c, 1, 12, "_NET_WM_NAME");
    xcb_intern_atom_cookie_t cookie1 = xcb_intern_atom(c, 1, 11, "UTF8_STRING");
    xcb_intern_atom_cookie_t cookie2 =
        xcb_intern_atom(c, 1, 12, "WM_PROTOCOLS");
    xcb_intern_atom_cookie_t cookie3 =
        xcb_intern_atom(c, 1, 16, "WM_DELETE_WINDOW");
    xcb_intern_atom_reply_t* reply0 = xcb_intern_atom_reply(c, cookie0, NULL);
    xcb_intern_atom_reply_t* reply1 = xcb_intern_atom_reply(c, cookie1, NULL);
    xcb_intern_atom_reply_t* reply2 = xcb_intern_atom_reply(c, cookie2, NULL);
    xcb_intern_atom_reply_t* reply3 = xcb_intern_atom_reply(c, cookie3, NULL);
    g_atom_net_wm_name = reply0->atom;
    g_atom_utf8_string = reply1->atom;
    g_atom_wm_protocols = reply2->atom;
    g_atom_wm_delete_window = reply3->atom;
    free(reply0);
    free(reply1);
    free(reply2);
    free(reply3);
  }

  xcb_window_t w = make_window(c, s);
  xcb_gcontext_t g = xcb_generate_id(c);
  xcb_create_gc(c, g, w, 0, NULL);
  init_keymap(c, z);
  xcb_flush(c);
  g_pixmap = xcb_generate_id(c);

  bool loaded = load(c, s, w, g, (argc > 1) ? argv[1] : NULL);
  int arg = 1;

  while (true) {
    xcb_generic_event_t* event = xcb_wait_for_event(c);
    bool reload = false;

    switch (event->response_type & 0x7F) {
      case XCB_EXPOSE: {
        xcb_expose_event_t* e = (xcb_expose_event_t*)event;
        if (loaded && (e->count == 0)) {
          xcb_copy_area(c, g_pixmap, w, g, 0, 0, 0, 0, g_width, g_height);
          xcb_flush(c);
        }
        break;
      }

      case XCB_KEY_PRESS: {
        xcb_key_press_event_t* e = (xcb_key_press_event_t*)event;
        uint32_t i = e->detail;
        if ((z->min_keycode <= i) && (i <= z->max_keycode)) {
          i = g_keysyms[(i - z->min_keycode) *
                        g_keyboard_mapping->keysyms_per_keycode];
          switch (i) {
            case XK_Escape:
              return 0;

            case ' ':
            case XK_BackSpace:
            case XK_Return:
              if (argc <= 2) {
                break;
              }
              arg += (i != XK_BackSpace) ? +1 : -1;
              if (arg == 0) {
                arg = argc - 1;
              } else if (arg == argc) {
                arg = 1;
              }
              reload = true;
              break;

            case ',':
            case '.':
              g_background_color_index +=
                  (i == ',') ? (NUM_BACKGROUND_COLORS - 1) : 1;
              g_background_color_index %= NUM_BACKGROUND_COLORS;
              reload = true;
              break;
          }
        }
        break;
      }

      case XCB_CLIENT_MESSAGE: {
        xcb_client_message_event_t* e = (xcb_client_message_event_t*)event;
        if (e->data.data32[0] == g_atom_wm_delete_window) {
          return 0;
        }
        break;
      }
    }

    free(event);

    if (reload) {
      loaded = load(c, s, w, g, argv[arg]);
      xcb_clear_area(c, 1, w, 0, 0, 0xFFFF, 0xFFFF);
      xcb_flush(c);
    }
  }
  return 0;
}

#endif  // defined(__linux__)

  // ---------------------------------------------------------------------

#if !defined(SUPPORTED_OPERATING_SYSTEM)

int  //
main(int argc, char** argv) {
  printf("unsupported operating system\n");
  return 1;
}

#endif  // !defined(SUPPORTED_OPERATING_SYSTEM)
