#include "qcodeedit_completer_p.h"

#include "qad_types.h"

#include <QHeaderView>
#include <QKeyEvent>
#include <QScreen>


QCodeEditCompleter::QCodeEditCompleter(QWidget * parent): QTreeWidget(parent) {
	setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
	setFocusPolicy(Qt::NoFocus);
	setColumnCount(2);
	setRootIsDecorated(false);
	setHeaderHidden(true);
#if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
	setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
#endif
	setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
	header()->setDefaultAlignment(Qt::AlignCenter);
	header()->
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
		setSectionResizeMode
#else
		setResizeMode
#endif
		(QHeaderView::ResizeToContents);
	header()->setStretchLastSection(false);
}


QCodeEditCompleter::~QCodeEditCompleter() {}


void QCodeEditCompleter::nextCompletition() {
	int ci = currentIndex().row();
	if (ci >= topLevelItemCount() - 1) return;
	if (topLevelItem(ci + 1)->flags().testFlag(Qt::ItemIsSelectable))
		setCurrentItem(topLevelItem(ci + 1));
	else {
		if (ci >= topLevelItemCount() - 2) return;
		setCurrentItem(topLevelItem(ci + 2));
	}
}


void QCodeEditCompleter::previousCompletition() {
	int ci = currentIndex().row();
	if (ci <= 0) return;
	if (topLevelItem(ci - 1)->flags().testFlag(Qt::ItemIsSelectable))
		setCurrentItem(topLevelItem(ci - 1));
	else {
		if (ci <= 1) return;
		setCurrentItem(topLevelItem(ci - 2));
	}
}

void QCodeEditCompleter::addItems(QFont f, const QCodeEdit::ACClass & cl, const QCodeEdit::ACSection & items) {
	QTreeWidgetItem * gi = new QTreeWidgetItem();
	gi->setText(0, cl.name);
	gi->setTextAlignment(0, Qt::AlignCenter);
	gi->setTextAlignment(1, Qt::AlignCenter);
	gi->setFont(0, f);
	gi->setBackground(0, palette().window());
	gi->setFlags(Qt::ItemIsEnabled);
	addTopLevelItem(gi);
	gi->setFirstColumnSpanned(true);
	foreach(const auto & s, items.second) {
		QTreeWidgetItem * ni = new QTreeWidgetItem();
		ni->setIcon(0, cl.icon);
		ni->setText(0, s.type);
		ni->setText(1, s.name);
		ni->setData(0, Qt::UserRole, s.help_href);
		addTopLevelItem(ni);
	}
}


void QCodeEditCompleter::invoke(QPoint global_pos) {
	setCurrentItem(topLevelItem(1));
	if (isHidden()) move(global_pos);
	if (topLevelItemCount() > 0) {
		const auto screen = qApp->screenAt(global_pos);
		setVisible(true);
		adjust();
		if (global_pos.y() + height() > screen->availableSize().height()) {
			global_pos.setY(global_pos.y() -height() - fontHeight(this));
		}
		move(global_pos);
	} else {
		hide();
	}
}


QString QCodeEditCompleter::currentReturn() const {
	if (!currentItem()) return QString();
	return currentItem()->text(0);
}


QString QCodeEditCompleter::currentValue() const {
	if (!currentItem()) return QString();
	return currentItem()->text(1);
}


void QCodeEditCompleter::keyPressEvent(QKeyEvent * e) {
	switch (e->key()) {
	case Qt::Key_Escape: hide(); break;
	case Qt::Key_Return: emit commit(); break;
	case Qt::Key_F1:
		if (currentItem()) {
			QString href = currentItem()->data(0, Qt::UserRole).toString();
			emit gotoHRef(QCodeEdit::ACEntry().addHelpHRef(href));
		}
		break;
	default: break;
	}
	QTreeWidget::keyPressEvent(e);
}


void QCodeEditCompleter::adjust() {
	int sz = sizeHint().width();
	resize(sz, fontHeight(this) * 16);
}
