#ifndef OT_GLYF_GLYPH_HH
#define OT_GLYF_GLYPH_HH


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

#include "GlyphHeader.hh"
#include "SimpleGlyph.hh"
#include "CompositeGlyph.hh"


namespace OT {

struct glyf_accelerator_t;

namespace glyf_impl {


#ifndef HB_GLYF_MAX_POINTS
#define HB_GLYF_MAX_POINTS 10000
#endif


enum phantom_point_index_t
{
  PHANTOM_LEFT   = 0,
  PHANTOM_RIGHT  = 1,
  PHANTOM_TOP    = 2,
  PHANTOM_BOTTOM = 3,
  PHANTOM_COUNT  = 4
};

struct Glyph
{
  enum glyph_type_t { EMPTY, SIMPLE, COMPOSITE };

  public:
  composite_iter_t get_composite_iterator () const
  {
    if (type != COMPOSITE) return composite_iter_t ();
    return CompositeGlyph (*header, bytes).iter ();
  }

  const hb_bytes_t trim_padding () const
  {
    switch (type) {
    case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding ();
    case SIMPLE:    return SimpleGlyph (*header, bytes).trim_padding ();
    default:        return bytes;
    }
  }

  void drop_hints ()
  {
    switch (type) {
    case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return;
    case SIMPLE:    SimpleGlyph (*header, bytes).drop_hints (); return;
    default:        return;
    }
  }

  void set_overlaps_flag ()
  {
    switch (type) {
    case COMPOSITE: CompositeGlyph (*header, bytes).set_overlaps_flag (); return;
    case SIMPLE:    SimpleGlyph (*header, bytes).set_overlaps_flag (); return;
    default:        return;
    }
  }

  void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
  {
    switch (type) {
    case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return;
    case SIMPLE:    SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return;
    default:        return;
    }
  }

  void update_mtx (const hb_subset_plan_t *plan,
                   int xMin, int yMax,
                   const contour_point_vector_t &all_points) const
  {
    hb_codepoint_t new_gid = 0;
    if (!plan->new_gid_for_old_gid (gid, &new_gid))
      return;

    unsigned len = all_points.length;
    float leftSideX = all_points[len - 4].x;
    float rightSideX = all_points[len - 3].x;
    float topSideY = all_points[len - 2].y;
    float bottomSideY = all_points[len - 1].y;

    int hori_aw = roundf (rightSideX - leftSideX);
    if (hori_aw < 0) hori_aw = 0;
    int lsb = roundf (xMin - leftSideX);
    plan->hmtx_map->set (new_gid, hb_pair (hori_aw, lsb));

    int vert_aw = roundf (topSideY - bottomSideY);
    if (vert_aw < 0) vert_aw = 0;
    int tsb = roundf (topSideY - yMax);
    plan->vmtx_map->set (new_gid, hb_pair (vert_aw, tsb));
  }

  bool compile_header_bytes (const hb_subset_plan_t *plan,
                             const contour_point_vector_t &all_points,
                             hb_bytes_t &dest_bytes /* OUT */) const
  {
    GlyphHeader *glyph_header = nullptr;
    if (type != EMPTY && all_points.length > 4)
    {
      glyph_header = (GlyphHeader *) hb_calloc (1, GlyphHeader::static_size);
      if (unlikely (!glyph_header)) return false;
    }

    int xMin = 0, xMax = 0;
    int yMin = 0, yMax = 0;
    if (all_points.length > 4)
    {
      xMin = xMax = roundf (all_points[0].x);
      yMin = yMax = roundf (all_points[0].y);
    }

    for (unsigned i = 1; i < all_points.length - 4; i++)
    {
      float rounded_x = roundf (all_points[i].x);
      float rounded_y = roundf (all_points[i].y);
      xMin = hb_min (xMin, rounded_x);
      xMax = hb_max (xMax, rounded_x);
      yMin = hb_min (yMin, rounded_y);
      yMax = hb_max (yMax, rounded_y);
    }

    update_mtx (plan, xMin, yMax, all_points);

    /*for empty glyphs: all_points only include phantom points.
     *just update metrics and then return */
    if (!glyph_header)
      return true;

    glyph_header->numberOfContours = header->numberOfContours;
    glyph_header->xMin = xMin;
    glyph_header->yMin = yMin;
    glyph_header->xMax = xMax;
    glyph_header->yMax = yMax;

    dest_bytes = hb_bytes_t ((const char *)glyph_header, GlyphHeader::static_size);
    return true;
  }

  bool compile_bytes_with_deltas (const hb_subset_plan_t *plan,
                                  hb_font_t *font,
                                  const glyf_accelerator_t &glyf,
                                  hb_bytes_t &dest_start,  /* IN/OUT */
                                  hb_bytes_t &dest_end /* OUT */)
  {
    contour_point_vector_t all_points, deltas;
    if (!get_points (font, glyf, all_points, &deltas, false, false))
      return false;

    // .notdef, set type to empty so we only update metrics and don't compile bytes for
    // it
    if (gid == 0 &&
        !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
      type = EMPTY;

    switch (type) {
    case COMPOSITE:
      if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start,
                                                                      deltas,
                                                                      dest_end))
        return false;
      break;
    case SIMPLE:
      if (!SimpleGlyph (*header, bytes).compile_bytes_with_deltas (all_points,
                                                                   plan->flags & HB_SUBSET_FLAGS_NO_HINTING,
                                                                   dest_end))
        return false;
      break;
    default:
      /* set empty bytes for empty glyph
       * do not use source glyph's pointers */
      dest_start = hb_bytes_t ();
      dest_end = hb_bytes_t ();
      break;
    }

