#include "pultwindow_android.h"
#include <QApplication>
#include <QBoxLayout>
#include <QDebug>
#include <QPainter>
#include <QPushButton>
#include <QMenu>
#include <QPropertyAnimation>
#include <QStyleFactory>
#include <QScreen>
#include <QTimer>
#include <QMouseEvent>
#include <qad_types.h>
#include <piqt.h>
#include "SH_base.h"

const double widthPart = 0.667;


PultWindowAndroid::PultWindowAndroid(QWidget * parent): PultWindowBase(parent) {
	side_val = 0.f;
	moving = false;
	shadow = new QWidget(this);
	handle = new QWidget(this);
	side = new QWidget(this);
	side->setLayout(new QBoxLayout(QBoxLayout::TopToBottom));
	side->setAutoFillBackground(true);
	shadow->setAutoFillBackground(true);
	side->hide();
	handle->show();
	shadow->hide();
	handle->installEventFilter(this);
	shadow->installEventFilter(this);
	anim.setTargetObject(this);
	anim.setPropertyName("_sideVal");
	anim.setDuration(500);
	anim.setEasingCurve(QEasingCurve::OutCubic);
	QList<QAction * > al = pult_menu->actions();
	for (QAction * a: al) {
		if (a->isSeparator()) {
			side->layout()->addItem(new QSpacerItem(1, fontHeight(this) * 2, QSizePolicy::Preferred, QSizePolicy::Preferred));
			continue;
		}
		QPushButton * b = new QPushButton();
		b->setIconSize(preferredIconSize(iconSizeMul, this));
		b->setIcon(a->icon());
		b->setText(a->text());
		b->setProperty("_action", qulonglong(a));
		connect(b, SIGNAL(clicked(bool)), a, SLOT(trigger()));
		side->layout()->addWidget(b);
		buttons_list << b;
	}
	side->layout()->addItem(new QSpacerItem(1, 1, QSizePolicy::Preferred, QSizePolicy::Expanding));
	QLabel * lbl = new QLabel();
	lbl->setText(tr("SHS Pult  %1").arg(SHS_VERSION_NAME));
	lbl->setAlignment(Qt::AlignCenter);
	side->layout()->addWidget(lbl);
	connect(this, SIGNAL(hideMenuRequest()), this, SLOT(animSideHide()));
}


PultWindowAndroid::~PultWindowAndroid() {
	delete handle;
	delete side;
	delete shadow;
}


bool PultWindowAndroid::eventFilter(QObject * o, QEvent * e) {
	if (o == shadow) {
		if (e->type() == QEvent::MouseButtonPress)
			animSideHide();
	}
	if (o == handle) {
		switch (e->type()) {
		case QEvent::MouseButtonPress:
			pp = ((QMouseEvent*)e)->globalPos();
			for (auto * b: buttons_list) {
				QAction * a = (QAction*)(b->property("_action").toULongLong());
				b->setVisible(a->isVisible());
			}
			break;
		case QEvent::MouseButtonRelease: {
			QPoint cp = ((QMouseEvent*)e)->globalPos();
			if (moving) {
				if (_sideVal() <= 0.5) animSideHide();
				else animSideShow();
			} else {
				if ((cp - pp).manhattanLength() <= QApplication::startDragDistance()) {
					if (_sideVal() > 0.5) animSideHide();
					else animSideShow();
				}
			}
			moving = false;
			} break;
		case QEvent::MouseMove: {
			QPoint cp = ((QMouseEvent*)e)->globalPos();
			if (moving) {
				float dv = float(cp.x() - pp.x()) / width() / widthPart;
				_setSideVal(_sideVal() + dv);
				pp = cp;
			} else {
				if ((cp - pp).manhattanLength() > QApplication::startDragDistance()) {
					moving = true;
					anim.stop();
				}
			}
			} break;
		case QEvent::Paint: {
			QPainter p(handle);
			p.setOpacity(0.5);
			p.setBrush(handle->palette().color(QPalette::Window));
			p.setPen(QPen(Qt::black, lineThickness(this)));
			p.drawRect(handle->rect());
			p.setPen(QPen(Qt::black, handle->width() / 4., Qt::SolidLine, Qt::RoundCap));
			p.setRenderHint(QPainter::Antialiasing);
			for (int i = 0; i < 3; ++i)
				p.drawPoint(handle->width() / 2., handle->height() / 4. * (i + 1));
			} break;
		default: break;
		}
	}
	return PultWindowBase::eventFilter(o, e);
}


void PultWindowAndroid::resizeEvent(QResizeEvent * e) {
	PultWindowBase::resizeEvent(e);
	int hs = fontHeight() * 2.5;
	shadow->resize(width(), height());
	side->resize(width() * widthPart, height());
	handle->move(handle->x(), hs / 2);
	handle->resize(hs / 1.33, hs);
	_setSideVal(_sideVal());
}


bool PultWindowAndroid::backTriggered() {
	if (shadow->isVisible()) {
		animSideHide();
		return true;
	}
	if (main_stacked) {
		if (main_stacked->swipeMoveToFirstPage() && main_stacked->currentIndex() != 0) {
			main_stacked->gotoPage(0);
			return true;
		}
	}
	return false;
}


void PultWindowAndroid::setForm(QWidget * w) {
	PultWindowBase::setForm(w);
	QTimer::singleShot(10, [this](){
		resize(QApplication::primaryScreen()->availableGeometry().size());
	});
}


void PultWindowAndroid::unsetForm() {
	PultWindowBase::unsetForm();
}


void PultWindowAndroid::animSide(float tv) {
	anim.stop();
	anim.setStartValue(_sideVal());
	anim.setEndValue(tv);
	anim.start();
}


void PultWindowAndroid::_setSideVal(float v) {
	v = piClampf(v, 0.f, 1.f);
	side_val = v;
	int xd = side_val * width() * widthPart;
	QPalette pal = shadow->palette();
	QColor col = Qt::black;
	col.setAlphaF(side_val / 2.);
	pal.setColor(QPalette::Window, col);
	shadow->setPalette(pal);
	side->setVisible(xd > 0);
	shadow->setVisible(xd > 0);
	side->move(xd - side->width(), side->y());
	handle->move(xd - 2, handle->y());
}
