#include "edockwidget.h"

#include "qad_types.h"

#include <QEvent>
#include <QStyle>
#include <QTimer>


EDockWidget::EDockWidget(const QString & title, QWidget * parent, Qt::WindowFlags flags): QDockWidget(title, parent, flags) {
	init();
}


EDockWidget::EDockWidget(QWidget * parent, Qt::WindowFlags flags): QDockWidget(parent, flags) {
	init();
}


EDockWidget::~EDockWidget() {
	btn_hide->deleteLater();
	btn_dock->deleteLater();
	btn_maximize->deleteLater();
	lbl_title->deleteLater();
	lbl_icon->deleteLater();
	header->deleteLater();
	empty_header->deleteLater();
}


void EDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features) {
	btn_dock->setVisible(features.testFlag(DockWidgetFloatable));
	btn_hide->setVisible(features.testFlag(DockWidgetClosable));
	QDockWidget::setFeatures(features);
}


void EDockWidget::setWindowTitle(const QString & title) {
	lbl_title->setText(title);
	QDockWidget::setWindowTitle(title);
}


void EDockWidget::setWindowIcon(const QIcon & icon) {
	// #ifndef Q_OS_MACOS
	lbl_icon->setPixmap(icon.pixmap(QSize(256, 256)));
	QDockWidget::setWindowIcon(icon);
	if (!icon.isNull()) {
		lbl_icon->setScaledContents(true);
		lbl_icon->setFixedSize(preferredIconSize(1.5, this));
	}
	// #endif
}


void EDockWidget::setEmptyHeader() {
	if (titleBarWidget() != empty_header) setTitleBarWidget(empty_header);
}


void EDockWidget::setStandardHeader() {
	if (titleBarWidget() != header) setTitleBarWidget(header);
}


bool EDockWidget::event(QEvent * e) {
	if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish) {
		updateStyle();
	}
	return QDockWidget::event(e);
}


void EDockWidget::changeEvent(QEvent * e) {
	if (e->type() == QEvent::WindowStateChange || e->type() == QEvent::LanguageChange) {
		updateStyle();
	}
	QDockWidget::changeEvent(e);
}


void EDockWidget::init() {
	header = new QFrame();
	header->setFrameShape(QFrame::StyledPanel);
	empty_header = new QWidget();
	empty_header->setLayout(new QBoxLayout(QBoxLayout::BottomToTop));
	QBoxLayout * lay =
		new QBoxLayout(features().testFlag(QDockWidget::DockWidgetVerticalTitleBar) ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight);
	lay->setContentsMargins(2, 2, 2, 2);
	lay->setSpacing(2);
	lbl_icon = new QLabel();
	// #ifndef Q_OS_MACOS
	QIcon wi = windowIcon();
	if (!wi.isNull()) {
		lbl_icon->setPixmap(wi.pixmap(QSize(256, 256)));
		/*#if QT_VERSION >= 0x500000
		        if (lbl_icon->pixmap())
		            const_cast<QPixmap*>(lbl_icon->pixmap())->setDevicePixelRatio(1.);
		#endif*/
		// qDebug() << windowTitle() << wi.pixmap(QSize(256,256)).size();
		lbl_icon->setScaledContents(true);
	}
	lbl_icon->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
	// #endif
	lbl_title = new QLabel(windowTitle());
	lbl_title->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
	auto createButton = [this](const char * slot) {
		auto * ret = new QToolButton();
		ret->setAutoRaise(true);
		ret->setFocusPolicy(Qt::NoFocus);
		ret->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
		// ret->setIconSize(QSize(16, 16));
		connect(ret, SIGNAL(clicked(bool)), this, slot);
		return ret;
	};
	btn_dock     = createButton(SLOT(dockClicked()));
	btn_maximize = createButton(SLOT(maximize()));
	btn_hide     = createButton(SLOT(hide()));
	lay->addWidget(lbl_icon);
	lay->addWidget(lbl_title);
	lay->addWidget(btn_dock);
	lay->addWidget(btn_maximize);
	lay->addWidget(btn_hide);
	header->setLayout(lay);
	updateStyle();
	setTitleBarWidget(header);
	connect(this, &QDockWidget::topLevelChanged, this, &EDockWidget::updateStyle);
}


void EDockWidget::updateStyle() {
	int eh_m = style()->pixelMetric(QStyle::PM_DockWidgetTitleMargin);
	empty_header->layout()->setContentsMargins(eh_m, eh_m, 0, 0);
	QSize icon_size = preferredIconSize(0.75, this);
	int bm          = 2 * style()->pixelMetric(QStyle::PM_DockWidgetTitleBarButtonMargin, 0, this);
	QSize btn_size  = icon_size;
	btn_size += QSize(bm, bm);
	lbl_icon->setFixedSize(preferredIconSize(1.5, this));
	auto restyleButton = [this, icon_size, btn_size](QToolButton * btn, QStyle::StandardPixmap pm) {
		btn->setIcon(style()->standardIcon(pm));
		btn->setIconSize(icon_size);
		btn->setFixedSize(btn_size);
	};
	restyleButton(btn_dock, isFloating() ? QStyle::SP_TitleBarUnshadeButton : QStyle::SP_TitleBarShadeButton);
	restyleButton(btn_maximize, isMaximized() ? QStyle::SP_TitleBarNormalButton : QStyle::SP_TitleBarMaxButton);
	restyleButton(btn_hide, QStyle::SP_TitleBarCloseButton);
	btn_dock->setToolTip(isFloating() ? tr("Dock") : tr("Undock"));
	btn_maximize->setToolTip(isMaximized() ? tr("Show normal") : tr("Maximize"));
	btn_hide->setToolTip(tr("Hide"));
}


void EDockWidget::dockClicked() {
	if (isFloating() && isMaximized()) {
		showNormal();
		QTimer::singleShot(0, [this]() { setFloating(!isFloating()); });
	} else
		setFloating(!isFloating());
}


void EDockWidget::maximize() {
	if (!isFloating()) {
		setFloating(true);
		QTimer::singleShot(0, [this]() { showMaximized(); });
	} else {
		if (isMaximized())
			showNormal();
		else
			showMaximized();
	}
}
