#ifndef OT_GLYF_GLYPH_HH
#define OT_GLYF_GLYPH_HH


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

#include "GlyphHeader.hh"
#include "SimpleGlyph.hh"
#include "CompositeGlyph.hh"
#include "VarCompositeGlyph.hh"
#include "coord-setter.hh"


namespace OT {

struct glyf_accelerator_t;

namespace glyf_impl {


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,
#ifndef HB_NO_VAR_COMPOSITES
    VAR_COMPOSITE,
#endif
  };

  public:
  composite_iter_t get_composite_iterator () const
  {
    if (type != COMPOSITE) return composite_iter_t ();
    return CompositeGlyph (*header, bytes).iter ();
  }
  var_composite_iter_t get_var_composite_iterator () const
  {
#ifndef HB_NO_VAR_COMPOSITES
    if (type != VAR_COMPOSITE) return var_composite_iter_t ();
    return VarCompositeGlyph (*header, bytes).iter ();
#else
    return var_composite_iter_t ();
#endif
  }

  const hb_bytes_t trim_padding () const
  {
    switch (type) {
#ifndef HB_NO_VAR_COMPOSITES
    case VAR_COMPOSITE: return VarCompositeGlyph (*header, bytes).trim_padding ();
#endif
    case COMPOSITE: return CompositeGlyph (*header, bytes).trim_padding ();
    case SIMPLE:    return SimpleGlyph (*header, bytes).trim_padding ();
    case EMPTY:     return bytes;
    default:        return bytes;
    }
  }

  void drop_hints ()
  {
    switch (type) {
#ifndef HB_NO_VAR_COMPOSITES
    case VAR_COMPOSITE: return; // No hinting
#endif
    case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints (); return;
    case SIMPLE:    SimpleGlyph (*header, bytes).drop_hints (); return;
    case EMPTY:     return;
    }
  }

  void set_overlaps_flag ()
  {
    switch (type) {
#ifndef HB_NO_VAR_COMPOSITES
    case VAR_COMPOSITE: return; // No overlaps flag
#endif
    case COMPOSITE: CompositeGlyph (*header, bytes).set_overlaps_flag (); return;
    case SIMPLE:    SimpleGlyph (*header, bytes).set_overlaps_flag (); return;
    case EMPTY:     return;
    }
  }

  void drop_hints_bytes (hb_bytes_t &dest_start, hb_bytes_t &dest_end) const
  {
    switch (type) {
#ifndef HB_NO_VAR_COMPOSITES
    case VAR_COMPOSITE: return; // No hinting
#endif
    case COMPOSITE: CompositeGlyph (*header, bytes).drop_hints_bytes (dest_start); return;
    case SIMPLE:    SimpleGlyph (*header, bytes).drop_hints_bytes (dest_start, dest_end); return;
    case EMPTY:     return;
    }
  }

  bool get_all_points_without_var (const hb_face_t *face,
                                   contour_point_vector_t &points /* OUT */) const
  {
    switch (type) {
    case SIMPLE:
      if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points)))
        return false;
      break;
    case COMPOSITE:
    {
      for (auto &item : get_composite_iterator ())
        if (unlikely (!item.get_points (points))) return false;
      break;
    }
#ifndef HB_NO_VAR_COMPOSITES
    case VAR_COMPOSITE:
    {
      for (auto &item : get_var_composite_iterator ())
        if (unlikely (!item.get_points (points))) return false;
      break;
    }
