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

#define _WIN32_WINNT 0x0500

#include "hb-private.hh"

#include <windows.h>
#include <usp10.h>

typedef ULONG WIN_ULONG;

#include "hb-uniscribe.h"

#include "hb-ot-name-private.hh"
#include "hb-ot-tag.h"

#include "hb-font-private.hh"
#include "hb-buffer-private.hh"



#ifndef HB_DEBUG_UNISCRIBE
#define HB_DEBUG_UNISCRIBE (HB_DEBUG+0)
#endif


/*
DWORD GetFontData(
  __in   HDC hdc,
  __in   DWORD dwTable,
  __in   DWORD dwOffset,
  __out  LPVOID lpvBuffer,
  __in   DWORD cbData
);
*/

static bool
populate_log_font (LOGFONTW  *lf,
		   HDC        hdc,
		   hb_font_t *font)
{
  memset (lf, 0, sizeof (*lf));
  int dpi = GetDeviceCaps (hdc, LOGPIXELSY);
  lf->lfHeight = -font->y_scale;

  hb_blob_t *blob = Sanitizer<name>::sanitize (hb_face_reference_table (font->face, HB_TAG ('n','a','m','e')));
  const name *name_table = Sanitizer<name>::lock_instance (blob);
  unsigned int len = name_table->get_name (3, 1, 0x409, 4,
					   lf->lfFaceName,
					   sizeof (lf->lfFaceName[0]) * LF_FACESIZE)
					  / sizeof (lf->lfFaceName[0]);
  hb_blob_destroy (blob);

  if (unlikely (!len)) {
    DEBUG_MSG (UNISCRIBE, NULL, "Didn't find English name table entry");
    return FALSE;
  }
  if (unlikely (len >= LF_FACESIZE)) {
    DEBUG_MSG (UNISCRIBE, NULL, "Font name too long");
    return FALSE;
  }

  for (unsigned int i = 0; i < len; i++)
    lf->lfFaceName[i] = hb_be_uint16 (lf->lfFaceName[i]);
  lf->lfFaceName[len] = 0;

  return TRUE;
}


static struct hb_uniscribe_face_data_t{
  HANDLE fh;
} _hb_uniscribe_face_data_nil = {0};

static hb_user_data_key_t uniscribe_face_data_key;

static void
_hb_uniscribe_face_data_destroy (hb_uniscribe_face_data_t *data)
{
  if (data->fh)
    RemoveFontMemResourceEx (data->fh);
  free (data);
}

static hb_uniscribe_face_data_t *
_hb_uniscribe_face_get_data (hb_face_t *face)
{
  hb_uniscribe_face_data_t *data = (hb_uniscribe_face_data_t *) hb_face_get_user_data (face, &uniscribe_face_data_key);
  if (likely (data)) return data;

  data = (hb_uniscribe_face_data_t *) calloc (1, sizeof (hb_uniscribe_face_data_t));
  if (unlikely (!data))
    return &_hb_uniscribe_face_data_nil;

  hb_blob_t *blob = hb_face_reference_blob (face);
  unsigned int blob_length;
  const char *blob_data = hb_blob_get_data (blob, &blob_length);
  if (unlikely (!blob_length))
    DEBUG_MSG (UNISCRIBE, face, "Face has empty blob");

  DWORD num_fonts_installed;
  data->fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed);
  hb_blob_destroy (blob);
  if (unlikely (!data->fh))
    DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed");

  if (unlikely (!hb_face_set_user_data (face, &uniscribe_face_data_key, data,
					(hb_destroy_func_t) _hb_uniscribe_face_data_destroy,
					FALSE)))
  {
    _hb_uniscribe_face_data_destroy (data);
    data = (hb_uniscribe_face_data_t *) hb_face_get_user_data (face, &uniscribe_face_data_key);
    if (data)
      return data;
    else
      return &_hb_uniscribe_face_data_nil;
  }

  return data;
}


static struct hb_uniscribe_font_data_t {
  HDC hdc;
  HFONT hfont;
  SCRIPT_CACHE script_cache;
} _hb_uniscribe_font_data_nil = {NULL, NULL, NULL};

static hb_user_data_key_t uniscribe_font_data_key;

static void
_hb_uniscribe_font_data_destroy (hb_uniscribe_font_data_t *data)
{
  if (data->hdc)
    ReleaseDC (NULL, data->hdc);
  if (data->hfont)
    DeleteObject (data->hfont);
  if (data->script_cache)
    ScriptFreeCache (&data->script_cache);
  free (data);
}

