/**********************************************************************
 * LeechCraft - modular cross-platform feature rich internet client.
 * Copyright (C) 2006-2014  Georg Rudoy
 *
 * Boost Software License - Version 1.0 - August 17th, 2003
 *
 * Permission is hereby granted, free of charge, to any person or organization
 * obtaining a copy of the software and accompanying documentation covered by
 * this license (the "Software") to use, reproduce, display, distribute,
 * execute, and transmit the Software, and to prepare derivative works of the
 * Software, and to permit third-parties to whom the Software is furnished to
 * do so, all subject to the following:
 *
 * The copyright notices in the Software and this entire statement, including
 * the above license grant, this restriction and the following disclaimer,
 * must be included in all copies of the Software, in whole or in part, and
 * all derivative works of the Software, unless such copies or derivative
 * works are solely in the form of machine-executable object code generated by
 * a source language processor.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 **********************************************************************/

#include "htmlhighlighter.h"
#include <QTextEdit>

namespace LeechCraft
{
namespace Poshuku
{
	HtmlHighlighter::HtmlHighlighter (QTextDocument *doc)
	: QSyntaxHighlighter (doc)
	{
		Fill ();
	}

	HtmlHighlighter::HtmlHighlighter (QTextEdit *edit)
#if QT_VERSION < 0x050000
	: QSyntaxHighlighter (edit)
#else
	: QSyntaxHighlighter (edit->document ())
#endif
	{
		Fill ();
	}

	void HtmlHighlighter::SetFormatFor (Construct c, const QTextCharFormat& f)
	{
		Formats_ [c] = f;
		rehighlight ();
	}

	QTextCharFormat HtmlHighlighter::GetFormatFor (Construct c) const
	{
		return Formats_ [c];
	}

	void HtmlHighlighter::highlightBlock (const QString& text)
	{
		int state = previousBlockState ();
		int len = text.length ();
		int start = 0, pos = 0;

		while (pos < len)
		{
			switch (state)
			{
				case InComment:
					start = pos;
					while (pos < len)
					{
						if (text.mid (pos, 3) == "-->")
						{
							pos += 3;
							state = NormalState;
							break;
						}
						else
							++pos;
					}

					setFormat (start, pos - start,
							Formats_ [Comment]);
					break;
				case InTag:
					{
						QChar quote = QChar::Null;
						start = pos;
						while (pos < len)
						{
							QChar ch = text.at (pos);
							if (quote.isNull ())
							{
								if (ch == '\'' || ch == '"')
									quote = ch;
								else if (ch == '>')
								{
									++pos;
									state = NormalState;
									break;
								}
							}
							else if (ch == quote)
								quote = QChar::Null;

							++pos;
						}

						setFormat (start, pos - start,
								Formats_ [Tag]);
						break;
					}
				default:
					while (pos < len)
					{
						QChar ch = text.at (pos);
						if (ch == '<')
						{
							if (text.mid (pos, 4) == "<!--")
								state = InComment;
							else
								state = InTag;
							break;
						}
						else if (ch == '&')
						{
							start = pos;
							while (pos < len &&
									text.at (pos++) != ';') ;

							setFormat (start, pos - start,
									Formats_ [Entity]);
						}
						else
							++pos;
					}
					break;
			}
		}

		setCurrentBlockState (state);
	}

	void HtmlHighlighter::Fill ()
	{
		QTextCharFormat entityFormat;
		entityFormat.setForeground (QColor (0, 128, 0));
		entityFormat.setFontWeight (QFont::Bold);
		SetFormatFor (Entity, entityFormat);

		QTextCharFormat tagFormat;
		tagFormat.setForeground (QColor (192, 16, 112));
		tagFormat.setFontWeight (QFont::Bold);
		SetFormatFor (Tag, tagFormat);

		QTextCharFormat commentFormat;
		commentFormat.setForeground (QColor (128, 10, 74));
		commentFormat.setFontItalic (true);
		SetFormatFor (Comment, commentFormat);
	}
}
}