#endif
    case EMPTY:
      break;
    }

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

  void update_mtx (const hb_subset_plan_t *plan,
                   int xMin, int xMax,
                   int yMin, 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;

    if (type != EMPTY)
    {
      plan->bounds_width_vec[new_gid] = xMax - xMin;
      plan->bounds_height_vec[new_gid] = yMax - yMin;
    }

    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;

    uint32_t hash = hb_hash (new_gid);

    signed hori_aw = roundf (rightSideX - leftSideX);
    if (hori_aw < 0) hori_aw = 0;
    int lsb = roundf (xMin - leftSideX);
    plan->hmtx_map.set_with_hash (new_gid, hash, hb_pair ((unsigned) hori_aw, lsb));
    //flag value should be computed using non-empty glyphs
    if (type != EMPTY && lsb != xMin)
      plan->head_maxp_info.allXMinIsLsb = false;

    signed vert_aw = roundf (topSideY - bottomSideY);
    if (vert_aw < 0) vert_aw = 0;
    int tsb = roundf (topSideY - yMax);
    plan->vmtx_map.set_with_hash (new_gid, hash, hb_pair ((unsigned) 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 (!plan->pinned_at_default && type != EMPTY && all_points.length >= 4)
    {
      glyph_header = (GlyphHeader *) hb_calloc (1, GlyphHeader::static_size);
      if (unlikely (!glyph_header)) return false;
    }

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

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


    // These are destined for storage in a 16 bit field to clamp the values to
    // fit into a 16 bit signed integer.
    int rounded_xMin = hb_clamp (roundf (xMin), -32768.0f, 32767.0f);
    int rounded_xMax = hb_clamp (roundf (xMax), -32768.0f, 32767.0f);
    int rounded_yMin = hb_clamp (roundf (yMin), -32768.0f, 32767.0f);
    int rounded_yMax = hb_clamp (roundf (yMax), -32768.0f, 32767.0f);

    update_mtx (plan, rounded_xMin, rounded_xMax, rounded_yMin, rounded_yMax, all_points);

    if (type != EMPTY)
    {
      plan->head_maxp_info.xMin = hb_min (plan->head_maxp_info.xMin, rounded_xMin);
      plan->head_maxp_info.yMin = hb_min (plan->head_maxp_info.yMin, rounded_yMin);
      plan->head_maxp_info.xMax = hb_max (plan->head_maxp_info.xMax, rounded_xMax);
      plan->head_maxp_info.yMax = hb_max (plan->head_maxp_info.yMax, rounded_yMax);
    }

    /* when pinned at default, no need to compile glyph header
     * and 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 = rounded_xMin;
    glyph_header->yMin = rounded_yMin;
    glyph_header->xMax = rounded_xMax;
    glyph_header->yMax = rounded_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, points_with_deltas;
    unsigned composite_contours = 0;
    head_maxp_info_t *head_maxp_info_p = &plan->head_maxp_info;
    unsigned *composite_contours_p = &composite_contours;

    // don't compute head/maxp values when glyph has no contours(type is EMPTY)
    // also ignore .notdef glyph when --notdef-outline is not enabled
    if (type == EMPTY ||
        (gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)))
    {
      head_maxp_info_p = nullptr;
      composite_contours_p = nullptr;
    }

    if (!get_points (font, glyf, all_points, &points_with_deltas, head_maxp_info_p, composite_contours_p, 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;
      dest_start = hb_bytes_t ();
      dest_end = hb_bytes_t ();
    }

    //dont compile bytes when pinned at default, just recalculate bounds
    if (!plan->pinned_at_default)
    {
      switch (type)
      {
#ifndef HB_NO_VAR_COMPOSITES
      case VAR_COMPOSITE:
	// TODO
	dest_end = hb_bytes_t ();
	break;
#endif

      case COMPOSITE:
        if (!CompositeGlyph (*header, bytes).compile_bytes_with_deltas (dest_start,
                                                                        points_with_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;
      case EMPTY:
        /* 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 *points_with_deltas = nullptr, /* OUT */
		   head_maxp_info_t * head_maxp_info = nullptr, /* OUT */
		   unsigned *composite_contours = nullptr, /* OUT */
		   bool shift_points_hori = true,
		   bool use_my_metrics = true,
		   bool phantom_only = false,
		   hb_array_t<int> coords = hb_array_t<int> (),
		   hb_map_t *current_glyphs = nullptr,
		   unsigned int depth = 0,
		   unsigned *edge_count = nullptr) const
  {
    if (unlikely (depth > HB_MAX_NESTING_LEVEL)) return false;
    unsigned stack_edge_count = 0;
    if (!edge_count) edge_count = &stack_edge_count;
    if (unlikely (*edge_count > HB_GLYF_MAX_EDGE_COUNT)) return false;
    (*edge_count)++;

    hb_map_t current_glyphs_stack;
    if (current_glyphs == nullptr)
      current_glyphs = &current_glyphs_stack;

    if (head_maxp_info)
    {
      head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth);
    }

    if (!coords)
      coords = hb_array (font->coords, font->num_coords);

    contour_point_vector_t stack_points;
    contour_point_vector_t &points = type == SIMPLE ? all_points : stack_points;
    unsigned old_length = points.length;

    switch (type) {
    case SIMPLE:
      if (depth == 0 && head_maxp_info)
        head_maxp_info->maxContours = hb_max (head_maxp_info->maxContours, (unsigned) header->numberOfContours);
      if (depth > 0 && composite_contours)
        *composite_contours += (unsigned) header->numberOfContours;
      if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (all_points, phantom_only)))
	return false;
      break;
    case COMPOSITE:
    {
      for (auto &item : get_composite_iterator ())
        if (unlikely (!item.get_points (points))) return false;
      break;
    }
#ifndef HB_NO_VAR_COMPOSITES
    case VAR_COMPOSITE:
    {
      for (auto &item : get_var_composite_iterator ())
        if (unlikely (!item.get_points (points))) return false;
      break;
    }
#endif
    case EMPTY:
      break;
    }

    /* Init phantom points */
    if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
    hb_array_t<contour_point_t> phantoms = points.as_array ().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;
      HB_UNUSED 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 = (int) h_adv + h_delta;
      phantoms[PHANTOM_TOP].y = v_orig;
      phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
    }

#ifndef HB_NO_VAR
    if (coords)
      glyf_accelerator.gvar->apply_deltas_to_points (gid,
						     coords,
						     points.as_array ().sub_array (old_length),
						     phantom_only && type == SIMPLE);
