/***************************************************************************
*   Copyright (C) 2005 by Alexander Nemish   *
*   atlanter@gmail.com   *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
*   This program is distributed in the hope that it will be useful,       *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
*   GNU General Public License for more details.                          *
*                                                                         *
*   You should have received a copy of the GNU General Public License     *
*   along with this program; if not, write to the                         *
*   Free Software Foundation, Inc.,                                       *
*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
***************************************************************************/
#ifndef RENDERER_H
#define RENDERER_H

#include <tqstringlist.h>
#include <tqfont.h>
#include <tqstring.h>
#include <tqobject.h>
#include <tqsize.h>
#include <tqtimer.h>
#include <vector>
#include <memory>
class TQStringList;

class TextLine
{
public:
	static const int PARA_NONE = 0;
	static const int PARA_START = 1;
	static const int PARA_END = 2;
	static const int PARA_BOTH = 3;
	
	TextLine(int index, int begin, int end, int paraFlags = PARA_NONE):
		m_paragraphFlags(paraFlags),
		m_begin(begin),
		m_end(end),
		m_index(index)
	{}
	bool isParaStart() const { return m_paragraphFlags & PARA_START; }
	bool isParaEnd() const { return m_paragraphFlags & PARA_END; }
	void setParagraphFlags(int flags) { m_paragraphFlags = flags; }
	const int paragraphFlags() const { return m_paragraphFlags; }
	const int paragraphIndex() const { return m_index; }
	const int begin() const { return m_begin; }
	const int end() const { return m_end; }
	const int size() const { return m_end - m_begin; }
private:
	int m_paragraphFlags;
	int m_begin;
	int m_end;
	int m_index;
};

/**
*   \brief Renders input text into list of word wrapped strings
*	\author Alexandr Nemish <anemish@gmail.com>
*/
class Renderer : public TQObject
{
	TQ_OBJECT
  
public:
	Renderer();
	~Renderer();

	///	\brief Loads and renders list of strings
	void load(const TQStringList & list);
	///	\brief Renders loaded list of strings
	void render();
	/// \brief Clears all rendered data
	void clear();
	/// \brief Draws page
	void drawPage(TQPainter & paint, TQRect rect, int pageNumber);
	//Getters
	/// \brief Returns whether the text is empty
	bool isEmpty() const { return m_text.empty(); };
	/// \brief Returns current font
	TQFont font() const { return m_font; }
	/// \brief Returns current paragraph offset in pixels
	int paraOffset() const { return m_paraOffset; }
	/// \brief Returns the number of pages
	int pageCount() const { return m_pageCount; }
	/// \brief Returns page size in pixels
	TQSize pageSize() const { return m_pageSize; }
	//Setters
	/// \brief Sets current font
	void setFont(const TQFont & font);
	/// \brief Sets current paragraph offset in pixels
	void setParaOffset(int offset);
	/// \brief Sets size of a page
	void setPageSize(const TQSize & size);
	
	bool busy() const { return m_isRendering; }
signals:
	void renderingFinished();
private slots:
	void timeout();
private:
	typedef TQStringList::const_iterator TStringIter;
	typedef std::vector<TQString> TParagraphs;
	typedef TParagraphs::size_type TIndex;
	typedef std::vector<TextLine> TLines;
	//make it non-copyable		
	Renderer(const Renderer &);
	Renderer & operator = (const Renderer &);
	/// \brief Renders input paragraph into list of wrapped lines
	void parseParagraph(TIndex idx);
	/// \brief Returns width of string in pixels
	int width(const TQString & a_string) const;
	void addLine(TextLine line);
	int wordAt(const TQString & str, int len);
	TQString getWord(const TQString & str, int idx);
	/// \brief Draws justified string
	void drawLine(TQPainter& paint, int x, int y, const TLines::size_type idx);
	void cancel();

	TParagraphs m_text;
	TLines m_lines;
	int m_pageCount;
	int m_linesPerPage;
	int m_paraOffset;
	TQFont m_font;
	std::unique_ptr<TQFontMetrics> m_fontMetrics;
	TQSize m_pageSize;
	bool m_isStartAdded;
	TIndex m_curParagraph;
	bool m_isRendering;
	TQTimer m_timer;
};

#endif
