// 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:

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

for a C++ compiler $CXX, such as clang++ or g++.

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 choose 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__ADLER32
#define WUFFS_CONFIG__MODULE__AUX__BASE
#define WUFFS_CONFIG__MODULE__AUX__IMAGE
#define WUFFS_CONFIG__MODULE__BASE
#define WUFFS_CONFIG__MODULE__BMP
#define WUFFS_CONFIG__MODULE__CRC32
#define WUFFS_CONFIG__MODULE__DEFLATE
#define WUFFS_CONFIG__MODULE__GIF
#define WUFFS_CONFIG__MODULE__LZW
#define WUFFS_CONFIG__MODULE__NIE
#define WUFFS_CONFIG__MODULE__PNG
#define WUFFS_CONFIG__MODULE__WBMP
#define WUFFS_CONFIG__MODULE__ZLIB

// 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_INCL_DIMENSION 65535

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

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

uint32_t g_width = 0;
uint32_t g_height = 0;
wuffs_aux::MemOwner g_pixbuf_mem_owner(nullptr, &free);
wuffs_base__slice_u8 g_pixbuf_mem_slice = {0};
uint32_t g_background_color_index = 0;

class Callbacks : public wuffs_aux::DecodeImageCallbacks {
  wuffs_base__image_decoder::unique_ptr  //
  OnImageFormat(uint32_t fourcc, wuffs_base__slice_u8 prefix) override {
    switch (fourcc) {
      case WUFFS_BASE__FOURCC__BMP:
        return wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();
      case WUFFS_BASE__FOURCC__GIF:
        return wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();
      case WUFFS_BASE__FOURCC__NIE:
        return wuffs_nie__decoder::alloc_as__wuffs_base__image_decoder();
      case WUFFS_BASE__FOURCC__PNG: {
        auto dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();
        dec->set_quirk_enabled(WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, true);
        return dec;
      }
      case WUFFS_BASE__FOURCC__WBMP:
        return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();
    }
    return wuffs_base__image_decoder::unique_ptr(nullptr, &free);
  }

  DecodeImageCallbacks::AllocResult  //
  OnImageConfig(const wuffs_base__image_config& image_config) override {
    uint32_t w = image_config.pixcfg.width();
    uint32_t h = image_config.pixcfg.height();
    if ((w == 0) || (h == 0)) {
      return DecodeImageCallbacks::AllocResult("");
    }
    uint64_t len = image_config.pixcfg.pixbuf_len();
    if ((len == 0) || (SIZE_MAX < len)) {
      return DecodeImageCallbacks::AllocResult(
          wuffs_aux::DecodeImage_UnsupportedPixelConfiguration);
    }
    void* ptr = malloc((size_t)len);
    if (!ptr) {
      return DecodeImageCallbacks::AllocResult(
          wuffs_aux::DecodeImage_OutOfMemory);
    }

    // Fill in the background color. The default OnImageConfig implementation
    // fills with zeroes (transparent black).
    wuffs_base__color_u32_argb_premul color =
        g_background_colors[g_background_color_index];
    uint8_t* p4 = (uint8_t*)ptr;
    size_t n4 = ((size_t)len) / 4;
    for (size_t i = 0; i < n4; i++) {
      wuffs_base__poke_u32le__no_bounds_check(p4, color);
      p4 += 4;
    }

    return DecodeImageCallbacks::AllocResult(
        wuffs_aux::MemOwner(ptr, &free),
        wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
  }
};

bool  //
load_image(const char* filename) {
  FILE* file = stdin;
  const char* adj_filename = "<stdin>";
  if (filename) {
    FILE* f = fopen(filename, "r");
    if (f == NULL) {
      printf("%s: could not open file\n", filename);
      return false;
    }
    file = f;
    adj_filename = filename;
  }

  g_width = 0;
  g_height = 0;
  g_pixbuf_mem_owner.reset();
  g_pixbuf_mem_slice = wuffs_base__empty_slice_u8();

  Callbacks callbacks;
  wuffs_aux::sync_io::FileInput input(file);
  wuffs_aux::DecodeImageResult res = wuffs_aux::DecodeImage(
      callbacks, input, WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL,
      // Use PIXEL_BLEND__SRC_OVER, not the default PIXEL_BLEND__SRC, because
      // we override OnImageConfig to fill in the background color.
      WUFFS_BASE__PIXEL_BLEND__SRC_OVER, MAX_INCL_DIMENSION);
  if (filename) {
    fclose(file);
  }

  g_width = res.pixbuf.pixcfg.width();
  g_height = res.pixbuf.pixcfg.height();
  g_pixbuf_mem_owner = std::move(res.pixbuf_mem_owner);
  g_pixbuf_mem_slice = res.pixbuf_mem_slice;

  if (res.error_message.empty()) {
    printf("%s: ok (%" PRIu32 " x %" PRIu32 ")\n", adj_filename, g_width,
           g_height);
  } else {
    printf("%s: %s\n", adj_filename, res.error_message.c_str());
  }
  return res.pixbuf.pixcfg.is_valid();
}

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

#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_mem_slice.len, g_pixbuf_mem_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)
