#ifndef OT_GLYF_SUBSETGLYPH_HH
#define OT_GLYF_SUBSETGLYPH_HH


#include "../../hb-open-type.hh"


namespace OT {

struct glyf_accelerator_t;

namespace glyf_impl {


struct SubsetGlyph
{
  hb_codepoint_t old_gid;
  Glyph source_glyph;
  hb_bytes_t dest_start;  /* region of source_glyph to copy first */
  hb_bytes_t dest_end;    /* region of source_glyph to copy second */
  bool allocated;

  bool serialize (hb_serialize_context_t *c,
		  bool use_short_loca,
		  const hb_subset_plan_t *plan) const
  {
    TRACE_SERIALIZE (this);

    hb_bytes_t dest_glyph = dest_start.copy (c);
    hb_bytes_t end_copy = dest_end.copy (c);
    if (!end_copy.arrayZ || !dest_glyph.arrayZ) {
      return false;
    }

    dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + end_copy.length);
    unsigned int pad_length = use_short_loca ? padding () : 0;
    DEBUG_MSG (SUBSET, nullptr, "serialize %u byte glyph, width %u pad %u", dest_glyph.length, dest_glyph.length + pad_length, pad_length);

    HBUINT8 pad;
    pad = 0;
    while (pad_length > 0)
    {
      (void) c->embed (pad);
      pad_length--;
    }

    if (unlikely (!dest_glyph.length)) return_trace (true);

    /* update components gids. */
    for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
    {
      hb_codepoint_t new_gid;
      if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid))
	const_cast<CompositeGlyphRecord &> (_).set_gid (new_gid);
    }
#ifndef HB_NO_VAR_COMPOSITES
    for (auto &_ : Glyph (dest_glyph).get_var_composite_iterator ())
    {
      hb_codepoint_t new_gid;
      if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid))
	const_cast<VarCompositeGlyphRecord &> (_).set_gid (new_gid);
    }
#endif

#ifndef HB_NO_BEYOND_64K
    auto it = Glyph (dest_glyph).get_composite_iterator ();
    if (it)
    {
      /* lower GID24 to GID16 in components if possible.
       *
       * TODO: VarComposite. Not as critical, since VarComposite supports
       * gid24 from the first version. */
      char *p = it ? (char *) &*it : nullptr;
      char *q = p;
      const char *end = dest_glyph.arrayZ + dest_glyph.length;
      while (it)
      {
	auto &rec = const_cast<CompositeGlyphRecord &> (*it);
	++it;

	q += rec.get_size ();

	rec.lower_gid_24_to_16 ();

	unsigned size = rec.get_size ();

	memmove (p, &rec, size);

	p += size;
      }
      memmove (p, q, end - q);
      p += end - q;

      /* We want to shorten the glyph, but we can't do that without
       * updating the length in the loca table, which is already
       * written out :-(.  So we just fill the rest of the glyph with
       * harmless instructions, since that's what they will be
       * interpreted as.
       *
       * Should move the lowering to _populate_subset_glyphs() to
       * fix this issue. */

      hb_memset (p, 0x7A /* TrueType instruction ROFF; harmless */, end - p);
      p += end - p;
      dest_glyph = hb_bytes_t (dest_glyph.arrayZ, p - (char *) dest_glyph.arrayZ);

      // TODO: Padding; & trim serialized bytes.
      // TODO: Update length in loca. Ugh.
    }
#endif

    if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
      Glyph (dest_glyph).drop_hints ();

    if (plan->flags & HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG)
      Glyph (dest_glyph).set_overlaps_flag ();

    return_trace (true);
  }

  bool compile_bytes_with_deltas (const hb_subset_plan_t *plan,
                                  hb_font_t *font,
                                  const glyf_accelerator_t &glyf)
  {
    allocated = source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end);
    return allocated;
  }

  void free_compiled_bytes ()
  {
    if (likely (allocated)) {
      allocated = false;
      dest_start.fini ();
      dest_end.fini ();
    }
  }

  void drop_hints_bytes ()
  { source_glyph.drop_hints_bytes (dest_start, dest_end); }

  unsigned int      length () const { return dest_start.length + dest_end.length; }
  /* pad to 2 to ensure 2-byte loca will be ok */
  unsigned int     padding () const { return length () % 2; }
  unsigned int padded_size () const { return length () + padding (); }
};


} /* namespace glyf_impl */
} /* namespace OT */


#endif /* OT_GLYF_SUBSETGLYPH_HH */
