/*
 * Copyright © 2011  Google, Inc.
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Google Author(s): Behdad Esfahbod
 */

#ifndef HELPER_CAIRO_HH
#define HELPER_CAIRO_HH

#include "view-options.hh"
#include "output-options.hh"
#include "helper-image-output.hh"
#ifdef HAVE_CAIRO_FT
#  include "helper-cairo-ft.hh"
#endif

#include <cairo.h>
#include <hb.h>
#include <hb-cairo.h>
#include <hb-ot.h>

#include "helper-cairo-ansi.hh"
#ifdef CAIRO_HAS_SVG_SURFACE
#  include <cairo-svg.h>
#endif
#ifdef CAIRO_HAS_PDF_SURFACE
#  include <cairo-pdf.h>
#endif
#ifdef CAIRO_HAS_PS_SURFACE
#  include <cairo-ps.h>
#  define HAS_EPS 1

static cairo_surface_t *
_cairo_eps_surface_create_for_stream (cairo_write_func_t  write_func,
				      void               *closure,
				      double              width,
				      double              height)
{
  cairo_surface_t *surface;

  surface = cairo_ps_surface_create_for_stream (write_func, closure, width, height);
  cairo_ps_surface_set_eps (surface, true);

  return surface;
}

#endif
#ifdef CAIRO_HAS_SCRIPT_SURFACE
#   include <cairo-script.h>
#endif

static inline bool
helper_cairo_use_hb_draw (const font_options_t *font_opts)
{
  const char *env = getenv ("HB_DRAW");
  if (!env)
    /* Older cairo had a bug in rendering COLRv0 fonts in
     * right-to-left direction as well as clipping issue
     * with user-fonts.
     *
     * https://github.com/harfbuzz/harfbuzz/issues/4051 */
    return cairo_version () >= CAIRO_VERSION_ENCODE (1, 17, 5);

  return atoi (env);
}

static inline cairo_scaled_font_t *
helper_cairo_create_scaled_font (const font_options_t *font_opts,
				 const view_options_t *view_opts)
{
  hb_font_t *font = font_opts->font;
  bool use_hb_draw = true;

#ifdef HAVE_CAIRO_FT
  use_hb_draw = helper_cairo_use_hb_draw (font_opts);
#endif


  cairo_font_face_t *cairo_face = nullptr;
  if (use_hb_draw)
  {
    cairo_face = hb_cairo_font_face_create_for_font (font);
    hb_cairo_font_face_set_scale_factor (cairo_face, 1 << font_opts->subpixel_bits);
  }
#ifdef HAVE_CAIRO_FT
  else
    cairo_face = helper_cairo_create_ft_font_face (font_opts);
#endif

  cairo_matrix_t ctm, font_matrix;
  cairo_font_options_t *font_options;

  cairo_matrix_init_identity (&ctm);
  cairo_matrix_init_scale (&font_matrix,
			   font_opts->font_size_x,
			   font_opts->font_size_y);
  if (!use_hb_draw)
    font_matrix.xy = -font_opts->slant * font_opts->font_size_x;

  font_options = cairo_font_options_create ();
  cairo_font_options_set_hint_style (font_options, CAIRO_HINT_STYLE_NONE);
  cairo_font_options_set_hint_metrics (font_options, CAIRO_HINT_METRICS_OFF);
#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1,18,0)
  /* Pick draw vs paint mode.  --paint wins over --draw;
   * otherwise auto-detect: route mono fonts through the
   * cheaper outline path (NO_COLOR) and color fonts through
   * the paint pipeline (cairo's default color mode). */
  hb_face_t *hb_face = hb_font_get_face (font);
  bool font_has_color = hb_ot_color_has_paint (hb_face) ||
			hb_ot_color_has_layers (hb_face) ||
			hb_ot_color_has_png (hb_face);
  bool use_paint = view_opts->force_paint ? true
		 : view_opts->force_draw  ? false
		 : font_has_color;
  if (!use_paint)
    cairo_font_options_set_color_mode (font_options, CAIRO_COLOR_MODE_NO_COLOR);
#endif
#ifdef CAIRO_COLOR_PALETTE_DEFAULT
  cairo_font_options_set_color_palette (font_options, view_opts->palette);
#endif
#ifdef HAVE_CAIRO_FONT_OPTIONS_GET_CUSTOM_PALETTE_COLOR
  if (view_opts->custom_palette_entries)
  {
    for (unsigned i = 0; i < view_opts->custom_palette_entries->len; i++)
    {
      auto &entry =
        g_array_index (view_opts->custom_palette_entries,
                       typename view_options_t::custom_palette_entry_t, i);
      cairo_font_options_set_custom_palette_color (font_options, entry.index,
                                                   entry.color.r / 255.,
                                                   entry.color.g / 255.,
                                                   entry.color.b / 255.,
                                                   entry.color.a / 255.);
    }
  }
#endif

  cairo_scaled_font_t *scaled_font = cairo_scaled_font_create (cairo_face,
							       &font_matrix,
							       &ctm,
							       font_options);
  if (cairo_scaled_font_status (scaled_font) == CAIRO_STATUS_INVALID_MATRIX)
  {
    // Set font matrix to 0, which *does* work with cairo_scaled_font_create()
    font_matrix.xx = font_matrix.yy = 0;
    font_matrix.xy = font_matrix.yx = 0;
    font_matrix.x0 = font_matrix.y0 = 0;
    scaled_font = cairo_scaled_font_create (cairo_face,
					    &font_matrix,
					    &ctm,
					    font_options);

  }

  cairo_font_options_destroy (font_options);
  cairo_font_face_destroy (cairo_face);

  return scaled_font;
}

