#include "image_view.h"
#include <QGraphicsScene>
#include <QBuffer>
#include <QEvent>
#include <QMouseEvent>
#include <QWheelEvent>
#include <QDebug>
#include <qmath.h>


ImageView::ImageView(QWidget * parent): QGraphicsView(parent) {
	setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
	setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
	setDragMode(QGraphicsView::NoDrag);
	setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
	setScene(new QGraphicsScene());
	item.setTransformationMode(Qt::SmoothTransformation);
	item.setFlags(0);
	scene()->addItem(&item);
	viewport()->setAutoFillBackground(false);
	viewport()->installEventFilter(this);
	autofit_ = true;
}


ImageView::~ImageView() {
}


QPixmap ImageView::pixmap() const {
	return item.pixmap();
}


void ImageView::setPixmap(QPixmap pixmap) {
	item.setPixmap(pixmap);
	adjustView();
}


void ImageView::setImage(const QImage & i) {
	im_data.clear();
	if (i.isNull()) {
		item.setPixmap(QPixmap());
		return;
	}
	QBuffer b(&im_data); b.open(QIODevice::ReadWrite);
	i.save(&b, "png");
	b.close();
	item.setPixmap(QPixmap::fromImage(i));
	adjustView();
}


void ImageView::setImage(const QByteArray & i) {
	im_data = i;
	if (i.isEmpty()) {
		item.setPixmap(QPixmap());
		return;
	}
	item.setPixmap(QPixmap::fromImage(QImage::fromData(i)));
	adjustView();

}


void ImageView::clear() {
	im_data.clear();
	item.setPixmap(QPixmap());
}


void ImageView::mouseDoubleClickEvent(QMouseEvent * e) {
	autofit();
}


void ImageView::mousePressEvent(QMouseEvent * e) {
	QGraphicsView::mousePressEvent(e);
	emit clicked(mapToScene(e->pos()), e->buttons());
}


void ImageView::mouseMoveEvent(QMouseEvent * e) {
	//if (e->buttons().testFlag(Qt::RightButton) && !autofit_ && isInteractive()) return;;
	QGraphicsView::mouseMoveEvent(e);
}


//void ImageView::wheelEvent(QWheelEvent * e) {
//	if (!e->modifiers().testFlag(Qt::ControlModifier) || !isInteractive()) return;
//	double scl = 1. + e->delta() / 500.;
//	//autofit_ = false;
//	//scale(scl, scl);
//}


bool ImageView::eventFilter(QObject * o, QEvent * e) {
	QMouseEvent * me = (QMouseEvent *)e;
	switch (e->type()) {
	case QEvent::Resize:
		adjustView();
		break;
	case QEvent::MouseButtonPress:
		prev_pos = me->pos();
		break;
	case QEvent::MouseMove:
		if (!me->buttons().testFlag(Qt::RightButton) || autofit_ || !isInteractive()) break;
		{
		//double scl = 1. / qSqrt(transform().determinant());
		//QPointF dp = QPointF(me->pos() - prev_pos) * scl;
		//qDebug() << dp;
		//translate(0.00001, 0);
		prev_pos = me->pos();
		}
		break;
	default: break;
	}
	return QGraphicsView::eventFilter(o, e);
}


void ImageView::adjustView() {
	if (!autofit_) return;
	setSceneRect(item.boundingRect());
	fitInView(&item, Qt::KeepAspectRatio);
	centerOn(&item);
}


void ImageView::autofit() {
	autofit_ = true;
	adjustView();
}