static hb_uniscribe_font_data_t *
_hb_uniscribe_font_get_data (hb_font_t *font)
{
  hb_uniscribe_font_data_t *data = (hb_uniscribe_font_data_t *) hb_font_get_user_data (font, &uniscribe_font_data_key);
  if (likely (data)) return data;

  data = (hb_uniscribe_font_data_t *) calloc (1, sizeof (hb_uniscribe_font_data_t));
  if (unlikely (!data))
    return &_hb_uniscribe_font_data_nil;

  data->hdc = GetDC (NULL);

  LOGFONTW log_font;
  if (unlikely (!populate_log_font (&log_font, data->hdc, font)))
    DEBUG_MSG (UNISCRIBE, font, "Font populate_log_font() failed");
  else {
    data->hfont = CreateFontIndirectW (&log_font);
    if (unlikely (!data->hfont))
      DEBUG_MSG (UNISCRIBE, font, "Font CreateFontIndirectW() failed");
    if (!SelectObject (data->hdc, data->hfont))
      DEBUG_MSG (UNISCRIBE, font, "Font SelectObject() failed");
  }

  if (unlikely (!hb_font_set_user_data (font, &uniscribe_font_data_key, data,
					(hb_destroy_func_t) _hb_uniscribe_font_data_destroy,
					FALSE)))
  {
    _hb_uniscribe_font_data_destroy (data);
    data = (hb_uniscribe_font_data_t *) hb_font_get_user_data (font, &uniscribe_font_data_key);
    if (data)
      return data;
    else
      return &_hb_uniscribe_font_data_nil;
  }

  return data;
}


hb_bool_t
hb_uniscribe_shape (hb_font_t          *font,
		    hb_buffer_t        *buffer,
		    const hb_feature_t *features,
		    unsigned int        num_features,
		    const char         *shaper_options)
{
  buffer->guess_properties ();

#define FAIL(...) \
  HB_STMT_START { \
    DEBUG_MSG (UNISCRIBE, NULL, __VA_ARGS__); \
    return FALSE; \
  } HB_STMT_END;

  hb_uniscribe_face_data_t *face_data = _hb_uniscribe_face_get_data (font->face);
  if (unlikely (!face_data))
    FAIL ("Couldn't get face data");

  hb_uniscribe_font_data_t *font_data = _hb_uniscribe_font_get_data (font);
  if (unlikely (!font_data))
    FAIL ("Couldn't get font font");

  if (unlikely (!buffer->len))
    return TRUE;

  HRESULT hr;

retry:

  unsigned int scratch_size;
  char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);

  /* Allocate char buffers; they all fit */

#define ALLOCATE_ARRAY(Type, name, len) \
  Type *name = (Type *) scratch; \
  scratch += len * sizeof (name[0]); \
  scratch_size -= len * sizeof (name[0]);

#define utf16_index() var1.u32

  WCHAR *pchars = (WCHAR *) scratch;
  unsigned int chars_len = 0;
  for (unsigned int i = 0; i < buffer->len; i++) {
    hb_codepoint_t c = buffer->info[i].codepoint;
    buffer->info[i].utf16_index() = chars_len;
    if (likely (c < 0x10000))
      pchars[chars_len++] = c;
    else if (unlikely (c >= 0x110000))
      pchars[chars_len++] = 0xFFFD;
    else {
      pchars[chars_len++] = 0xD800 + ((c - 0x10000) >> 10);
      pchars[chars_len++] = 0xDC00 + ((c - 0x10000) & ((1 << 10) - 1));
    }
  }

  ALLOCATE_ARRAY (WCHAR, wchars, chars_len);
  ALLOCATE_ARRAY (WORD, log_clusters, chars_len);
  ALLOCATE_ARRAY (SCRIPT_CHARPROP, char_props, chars_len);

  /* On Windows, we don't care about alignment...*/
  unsigned int glyphs_size = scratch_size / (sizeof (WORD) +
					     sizeof (SCRIPT_GLYPHPROP) +
					     sizeof (int) +
					     sizeof (GOFFSET) +
					     sizeof (uint32_t));

  ALLOCATE_ARRAY (WORD, glyphs, glyphs_size);
  ALLOCATE_ARRAY (SCRIPT_GLYPHPROP, glyph_props, glyphs_size);
  ALLOCATE_ARRAY (int, advances, glyphs_size);
  ALLOCATE_ARRAY (GOFFSET, offsets, glyphs_size);
  ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size);


#define MAX_ITEMS 10

  SCRIPT_ITEM items[MAX_ITEMS + 1];
  SCRIPT_STATE bidi_state = {0};
  WIN_ULONG script_tags[MAX_ITEMS];
  int item_count;

  bidi_state.uBidiLevel = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1;
  bidi_state.fOverrideDirection = 1;

  hr = ScriptItemizeOpenType (wchars,
			      chars_len,
			      MAX_ITEMS,
			      NULL,
			      &bidi_state,
			      items,
			      script_tags,
			      &item_count);
  if (unlikely (FAILED (hr)))
    FAIL ("ScriptItemizeOpenType() failed: 0x%08xL", hr);