static inline bool
helper_cairo_scaled_font_has_color (cairo_scaled_font_t *scaled_font)
{
  hb_font_t *font = hb_cairo_font_face_get_font (cairo_scaled_font_get_font_face (scaled_font));

#ifdef HAVE_CAIRO_FT
  if (!font)
    return helper_cairo_ft_scaled_font_has_color (scaled_font);
#endif

  hb_face_t *face = hb_font_get_face (font);

  return hb_ot_color_has_png (face) ||
         hb_ot_color_has_layers (face) ||
         hb_ot_color_has_paint (face);
}

struct finalize_closure_t {
  void (*callback)(finalize_closure_t *);
  cairo_surface_t *surface;
  cairo_write_func_t write_func;
  void *closure;
  helper_image_protocol_t protocol;
};
static cairo_user_data_key_t finalize_closure_key;


static void
finalize_ansi (finalize_closure_t *closure)
{
  cairo_status_t status;
  status = helper_cairo_surface_write_to_ansi_stream (closure->surface,
						      closure->write_func,
						      closure->closure);
  if (status != CAIRO_STATUS_SUCCESS)
    fail (false, "Failed to write output: %s",
	  cairo_status_to_string (status));
}

static cairo_surface_t *
_cairo_ansi_surface_create_for_stream (cairo_write_func_t write_func,
				       void *closure,
				       double width,
				       double height,
				       cairo_content_t content,
				       helper_image_protocol_t protocol HB_UNUSED)
{
  cairo_surface_t *surface;
  int w = ceil (width);
  int h = ceil (height);

  switch (content) {
    case CAIRO_CONTENT_ALPHA:
      surface = cairo_image_surface_create (CAIRO_FORMAT_A8, w, h);
      break;
    default:
    case CAIRO_CONTENT_COLOR:
      surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h);
      break;
    case CAIRO_CONTENT_COLOR_ALPHA:
      surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
      break;
  }
  cairo_status_t status = cairo_surface_status (surface);
  if (status != CAIRO_STATUS_SUCCESS)
    fail (false, "Failed to create cairo surface: %s",
	  cairo_status_to_string (status));

  finalize_closure_t *ansi_closure = g_new0 (finalize_closure_t, 1);
  ansi_closure->callback = finalize_ansi;
  ansi_closure->surface = surface;
  ansi_closure->write_func = write_func;
  ansi_closure->closure = closure;

  if (cairo_surface_set_user_data (surface,
				   &finalize_closure_key,
				   (void *) ansi_closure,
				   (cairo_destroy_func_t) g_free))
    g_free ((void *) closure);

  return surface;
}