#endif

    // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
    // with child glyphs' points
    if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE)
    {
      if (unlikely (!points_with_deltas->resize (points.length))) return false;
      *points_with_deltas = points;
    }

    switch (type) {
    case SIMPLE:
      if (depth == 0 && head_maxp_info)
        head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, all_points.length - old_length - 4);
      break;
    case COMPOSITE:
    {
      unsigned int comp_index = 0;
      for (auto &item : get_composite_iterator ())
      {
	hb_codepoint_t item_gid = item.get_gid ();

        if (unlikely (current_glyphs->has (item_gid)))
	  continue;

	current_glyphs->add (item_gid);

	unsigned old_count = all_points.length;

	if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) &&
		      !glyf_accelerator.glyph_for_gid (item_gid)
				       .get_points (font,
						    glyf_accelerator,
						    all_points,
						    points_with_deltas,
						    head_maxp_info,
						    composite_contours,
						    shift_points_hori,
						    use_my_metrics,
						    phantom_only,
						    coords,
						    current_glyphs,
						    depth + 1,
						    edge_count)))
	{
	  current_glyphs->del (item_gid);
	  return false;
	}

	auto comp_points = all_points.as_array ().sub_array (old_count);

	/* 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 (comp_points) // Empty in case of phantom_only
	{
	  float matrix[4];
	  contour_point_t default_trans;
	  item.get_transformation (matrix, default_trans);

	  /* Apply component transformation & translation (with deltas applied) */
	  item.transform_points (comp_points, matrix, points[comp_index]);
	}

	if (item.is_anchored () && !phantom_only)
	{
	  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);

	    item.translate (delta, comp_points);
	  }
	}

	all_points.resize (all_points.length - PHANTOM_COUNT);

	if (all_points.length > HB_GLYF_MAX_POINTS)
	{
	  current_glyphs->del (item_gid);
	  return false;
	}

	comp_index++;
        current_glyphs->del (item_gid);
      }

      if (head_maxp_info && depth == 0)
      {
        if (composite_contours)
          head_maxp_info->maxCompositeContours = hb_max (head_maxp_info->maxCompositeContours, *composite_contours);
        head_maxp_info->maxCompositePoints = hb_max (head_maxp_info->maxCompositePoints, all_points.length);
        head_maxp_info->maxComponentElements = hb_max (head_maxp_info->maxComponentElements, comp_index);
      }
      all_points.extend (phantoms);
    } break;
#ifndef HB_NO_VAR_COMPOSITES
    case VAR_COMPOSITE:
    {
      hb_array_t<contour_point_t> points_left = points.as_array ();
      for (auto &item : get_var_composite_iterator ())
      {
	hb_codepoint_t item_gid = item.get_gid ();

        if (unlikely (current_glyphs->has (item_gid)))
	  continue;

	current_glyphs->add (item_gid);

	unsigned item_num_points = item.get_num_points ();
	hb_array_t<contour_point_t> record_points = points_left.sub_array (0, item_num_points);
	assert (record_points.length == item_num_points);

	auto component_coords = coords;
	/* Copying coords is expensive; so we have put an arbitrary
	 * limit on the max number of coords for now. */
	if (item.is_reset_unspecified_axes () ||
	    coords.length > HB_GLYF_VAR_COMPOSITE_MAX_AXES)
	  component_coords = hb_array<int> ();

	coord_setter_t coord_setter (component_coords);
	item.set_variations (coord_setter, record_points);

	unsigned old_count = all_points.length;

	if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) &&
		      !glyf_accelerator.glyph_for_gid (item_gid)
				       .get_points (font,
						    glyf_accelerator,
						    all_points,
						    points_with_deltas,
						    head_maxp_info,
						    nullptr,
						    shift_points_hori,
						    use_my_metrics,
						    phantom_only,
						    coord_setter.get_coords (),
						    current_glyphs,
						    depth + 1,
						    edge_count)))
	{
	  current_glyphs->del (item_gid);
	  return false;
	}

	auto comp_points = all_points.as_array ().sub_array (old_count);

	/* Apply component transformation */
	if (comp_points) // Empty in case of phantom_only
	  item.transform_points (record_points, comp_points);

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

	all_points.resize (all_points.length - PHANTOM_COUNT);

	if (all_points.length > HB_GLYF_MAX_POINTS)
	{
	  current_glyphs->del (item_gid);
	  return false;
	}

	points_left += item_num_points;

        current_glyphs->del (item_gid);
      }
      all_points.extend (phantoms);
    } break;
#endif
    case EMPTY:
      all_points.extend (phantoms);
      break;
    }

    if (depth == 0 && shift_points_hori) /* Apply at top level */
    {
      /* Undocumented rasterizer behavior:
       * Shift points horizontally by the updated left side bearing
       */
      int v = -phantoms[PHANTOM_LEFT].x;
      if (v)
        for (auto &point : all_points)
	  point.x += v;
    }

    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_type_t get_type () const { return type; }
  const GlyphHeader *get_header () const { return header; }

  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 if (num_contours == -1) type = COMPOSITE;
#ifndef HB_NO_VAR_COMPOSITES
    else if (num_contours == -2) type = VAR_COMPOSITE;
#endif
    else type = EMPTY; // Spec deviation; Spec says COMPOSITE, but not seen in the wild.
  }

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


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


#endif /* OT_GLYF_GLYPH_HH */
