#ifndef _MDC_TEXT_H_
#define _MDC_TEXT_H_

#include "mdc_figure.h"

/**
 * @file mdc_text.h
 *
 * Declaration of everything pertaining to the text output on the canvas. The file defines alignment and layout of 
 * text as well as the actual text figure.
 */

BEGIN_MDC_DECLS

/**
 * Determines how text is to be aligned within the figure.
 */
enum TextAlignment {
    AlignLeft,
    AlignCenter,
    AlignRight
};
  
/**
 * Manages the layout of text including rendering to a Cairo context.
 */
class TextLayout 
{
  struct Paragraph {
    size_t text_offset;
    size_t text_length;
  };

  struct Line {
    size_t text_offset;
    size_t text_length;

    Point offset;
    Size size;
  };

  // A list of paragraphs which are rendered individually.
  std::vector<Paragraph> _paragraphs;

  // The text to render.
  char *_text;

  // Description for each line.
  std::vector<Line> _lines;

  // The font to use for rendering.
  FontSpec _font;

  Size _fixed_size;
  bool _needs_relayout;

  void break_paragraphs();
  void layout_paragraph(CairoCtx *cr, Paragraph &para);

public:
  TextLayout();
  ~TextLayout();

  void relayout(CairoCtx *cr);
  void render(CairoCtx *cr, const Point &pos, const Size &size, TextAlignment align);

  void set_text(const std::string &text);

  void set_font(const FontSpec &font);

  void set_width(double width);
  void set_height(double height);

  Size get_size();
};

/**
 * Implements the actual canvas figure used to render text. This class manages the layouter as well as needed
 * resources. It is also the interface through which other parts control text rendering.
 */
class MYSQLCANVAS_PUBLIC_FUNC TextFigure : public Figure {
public:
  TextFigure(Layer *layer);
  virtual ~TextFigure();
  
  virtual Size calc_min_size();
  
  void set_text(const std::string &text);
  const std::string &get_text() const { return _text; }

  void set_fill_background(bool flag);

  void set_font(const FontSpec &font);
  const FontSpec &get_font() { return _font; }

  void set_text_alignment(TextAlignment align);

  void set_multi_line(bool flag);
  void set_allow_shrinking(bool flag);

  virtual void draw_contents(CairoCtx *cr);

  void auto_size();

protected:
  FontSpec _font;
  std::string _text;
  std::string _shrinked_text;

  TextAlignment _align;

  TextLayout *_text_layout;
  bool _multi_line;
  bool _allow_shrinking;
  bool _fill_background;

  Size get_text_size();
  
  void reset_shrinked_text();

  void draw_contents(CairoCtx *cr, const Rect &bounds);
};


END_MDC_DECLS


#endif /* _MDC_TEXT_H_ */