#ifdef CAIRO_HAS_PNG_FUNCTIONS

static cairo_status_t
byte_array_write_func (void                *closure,
		       const unsigned char *data,
		       unsigned int         size)
{
  g_byte_array_append ((GByteArray *) closure, data, size);
  return CAIRO_STATUS_SUCCESS;
}

static void
finalize_png (finalize_closure_t *closure)
{
  cairo_status_t status;
  GByteArray *bytes = nullptr;

  if (closure->protocol == helper_image_protocol_t::NONE)
  {
    status = cairo_surface_write_to_png_stream (closure->surface,
						closure->write_func,
						closure->closure);
  }
  else
  {
    bytes = g_byte_array_new ();
    status = cairo_surface_write_to_png_stream (closure->surface,
						byte_array_write_func,
						bytes);
  }

  if (status != CAIRO_STATUS_SUCCESS)
    fail (false, "Failed to write output: %s",
	  cairo_status_to_string (status));

  if (closure->protocol == helper_image_protocol_t::NONE)
    return;
  helper_image_write_png_data (bytes->data, bytes->len,
			       closure->write_func, closure->closure,
			       closure->protocol);

  g_byte_array_unref (bytes);
}

static cairo_surface_t *
_cairo_png_surface_create_for_stream (cairo_write_func_t write_func,
				      void *closure,
				      double width,
				      double height,
				      cairo_content_t content,
				      helper_image_protocol_t protocol)
{
  cairo_surface_t *surface;
  int w = ceil (width);
  int h = ceil (height);

  switch (content) {
    case CAIRO_CONTENT_ALPHA:
      surface = cairo_image_surface_create (CAIRO_FORMAT_A8, w, h);
      break;
    default:
    case CAIRO_CONTENT_COLOR:
      surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, w, h);
      break;
    case CAIRO_CONTENT_COLOR_ALPHA:
      surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h);
      break;
  }
  cairo_status_t status = cairo_surface_status (surface);
  if (status != CAIRO_STATUS_SUCCESS)
    fail (false, "Failed to create cairo surface: %s",
	  cairo_status_to_string (status));

  finalize_closure_t *png_closure = g_new0 (finalize_closure_t, 1);
  png_closure->callback = finalize_png;
  png_closure->surface = surface;
  png_closure->write_func = write_func;
  png_closure->closure = closure;
  png_closure->protocol = protocol;

  if (cairo_surface_set_user_data (surface,
				   &finalize_closure_key,
				   (void *) png_closure,
				   (cairo_destroy_func_t) g_free))
    g_free ((void *) closure);

  return surface;
}

#endif

#ifdef CAIRO_HAS_SCRIPT_SURFACE

static cairo_surface_t *
_cairo_script_surface_create_for_stream (cairo_write_func_t write_func,
				         void *closure,
				         double width,
				         double height,
				         cairo_content_t content,
				         helper_image_protocol_t protocol HB_UNUSED)
{
  cairo_device_t *script = cairo_script_create_for_stream (write_func, closure);
  cairo_surface_t *surface = cairo_script_surface_create (script, content, width, height);
  cairo_device_destroy (script);
  return surface;
}

#endif

static const char *helper_cairo_supported_formats[] =
{
#ifdef CAIRO_HAS_PNG_FUNCTIONS
  "png",
#endif
  #ifdef CAIRO_HAS_SVG_SURFACE
  "svg",
  #endif
  #ifdef CAIRO_HAS_PDF_SURFACE
  "pdf",
  #endif
  #ifdef CAIRO_HAS_PS_SURFACE
  "ps",
   #ifdef HAS_EPS
    "eps",
   #endif
  #endif
  #ifdef CAIRO_HAS_SCRIPT_SURFACE
  "script",
  #endif
  "ansi",
  nullptr
};

