#ifndef OT_GLYF_PATH_BUILDER_HH
#define OT_GLYF_PATH_BUILDER_HH


#include "../../hb.hh"


namespace OT {
namespace glyf_impl {


struct path_builder_t
{
  hb_font_t *font;
  hb_draw_session_t *draw_session;

  struct optional_point_t
  {
    optional_point_t () {}
    optional_point_t (float x_, float y_) : has_data (true), x (x_), y (y_) {}
    operator bool () const { return has_data; }

    bool has_data = false;
    float x;
    float y;

    optional_point_t mid (optional_point_t p)
    { return optional_point_t ((x + p.x) * 0.5f, (y + p.y) * 0.5f); }
  } first_oncurve, first_offcurve, first_offcurve2, last_offcurve, last_offcurve2;

  path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_) :
    font (font_), draw_session (&draw_session_) {}

  /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
     See also:
     * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM01/Chap1.html
     * https://stackoverflow.com/a/20772557
     *
     * Cubic support added. */
  HB_ALWAYS_INLINE
  void consume_point (const contour_point_t &point)
  {
    bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE;
#ifdef HB_NO_CUBIC_GLYF
    bool is_cubic = false;
#else
    bool is_cubic = !is_on_curve && (point.flag & glyf_impl::SimpleGlyph::FLAG_CUBIC);
#endif
    optional_point_t p (font->em_fscalef_x (point.x), font->em_fscalef_y (point.y));
    if (unlikely (!first_oncurve))
    {
      if (is_on_curve)
      {
	first_oncurve = p;
	draw_session->move_to (p.x, p.y);
      }
      else
      {
	if (is_cubic && !first_offcurve2)
	{
	  first_offcurve2 = first_offcurve;
	  first_offcurve = p;
	}
	else if (first_offcurve)
	{
	  optional_point_t mid = first_offcurve.mid (p);
	  first_oncurve = mid;
	  last_offcurve = p;
	  draw_session->move_to (mid.x, mid.y);
	}
	else
	  first_offcurve = p;
      }
    }
    else
    {
      if (last_offcurve)
      {
	if (is_on_curve)
	{
	  if (last_offcurve2)
	  {
	    draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
				    last_offcurve.x, last_offcurve.y,
				    p.x, p.y);
	    last_offcurve2 = optional_point_t ();
	  }
	  else
	    draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
				       p.x, p.y);
	  last_offcurve = optional_point_t ();
	}
	else
	{
	  if (is_cubic && !last_offcurve2)
	  {
	    last_offcurve2 = last_offcurve;
	    last_offcurve = p;
	  }
	  else
	  {
	    optional_point_t mid = last_offcurve.mid (p);

	    if (is_cubic)
	    {
	      draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
				      last_offcurve.x, last_offcurve.y,
				      mid.x, mid.y);
	      last_offcurve2 = optional_point_t ();
	    }
	    else
	      draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
					 mid.x, mid.y);
	    last_offcurve = p;
	  }
	}
      }
      else
      {
	if (is_on_curve)
	  draw_session->line_to (p.x, p.y);
	else
	  last_offcurve = p;
      }
    }

    if (unlikely (point.is_end_point))
    {
      if (first_offcurve && last_offcurve)
      {
	optional_point_t mid = last_offcurve.mid (first_offcurve2 ?
						  first_offcurve2 :
						  first_offcurve);
	if (last_offcurve2)
	  draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
				  last_offcurve.x, last_offcurve.y,
				  mid.x, mid.y);
	else
	  draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
				     mid.x, mid.y);
	last_offcurve = optional_point_t ();
      }
      /* now check the rest */

      if (first_offcurve && first_oncurve)
      {
        if (first_offcurve2)
	  draw_session->cubic_to (first_offcurve2.x, first_offcurve2.y,
				  first_offcurve.x, first_offcurve.y,
				  first_oncurve.x, first_oncurve.y);
	else
	  draw_session->quadratic_to (first_offcurve.x, first_offcurve.y,
				     first_oncurve.x, first_oncurve.y);
      }
      else if (last_offcurve && first_oncurve)
      {
	if (last_offcurve2)
	  draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
				  last_offcurve.x, last_offcurve.y,
				  first_oncurve.x, first_oncurve.y);
	else
	  draw_session->quadratic_to (last_offcurve.x, last_offcurve.y,
				     first_oncurve.x, first_oncurve.y);
      }
      else if (first_oncurve)
	draw_session->line_to (first_oncurve.x, first_oncurve.y);
      else if (first_offcurve)
      {
	float x = first_offcurve.x, y = first_offcurve.y;
	draw_session->move_to (x, y);
	draw_session->quadratic_to (x, y, x, y);
      }

      /* Getting ready for the next contour */
      first_oncurve = first_offcurve = last_offcurve = last_offcurve2 = optional_point_t ();
      draw_session->close_path ();
    }
  }
  void points_end () {}

  bool is_consuming_contour_points () { return true; }
  contour_point_t *get_phantoms_sink () { return nullptr; }
};


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


#endif /* OT_GLYF_PATH_BUILDER_HH */