#undef MAX_ITEMS

  int *range_char_counts = NULL;
  TEXTRANGE_PROPERTIES **range_properties = NULL;
  int range_count = 0;
  if (num_features) {
    /* XXX setup ranges */
  }

  OPENTYPE_TAG language_tag = hb_ot_tag_from_language (buffer->props.language);

  unsigned int glyphs_offset = 0;
  unsigned int glyphs_len;
  for (unsigned int i = 0; i < item_count; i++)
  {
      unsigned int chars_offset = items[i].iCharPos;
      unsigned int item_chars_len = items[i + 1].iCharPos - chars_offset;
      OPENTYPE_TAG script_tag = script_tags[i]; /* XXX buffer->props.script */

      hr = ScriptShapeOpenType (font_data->hdc,
				&font_data->script_cache,
				&items[i].a,
				script_tag,
				language_tag,
				range_char_counts,
				range_properties,
				range_count,
				wchars + chars_offset,
				item_chars_len,
				glyphs_size - glyphs_offset,
				/* out */
				log_clusters + chars_offset,
				char_props + chars_offset,
				glyphs + glyphs_offset,
				glyph_props + glyphs_offset,
				(int *) &glyphs_len);

      if (unlikely (items[i].a.fNoGlyphIndex))
	FAIL ("ScriptShapeOpenType() set fNoGlyphIndex");
      if (unlikely (hr == E_OUTOFMEMORY))
      {
        buffer->ensure (buffer->allocated * 2);
	if (buffer->in_error)
	  FAIL ("Buffer resize failed");
	goto retry;
      }
      if (unlikely (hr == USP_E_SCRIPT_NOT_IN_FONT))
	FAIL ("ScriptShapeOpenType() failed: Font doesn't support script");
      if (unlikely (FAILED (hr)))
	FAIL ("ScriptShapeOpenType() failed: 0x%08xL", hr);

      hr = ScriptPlaceOpenType (font_data->hdc,
				&font_data->script_cache,
				&items[i].a,
				script_tag,
				language_tag,
				range_char_counts,
				range_properties,
				range_count,
				wchars + chars_offset,
				log_clusters + chars_offset,
				char_props + chars_offset,
				item_chars_len,
				glyphs + glyphs_offset,
				glyph_props + glyphs_offset,
				glyphs_len,
				/* out */
				advances + glyphs_offset,
				offsets + glyphs_offset,
				NULL);
      if (unlikely (FAILED (hr)))
	FAIL ("ScriptPlaceOpenType() failed: 0x%08xL", hr);

      glyphs_offset += glyphs_len;
  }
  glyphs_len = glyphs_offset;

  /* Ok, we've got everything we need, now compose output buffer,
   * very, *very*, carefully! */

  /* Calculate visual-clusters.  That's what we ship. */
  for (unsigned int i = 0; i < buffer->len; i++)
    vis_clusters[i] = 0;
  for (unsigned int i = 0; i < buffer->len; i++) {
    uint32_t *p = &vis_clusters[log_clusters[buffer->info[i].utf16_index()]];
    *p = MIN (*p, buffer->info[i].cluster);
  }
  for (unsigned int i = 1; i < glyphs_len; i++)
    if (!glyph_props[i].sva.fClusterStart)
    vis_clusters[i] = vis_clusters[i - 1];

#undef utf16_index

  buffer->ensure (glyphs_len);
  if (buffer->in_error)
    FAIL ("Buffer in error");

#undef FAIL

  /* Set glyph infos */
  for (unsigned int i = 0; i < glyphs_len; i++)
  {
    hb_glyph_info_t *info = &buffer->info[i];

    info->codepoint = glyphs[i];
    info->cluster = vis_clusters[i];

    /* The rest is crap.  Let's store position info there for now. */
    info->mask = advances[i];
    info->var1.u32 = offsets[i].du;
    info->var2.u32 = offsets[i].dv;
  }
  buffer->len = glyphs_len;

  /* Set glyph positions */
  buffer->clear_positions ();
  for (unsigned int i = 0; i < glyphs_len; i++)
  {
    hb_glyph_info_t *info = &buffer->info[i];
    hb_glyph_position_t *pos = &buffer->pos[i];

    /* TODO vertical */
    pos->x_advance = info->mask;
    pos->x_offset = info->var1.u32;
    pos->y_offset = info->var2.u32;
  }

  /* Wow, done! */
  return TRUE;
}