template <typename view_options_t,
	 typename output_options_type>
static inline cairo_t *
helper_cairo_create_context (double w, double h,
			     view_options_t *view_opts,
			     output_options_type *out_opts,
			     cairo_content_t content)
{
  cairo_surface_t *(*constructor) (cairo_write_func_t write_func,
				   void *closure,
				   double width,
				   double height) = nullptr;
  cairo_surface_t *(*constructor2) (cairo_write_func_t write_func,
				    void *closure,
				    double width,
				    double height,
				    cairo_content_t content,
				    helper_image_protocol_t protocol) = nullptr;

  helper_image_protocol_t protocol = helper_image_protocol_t::NONE;
  const char *extension = out_opts->output_format;
  if (!extension)
    extension = helper_image_get_implicit_output_format (out_opts->out_fp,
#ifdef CAIRO_HAS_PNG_FUNCTIONS
							 "png",
#else
							 "ansi",
#endif
							 &protocol);
  if (0)
    ;
    else if (0 == g_ascii_strcasecmp (extension, "ansi"))
      constructor2 = _cairo_ansi_surface_create_for_stream;
  #ifdef CAIRO_HAS_PNG_FUNCTIONS
    else if (0 == g_ascii_strcasecmp (extension, "png"))
      constructor2 = _cairo_png_surface_create_for_stream;
  #endif
  #ifdef CAIRO_HAS_SVG_SURFACE
    else if (0 == g_ascii_strcasecmp (extension, "svg"))
      constructor = cairo_svg_surface_create_for_stream;
  #endif
  #ifdef CAIRO_HAS_PDF_SURFACE
    else if (0 == g_ascii_strcasecmp (extension, "pdf"))
      constructor = cairo_pdf_surface_create_for_stream;
  #endif
  #ifdef CAIRO_HAS_PS_SURFACE
    else if (0 == g_ascii_strcasecmp (extension, "ps"))
      constructor = cairo_ps_surface_create_for_stream;
   #ifdef HAS_EPS
    else if (0 == g_ascii_strcasecmp (extension, "eps"))
      constructor = _cairo_eps_surface_create_for_stream;
   #endif
   #ifdef CAIRO_HAS_SCRIPT_SURFACE
    else if (0 == g_ascii_strcasecmp (extension, "script"))
      constructor2 = _cairo_script_surface_create_for_stream;
   #endif
  #endif


  unsigned int fr, fg, fb, fa, br, bg, bb, ba;
  br = view_opts->background_color.r;
  bg = view_opts->background_color.g;
  bb = view_opts->background_color.b;
  ba = view_opts->background_color.a;
  fr = view_opts->foreground_color.r;
  fg = view_opts->foreground_color.g;
  fb = view_opts->foreground_color.b;
  fa = view_opts->foreground_color.a;
  bool foreground_has_color = false;
  bool foreground_has_alpha = false;
  bool stroke_has_color = false;
  bool stroke_has_alpha = false;
  using rgba_color_t = typename view_options_t::rgba_color_t;

  if (view_opts->foreground_use_palette &&
      view_opts->foreground_palette &&
      view_opts->foreground_palette->len)
  {
    auto &first = g_array_index (view_opts->foreground_palette,
				 rgba_color_t, 0);
    fr = first.r;
    fg = first.g;
    fb = first.b;
    fa = first.a;
    foreground_has_color = view_opts->foreground_palette->len > 1;
    for (unsigned i = 0; i < view_opts->foreground_palette->len; i++)
    {
      auto &c = g_array_index (view_opts->foreground_palette,
			       rgba_color_t, i);
      foreground_has_color |= c.r != c.g || c.g != c.b;
      foreground_has_alpha |= c.a != 255;
    }
  }
  else
  {
    foreground_has_color = fr != fg || fg != fb;
    foreground_has_alpha = fa != 255;
  }

  if (view_opts->stroke_enabled)
  {
    auto &stroke = view_opts->stroke_color;
    stroke_has_color = stroke.r != stroke.g || stroke.g != stroke.b;
    stroke_has_alpha = stroke.a != 255;
  }

  if (content == CAIRO_CONTENT_ALPHA)
  {
    if (view_opts->show_extents ||
			br != bg || bg != bb ||
			foreground_has_color ||
			stroke_has_color)
      content = CAIRO_CONTENT_COLOR;
  }
  if (ba != 255 || foreground_has_alpha || stroke_has_alpha)
    content = CAIRO_CONTENT_COLOR_ALPHA;

  cairo_surface_t *surface;
  FILE *f = out_opts->out_fp;
  if (constructor)
    surface = constructor (helper_image_stdio_write_func, f, w, h);
  else if (constructor2)
    surface = constructor2 (helper_image_stdio_write_func, f, w, h, content, protocol);
  else
    fail (false, "Unknown output format `%s'; supported formats are: %s%s",
	  extension,
	  g_strjoinv ("/", const_cast<char**> (helper_cairo_supported_formats)),
	  out_opts->explicit_output_format ? "" :
	  "\nTry setting format using --output-format");

  cairo_t *cr = cairo_create (surface);
  content = cairo_surface_get_content (surface);

  switch (content) {
    case CAIRO_CONTENT_ALPHA:
      cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
      cairo_set_source_rgba (cr, 1., 1., 1., br / 255.);
      cairo_paint (cr);
      cairo_set_source_rgba (cr, 1., 1., 1.,
			     (fr / 255.) * (fa / 255.) + (br / 255.) * (1 - (fa / 255.)));
      break;
    default:
    case CAIRO_CONTENT_COLOR:
    case CAIRO_CONTENT_COLOR_ALPHA:
      cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
      cairo_set_source_rgba (cr, br / 255., bg / 255., bb / 255., ba / 255.);
      cairo_paint (cr);
      cairo_set_source_rgba (cr, fr / 255., fg / 255., fb / 255., fa / 255.);
      break;
  }

  cairo_surface_destroy (surface);
  return cr;
}

