#include "style.h"
#include "conf.h"

#include <KColorButton>
#include <KLocalizedString>


namespace Dict {

StyleItem::StyleItem(const QString &name)
	: QTreeWidgetItem(QStringList(name), QTreeWidgetItem::UserType), type(name)
{}

void StyleItem::setColorWidgets()
{
	if (!treeWidget()) return;

	KColorButton *text = new KColorButton(treeWidget());
	text->setFixedWidth(70);
	treeWidget()->setItemWidget(this, Text, text);
	connect(text, SIGNAL(changed (const QColor &)),
		SLOT(setTextColor(const QColor &)));

	KColorButton *back = new KColorButton(treeWidget());
	back->setFixedWidth(70);
	treeWidget()->setItemWidget(this, Back, back);
	connect(back, SIGNAL(changed (const QColor &)),
		SLOT(setBackColor(const QColor &)));

	if (type == "Link" || type == "Description") {
		back->setEnabled(false);
		back->setToolTip("Currently disabled, as it doesn't render correctly.");
	}
}

void StyleItem::setTextColor(const QColor &color)
{
	setForeground(Context, color);
}

void StyleItem::setBackColor(const QColor &color)
{
	setBackground(Context, color);
}

int StyleItem::style() const
{
	int style = NormalFont;
	if (bold()) style |= BoldFont;
	if (italic()) style |= ItalicFont;
	if (underline()) style |= UnderlineFont;
	return style;
}

bool StyleItem::bold() const
{
	return (font(Context).bold());
}

bool StyleItem::italic() const
{
	return (font(Context).italic());
}

bool StyleItem::underline() const
{
	return (font(Context).underline());
}

QString StyleItem::text() const
{
	return foreground(Context).color().name();
}

QString StyleItem::back() const
{
	return background(Context).color().name();
}

void StyleItem::setCheckBoxes()
{
	setCheckState(Bold, (bold()) ? Qt::Checked : Qt::Unchecked);
	setCheckState(Italic, (italic()) ? Qt::Checked : Qt::Unchecked);
	setCheckState(Underline, (underline()) ? Qt::Checked : Qt::Unchecked);
}

void StyleItem::set(int style, const QString &text, const QString &back)
{
	setFlags(Qt::ItemIsEnabled);

	QFont newfont = font(Context);
	newfont.setBold(style & BoldFont);
	newfont.setItalic(style & ItalicFont);
	newfont.setUnderline(style & UnderlineFont);
	setFont(Context, newfont);
	setCheckBoxes();

	setTextColor(QColor(text));
	setBackColor(QColor(back));
	if (treeWidget()) {
		((KColorButton *)treeWidget()->itemWidget(this, Text))->setColor(QColor(text));
		((KColorButton *)treeWidget()->itemWidget(this, Back))->setColor(QColor(back));
	}
}

void StyleItem::setFonts(int column)
{
	QFont newfont = font(Context);
	switch (column) {
	case Bold:
		newfont.setBold(!newfont.bold());
		break;
	case Italic:
		newfont.setItalic(!newfont.italic());
		break;
	case Underline:
		newfont.setUnderline(!newfont.underline());
		break;
	}
	setFont(Context, newfont);
	setCheckBoxes();
}


StyleConf::StyleConf(QWidget *parent)
	: QTreeWidget(parent)
{
	setRootIsDecorated(false);

	QStringList headers;
	headers << i18n("Role") << "" << "" << ""
		<< i18n("Text") << i18n("Background");
	setHeaderLabels(headers);

	headerItem()->setIcon(StyleItem::Bold, QIcon::fromTheme("format-text-bold"));
	headerItem()->setIcon(StyleItem::Italic, QIcon::fromTheme("format-text-italic"));
	headerItem()->setIcon(StyleItem::Underline, QIcon::fromTheme("format-text-underline"));

	for (int i = StyleItem::Bold; i <= StyleItem::Underline; ++i)
		resizeColumnToContents(i);

	connect(this, SIGNAL(itemClicked(QTreeWidgetItem *, int)),
		SLOT(setFonts(QTreeWidgetItem *, int)));
}

void StyleConf::setFonts(QTreeWidgetItem *item, int column)
{
	((StyleItem *)item)->setFonts(column);
}

void StyleConf::setStyle(Style *style)
{
	if (!topLevelItemCount())
		foreach (StyleItem *item, style->itemList()) {
			addTopLevelItem(item);
			item->setColorWidgets();
		}
	resizeColumnToContents(StyleItem::Text);
	resizeColumnToContents(StyleItem::Context);
}


Style::Style()
{
	QStringList type;
	type << i18n("Title") << i18n("Headword") << i18n("Abbreviation")
		<< i18n("Pronunciation") << i18n("Description") << i18n("Link");
	foreach (QString style, type)
		stylelist << new StyleItem(style);
}

Style::~Style()
{
	foreach (StyleItem *item, stylelist)
		if (!item->treeWidget()) delete item;
}

void Style::setDefaults()
{
	QPalette palette;
	QString text = palette.color(QPalette::Text).name();
	QString back = palette.color(QPalette::Base).name();

	stylelist[Title]->set(StyleItem::NormalFont, back, "#6094CF");
	stylelist[Headword]->set(StyleItem::NormalFont, "#BF0000", back);
	stylelist[Abbreviation]->set(StyleItem::NormalFont, "#00892B", back);
	stylelist[Pronunciation]->set(StyleItem::NormalFont, "#555555", back);
	stylelist[Description]->set(StyleItem::NormalFont, text, back);
	stylelist[Link]->set(StyleItem::NormalFont, palette.color(QPalette::Link).name(), back);
}

void Style::read()
{
	ConfGroup conf("Style");

	setDefaults();
	foreach (StyleItem *item, stylelist) {
		QStringList style;
		style = conf.readEntry(item->context(), style);
		if (style.size() == 3)
			item->set(style[0].toInt(), style[1], style[2]);
	}
	stylefont = conf.readEntry("Font", QFont("Sans Serif"));
}

void Style::write()
{
	ConfGroup conf("Style");

	foreach (StyleItem *item, stylelist) {
		QStringList style;
		style << QString::number(item->style())
			<< item->text() << item->back();
		conf.writeEntry(item->context(), style);
	}
	conf.writeEntry("Font", stylefont);
}

QString resource(const QString &resfile);

QString Style::stylesheet() const
{
	QPalette palette;
	QString text = palette.color(QPalette::Text).name();
	QString back = palette.color(QPalette::Base).name();

	QStringList style;
	foreach (StyleItem *item, stylelist) {
		QString itemstyle;
		if (item->bold()) itemstyle += "font-weight: bold; ";
		if (item->italic()) itemstyle += "font-style: italic; ";
		itemstyle += QString("text-decoration: %1; ")
			.arg((item->underline() ? "underline" : "none"));
		if (item->text() != text)
			itemstyle += QString("color: %1; ").arg(item->text());
		if (item->back() != back)
			itemstyle += QString("background: %1; ").arg(item->back());
		style << itemstyle;
	}
	return resource("dikt.css")
		.arg(style[Title], style[Headword], style[Abbreviation],
		style[Pronunciation], style[Description], style[Link]);
}

QTextCharFormat Style::format(Context context) const
{
	StyleItem *item = stylelist[context];
	QTextCharFormat format;
	if (item->bold()) format.setFontWeight(QFont::Bold);
	format.setForeground(item->foreground(StyleItem::Context));
	return format;
}

}