    if (!compile_header_bytes (plan, all_points, dest_start))
    {
      dest_end.fini ();
      return false;
    }
    return true;
  }


  /* Note: Recursively calls itself.
   * all_points includes phantom points
   */
  template <typename accelerator_t>
  bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
		   contour_point_vector_t &all_points /* OUT */,
		   contour_point_vector_t *deltas = nullptr, /* OUT */
		   bool shift_points_hori = true,
		   bool use_my_metrics = true,
		   bool phantom_only = false,
		   unsigned int depth = 0) const
  {
    if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false;
    contour_point_vector_t stack_points;
    bool inplace = type == SIMPLE && all_points.length == 0;
    /* Load into all_points if it's empty, as an optimization. */
    contour_point_vector_t &points = inplace ? all_points : stack_points;

    switch (type) {
    case COMPOSITE:
    {
      /* pseudo component points for each component in composite glyph */
      unsigned num_points = hb_len (CompositeGlyph (*header, bytes).iter ());
      if (unlikely (!points.resize (num_points))) return false;
      break;
    }
    case SIMPLE:
      if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
	return false;
      break;
    }

    /* Init phantom points */
    if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
    hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
    {
      int lsb = 0;
      int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ?
		    (int) header->xMin - lsb : 0;
      int tsb = 0;
      int v_orig  = (int) header->yMax +
#ifndef HB_NO_VERTICAL
		    ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb)
#else
		    0
#endif
		    ;
      unsigned h_adv = glyf_accelerator.hmtx->get_advance_without_var_unscaled (gid);
      unsigned v_adv =
#ifndef HB_NO_VERTICAL
		       glyf_accelerator.vmtx->get_advance_without_var_unscaled (gid)
#else
		       - font->face->get_upem ()
#endif
		       ;
      phantoms[PHANTOM_LEFT].x = h_delta;
      phantoms[PHANTOM_RIGHT].x = h_adv + h_delta;
      phantoms[PHANTOM_TOP].y = v_orig;
      phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
    }

    if (deltas != nullptr && depth == 0 && type == COMPOSITE)
    {
      if (unlikely (!deltas->resize (points.length))) return false;
      deltas->copy_vector (points);
    }

#ifndef HB_NO_VAR
    glyf_accelerator.gvar->apply_deltas_to_points (gid, font, points.as_array ());
#endif

    // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
    // with child glyphs' points
    if (deltas != nullptr && depth == 0 && type == COMPOSITE)
    {
      for (unsigned i = 0 ; i < points.length; i++)
      {
        deltas->arrayZ[i].x = points.arrayZ[i].x - deltas->arrayZ[i].x;
        deltas->arrayZ[i].y = points.arrayZ[i].y - deltas->arrayZ[i].y;
      }
    }

    switch (type) {
    case SIMPLE:
      if (!inplace)
	all_points.extend (points.as_array ());
      break;
    case COMPOSITE:
    {
      contour_point_vector_t comp_points;
      unsigned int comp_index = 0;
      for (auto &item : get_composite_iterator ())
      {
        comp_points.reset ();
	if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
				       .get_points (font, glyf_accelerator, comp_points,
						    deltas, shift_points_hori, use_my_metrics, phantom_only, depth + 1)))
	  return false;

	/* Apply component transformation & translation */
	item.transform_points (comp_points);

	/* Apply translation from gvar */
	comp_points.translate (points[comp_index]);

	if (item.is_anchored ())
	{
	  unsigned int p1, p2;
	  item.get_anchor_points (p1, p2);
	  if (likely (p1 < all_points.length && p2 < comp_points.length))
	  {
	    contour_point_t delta;
	    delta.init (all_points[p1].x - comp_points[p2].x,
			all_points[p1].y - comp_points[p2].y);

	    comp_points.translate (delta);
	  }
	}

	/* Copy phantom points from component if USE_MY_METRICS flag set */
	if (use_my_metrics && item.is_use_my_metrics ())
	  for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
	    phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];

	if (all_points.length > HB_GLYF_MAX_POINTS)
	  return false;

	all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT));

	comp_index++;
      }

      all_points.extend (phantoms);
    } break;
    default:
      all_points.extend (phantoms);
    }

    if (depth == 0 && shift_points_hori) /* Apply at top level */
    {
      /* Undocumented rasterizer behavior:
       * Shift points horizontally by the updated left side bearing
       */
      contour_point_t delta;
      delta.init (-phantoms[PHANTOM_LEFT].x, 0.f);
      if (delta.x) all_points.translate (delta);
    }

    return !all_points.in_error ();
  }

  bool get_extents_without_var_scaled (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator,
				       hb_glyph_extents_t *extents) const
  {
    if (type == EMPTY) return true; /* Empty glyph; zero extents. */
    return header->get_extents_without_var_scaled (font, glyf_accelerator, gid, extents);
  }

  hb_bytes_t get_bytes () const { return bytes; }

  Glyph () : bytes (),
             header (bytes.as<GlyphHeader> ()),
             gid (-1),
             type(EMPTY)
  {}

  Glyph (hb_bytes_t bytes_,
	 hb_codepoint_t gid_ = (unsigned) -1) : bytes (bytes_),
                                                header (bytes.as<GlyphHeader> ()),
                                                gid (gid_)
  {
    int num_contours = header->numberOfContours;
    if (unlikely (num_contours == 0)) type = EMPTY;
    else if (num_contours > 0) type = SIMPLE;
    else type = COMPOSITE; /* negative numbers */
  }

  protected:
  hb_bytes_t bytes;
  const GlyphHeader *header;
  hb_codepoint_t gid;
  unsigned type;
};


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


#endif /* OT_GLYF_GLYPH_HH */