static inline void
helper_cairo_destroy_context (cairo_t *cr)
{
  finalize_closure_t *closure = (finalize_closure_t *)
				cairo_surface_get_user_data (cairo_get_target (cr),
							     &finalize_closure_key);
  if (closure)
    closure->callback (closure);

  cairo_status_t status = cairo_status (cr);
  if (status != CAIRO_STATUS_SUCCESS)
    fail (false, "Failed: %s",
	  cairo_status_to_string (status));
  cairo_destroy (cr);
}


struct helper_cairo_line_t {
  cairo_glyph_t *glyphs = nullptr;
  unsigned int num_glyphs = 0;
  char *utf8 = nullptr;
  unsigned int utf8_len = 0;
  cairo_text_cluster_t *clusters = nullptr;
  unsigned int num_clusters = 0;
  cairo_text_cluster_flags_t cluster_flags = (cairo_text_cluster_flags_t) 0;

  helper_cairo_line_t (const char          *utf8_,
		       unsigned             utf8_len_,
		       hb_buffer_t         *buffer,
		       hb_bool_t            utf8_clusters,
		       unsigned             subpixel_bits) :
    utf8 (utf8_ ? g_strndup (utf8_, utf8_len_) : nullptr),
    utf8_len (utf8_len_)
  {
    hb_cairo_glyphs_from_buffer (buffer,
				 utf8_clusters,
				 1 << subpixel_bits, 1 << subpixel_bits,
				 0., 0.,
				 utf8, utf8_len,
				 &glyphs, &num_glyphs,
				 &clusters, &num_clusters,
				 &cluster_flags);
  }

  void finish ()
  {
    if (glyphs)
      cairo_glyph_free (glyphs);
    if (clusters)
      cairo_text_cluster_free (clusters);
    g_free (utf8);
  }

  void get_advance (double *x_advance, double *y_advance)
  {
    *x_advance = glyphs[num_glyphs].x;
    *y_advance = glyphs[num_glyphs].y;
  }
};

#endif
