#include "ribbon.h"

#include "qad_types.h"

#include <QScrollBar>


Ribbon::Ribbon(QMainWindow * parent_): QToolBar() {
	setObjectName("ribbon");
	setProperty("ribbon", true);
	setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
	parent = parent_;
	if (parent_) parent_->installEventFilter(this);
	init();
}


Ribbon::~Ribbon() {}


bool Ribbon::eventFilter(QObject * o, QEvent * e) {
	// qDebug() << e;
	if (o == parent) {
		if (e->type() == QEvent::Resize || e->type() == QEvent::WindowActivate) _resize();
		if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish) _setIconsSize();
		return QToolBar::eventFilter(o, e);
	}
	if (e->type() == QEvent::ActionChanged) {
		QToolButton * b = qobject_cast<QToolButton *>((QObject *)o->property("ribbonButton").toLongLong());
		if (b != 0) b->setEnabled(qobject_cast<QAction *>(o)->isEnabled());
	}
	return QToolBar::eventFilter(o, e);
}


void Ribbon::timerEvent(QTimerEvent * e) {
	if (hovers.value(e->timerId(), -1) == hovered) tab->setCurrentIndex(hovered);
	hovers.remove(e->timerId());
	killTimer(e->timerId());
}


void Ribbon::changeEvent(QEvent * e) {
	QToolBar::changeEvent(e);
	switch (e->type()) {
	case QEvent::LanguageChange: retranslate(); break;
	default: break;
	}
}


void Ribbon::_resize() {
	return; // WARNING
	for (int i = 0; i < tab->count(); ++i) {
		int h = ((QScrollArea *)(tab->widget(i)))->sizeHint().height();
		if (((QScrollArea *)(tab->widget(i)))->horizontalScrollBar()->isVisible())
			h += ((QScrollArea *)(tab->widget(i)))->horizontalScrollBar()->height();
		((QScrollArea *)(tab->widget(i)))->setMinimumHeight(h);
	}
}


void Ribbon::_setIconsSize() {
	// qDebug() << "resize" << preferredIconSize() << QApplication::font();
	setTabIconSize(preferredIconSize(1.6, this));
	setIconSize(preferredIconSize(2.4, this));
}


void Ribbon::_setButtonText(QToolButton * b, QAction * a) {
	b->setText(a->text());
	QString sc;
	for (const auto & s: a->shortcuts()) {
		sc += "\n" + s.toString(QKeySequence::NativeText);
	}
	b->setToolTip(a->text() + sc);
}


void Ribbon::tabHovered(int tab) {
	if (!delay_e) return;
	hovers.clear();
	hovered = tab;
	hovers.insert(startTimer(delay), tab);
}


void Ribbon::setVisible(bool yes) {
	QToolBar::setVisible(yes);
	if (parent == 0) return;
	if (parent->menuBar() == 0) return;
	parent->menuBar()->setVisible(!yes);
}


