/*
 * Copyright © 2011,2012  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
 */

#ifndef HB_SHAPE_CONSUMER_HH
#define HB_SHAPE_CONSUMER_HH

#include "font-options.hh"
#include "shape-options.hh"
#include "text-options.hh"


template <typename output_t>
struct shape_consumer_t : shape_options_t
{
  void add_options (option_parser_t *parser)
  {
    shape_options_t::add_options (parser);
    output.add_options (parser);
  }

  void init (const font_options_t *font_opts)
  {
    font = hb_font_reference (font_opts->font);
    failed = false;
    buffer = hb_buffer_create ();

    output.init (buffer, font_opts);
  }
  bool consume_line (shape_text_options_t &text_opts)
  {
    unsigned int text_len;
    const char *text;
    if (!(text = text_opts.get_line (&text_len)))
      return false;

    output.new_line ();

    for (unsigned int n = num_iterations; n; n--)
    {
      const char *error = nullptr;

      populate_buffer (buffer, text, text_len, text_opts.text_before, text_opts.text_after);
      if (n == 1)
	output.consume_text (buffer, text, text_len, utf8_clusters);
      if (!shape (font, buffer, &error))
      {
	failed = true;
	output.error (error);
	if (hb_buffer_get_content_type (buffer) == HB_BUFFER_CONTENT_TYPE_GLYPHS)
	  break;
	else
	  return true;
      }
    }

    output.consume_glyphs (buffer, text, text_len, utf8_clusters);
    return true;
  }
  void finish (const font_options_t *font_opts)
  {
    output.finish (buffer, font_opts);
    hb_font_destroy (font);
    font = nullptr;
    hb_buffer_destroy (buffer);
    buffer = nullptr;
  }

  public:
  bool failed = false;

  protected:
  output_t output;

  hb_font_t *font = nullptr;
  hb_buffer_t *buffer = nullptr;
};


#endif