void Ribbon::init() {
	if (parent == 0) return;
	if (parent->menuBar() == 0) return;
	QList<QAction *> lm = parent->menuBar()->actions(), la;
	QString prev_tab;
	if (tab) {
		if (tab->currentIndex() >= 0) prev_tab = tab->tabText(tab->currentIndex());
		tab->deleteLater();
	}
	clear();
	if (scroll_area) delete scroll_area;
	buttons.clear();
	tab = new ETabWidget();
	tab->setObjectName("ribbon_tab_widget");
	connect(tab, SIGNAL(tabHovered(int)), this, SLOT(tabHovered(int)));
	connect(tab, SIGNAL(currentChanged(int)), this, SIGNAL(currentTabChanged(int)));
	tab->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
	QFrame * g;
	QBoxLayout *l, *tl;
	QToolButton * b;
	// tab->setIconSize(QSize(32, 32));
	for (QAction * i: lm) {
		if (!i->menu()) continue;
		// if (!i->menu()->isVisible()) continue;
		la        = i->menu()->actions();
		QIcon tic = i->icon();
		if (!tic.isNull())
			i->setProperty("__icon", QVariant::fromValue<QIcon>(tic));
		else
			tic = i->property("__icon").value<QIcon>();
		// #ifdef Q_OS_MACOS
		//		tic = QIcon();
		// #endif
		tab->addTab(new QWidget(), tic, i->text());
		// qDebug() << this << i->icon() << i->text();
		// continue;
		/*QScrollArea * sa = new QScrollArea();
		sa->setWidget(new QWidget());
		sa->setWidgetResizable(true);
		sa->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
		sa->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
		sa->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
		sa->setFrameShape(QFrame::NoFrame);
		tab->addTab(sa, i->icon(), i->text());*/
		tab->widget(tab->count() - 1)->setProperty("ribbonAction", qlonglong((void *)i));
		i->setIcon(QIcon());
		tl = new QBoxLayout(QBoxLayout::LeftToRight);
		tl->setSpacing(2);
#ifndef Q_OS_MACOS
		tl->setContentsMargins(2, 2, 2, 2);
#else
		tl->setContentsMargins(2, 0, 2, 2);
#endif
		g = new QFrame();
		g->setFrameShape(QFrame::StyledPanel);
		l = new QBoxLayout(QBoxLayout::LeftToRight);
		g->setLayout(l);
		l->setSpacing(2);
		l->setContentsMargins(2, 2, 2, 2);
		for (QAction * j: la) {
			if (j->isSeparator()) {
				if (l->isEmpty()) continue;
				tl->addWidget(g);
				g = new QFrame();
				g->setFrameShape(QFrame::StyledPanel);
				l = new QBoxLayout(QBoxLayout::LeftToRight);
				l->setSpacing(2);
				l->setContentsMargins(2, 2, 2, 2);
				g->setLayout(l);
				continue;
			}
			if (qobject_cast<QWidgetAction *>(j)) {
				QWidget * _w = qobject_cast<QWidgetAction *>(j)->defaultWidget();
				l->addWidget(_w);
				_w->show();
				continue;
			}
			b = new QToolButton();
			// b->setVisible(j->isVisible());
			b->setEnabled(j->isEnabled());
			b->setProperty("ribbonAction", qlonglong((void *)j));
			j->setProperty("ribbonButton", qlonglong((void *)b));
			j->installEventFilter(this);
			if (j->menu() != 0) {
				b->setPopupMode(QToolButton::InstantPopup);
				b->setMenu(j->menu());
			} else {
				b->setCheckable(j->isCheckable());
				if (b->isCheckable()) {
					b->setChecked(j->isChecked());
					connect(b, SIGNAL(toggled(bool)), j, SLOT(setChecked(bool)));
					connect(b, SIGNAL(clicked(bool)), j, SIGNAL(triggered(bool)));
					connect(j, SIGNAL(toggled(bool)), b, SLOT(setChecked(bool)));
				} else
					connect(b, SIGNAL(clicked()), j, SLOT(trigger()));
			}
			// b->setIconSize(QSize(16, 16));
			b->setIcon(j->icon());
			_setButtonText(b, j);
			// b->addAction(j);
			// b->setShortcut(j->shortcut());
			b->setAutoRaise(true);
			b->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
			b->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
			buttons << b;
			l->addWidget(b);
		}
		tl->addWidget(g);
		tl->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed));
		// sa->widget()->setLayout(tl);
		tab->widget(tab->count() - 1)->setLayout(tl);
		if (i->text() == prev_tab) tab->setCurrentIndex(tab->count() - 1);
	}
	setFloatable(false);
	setMovable(false);
	/*scroll_area = new QScrollArea();
	scroll_area->setFrameShape(QFrame::NoFrame);
	scroll_area->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
	scroll_area->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
	scroll_area->setWidget(tab);*/
	_resize();
	// addWidget(scroll_area);
	addWidget(tab);
	parent->addToolBar(Qt::TopToolBarArea, this);
	parent->menuBar()->hide();
	tab->setAutoFillBackground(false);
	_setIconsSize();
}


void Ribbon::retranslate() {
	QAction * a;
	for (QToolButton * i: buttons) {
		a = (QAction *)(i->property("ribbonAction").toLongLong());
		if (a == 0) continue;
		_setButtonText(i, a);
		// i->setShortcut(a->shortcut());
	}
	for (int i = 0; i < tab->count(); ++i) {
		a = (QAction *)(tab->widget(i)->property("ribbonAction").toLongLong());
		if (a == 0) continue;
		tab->setTabText(i, a->text());
	}
	_resize();
}


void Ribbon::setIconSize(const QSize & size) {
	for (QToolButton * i: buttons)
		i->setIconSize(size);
	_resize();
}


void Ribbon::setTabIconSize(const QSize & size) {
#ifndef Q_OS_MACOS
	tab->setIconSize(size);
#endif
	_resize();
}


void Ribbon::setButtonStyle(const Qt::ToolButtonStyle & style) {
	foreach(QToolButton * i, buttons)
		i->setToolButtonStyle(style);
}


void Ribbon::setCurrentTab(int tab_) {
	if (tab_ < 0 || tab_ >= tab->count()) return;
	tab->setCurrentIndex(tab_);
}
