#include "global.h"

#include "matcherdialog.h"
#include "g12Image.h"
#include <qpainter.h>
#include <math.h>

MatcherDialog::MatcherDialog(QWidget *parent)
    : QDialog(parent)
{
	ui.setupUi(this);

	/* Main UI*/
	connect(ui.widget, SIGNAL(askParentRepaint(QPaintEvent *, QWidget *)), this, SLOT(repaintChild(QPaintEvent *, QWidget *)));
	connect(ui.widget, SIGNAL(notifyParentMouseMove(QMouseEvent* )), this, SLOT(mouseChild(QMouseEvent *)));

	connect(ui.leftBufferButton, SIGNAL(released()),  ui.widget, SLOT(update()));
	connect(ui.rightBufferButton, SIGNAL(released()),  ui.widget, SLOT(update()));

	connect(ui.pointsButton, SIGNAL(released()), ui.widget, SLOT(update()));
	connect(ui.arrowsButton, SIGNAL(released()), ui.widget, SLOT(update()));
	connect(ui.noneButton, SIGNAL(released()), this, SLOT(update()));


	buffer1 = NULL;
	buffer2 = NULL;
	flow = NULL;
	corrList = NULL;
	corrNumber = 0;


	sParam.epsilonHighLimit = 8;
	sParam.epsilonLowLimit = 1;
	sParam.sdevHighLimit = 100;
	sParam.sdevLowLimit = 1;
	sParam.mask = 0xFFFF;

	ui.zoneSizeBox->setMinimum(0);
	ui.zoneSizeBox->setMaximum(10);
	ui.zoneSizeBox->setValue(5);

	ui.maxDeviationBox->setMinimum(0);
	ui.maxDeviationBox->setMaximum(2000);
	ui.maxDeviationBox->setValue(9);

	ui.goodSamplesBox->setMinimum(0);
	ui.goodSamplesBox->setMaximum(80);
	ui.goodSamplesBox->setValue(4);

	ui.maxSigBox->setMinimum(0);
	ui.maxSigBox->setMaximum(20);
	ui.maxSigBox->setValue(7);

	ui.epsHighBox->setMaximum(100);
	ui.epsHighBox->setMinimum(0);
	ui.epsHighBox->setValue(sParam.epsilonHighLimit);

	ui.epsLowBox->setMaximum(100);
	ui.epsLowBox->setMinimum(0);
	ui.epsLowBox->setValue(sParam.epsilonLowLimit);

	ui.sDevLowBox->setMaximum(100);
	ui.sDevLowBox->setMinimum(0);
	ui.sDevLowBox->setValue(sParam.sdevLowLimit);

	ui.sDevHighBox->setMaximum(100);
	ui.sDevHighBox->setMinimum(0);
	ui.sDevHighBox->setValue(sParam.sdevHighLimit);

	connect(ui.epsHighBox, SIGNAL(valueChanged(int)), this, SLOT(epsHighChanged(int)));
	connect(ui.epsLowBox, SIGNAL(valueChanged(int)), this, SLOT(epsLowChanged(int)));
	connect(ui.sDevHighBox, SIGNAL(valueChanged(int)), this, SLOT(sDevHighChanged(int)));
	connect(ui.sDevLowBox, SIGNAL(valueChanged(int)), this, SLOT(sDevLowChanged(int)));

	connect(ui.recalculateButton, SIGNAL(released()), this, SLOT(notifyRecalculate()));

}

void MatcherDialog::buffersChangedSlot(G12Buffer *buffer1, G12Buffer *buffer2)
{
	this->buffer1 = buffer1;
	this->buffer2 = buffer2;
	this->update();
}

void MatcherDialog::sDevHighChanged(int value)
{
	sParam.sdevHighLimit = value;
	ui.recalculateButton->setEnabled(true);
}

void MatcherDialog::sDevLowChanged(int value)
{
	sParam.sdevLowLimit = value;
	ui.recalculateButton->setEnabled(true);
}

void MatcherDialog::epsHighChanged(int value)
{
	sParam.epsilonHighLimit = value;
	ui.recalculateButton->setEnabled(true);
}

void MatcherDialog::epsLowChanged(int value)
{
	sParam.epsilonLowLimit = value;
	ui.recalculateButton->setEnabled(true);
}

void MatcherDialog::repaintChild(QPaintEvent *event, QWidget *who)
{
	QPainter painter(who);
	if (ui.leftBufferButton->isChecked() && buffer1 != NULL)
	{
		g12Image image(buffer1);
		painter.drawImage(QPoint(0,0), image);
	}

	if (ui.rightBufferButton->isChecked() && buffer2 != NULL)
	{
		g12Image image(buffer2);
		painter.drawImage(QPoint(0,0), image);
	}

	if (buffer1 == NULL)
		painter.drawText(0,0, who->width()/2, who->height(), Qt::AlignHCenter | Qt::AlignVCenter, QString("NO LEFT IMAGE"));
	if (buffer2 == NULL)
		painter.drawText(who->width()/2, 0, who->width()/2, who->height(), Qt::AlignHCenter | Qt::AlignVCenter, QString("NO RIGHT IMAGE"));

	if (flow == NULL)
			return;
		if (ui.arrowsButton->isChecked())
		{
			int i,j;
			for (i = 6; i < flow->h - 6; i++ )
			{
				for (j = 6; j < flow->w - 6; j++ )
				{
					if (FELEM(flow, j,i).x == FLOW_UNKNOWN_X || FELEM(flow, j,i).y == FLOW_UNKNOWN_Y)
						continue;
					vector2Ds16 point = FELEM(flow, j,i);
					int color = sqrt((double)point.x * point.x + point.y * point.y) * 20;
					if (color > 255)
						color = 255;
					painter.setPen(QColor(0, color, 255));
					painter.setBrush(QColor(0, color, 255));
					painter.drawLine(j,i,j + point.x, i + point.y);

				}
			}
		}
		if (ui.pointsButton->isChecked())
		{
			int i,j;
			for (i = 6; i < flow->h - 6; i++ )
			{
				for (j = 6; j < flow->w - 6; j++ )
				{
					if (FELEM(flow, j,i).x == FLOW_UNKNOWN_X || FELEM(flow, j,i).y == FLOW_UNKNOWN_Y)
						continue;
					vector2Ds16 point = FELEM(flow, j,i);
					int color = sqrt((double)point.x * point.x + point.y * point.y) * 20;
					if (color > 255)
						color = 255;
					//color = (color << 16) | (0xFF);
					painter.setBrush(QColor(0, color, 255));
					painter.setPen(QColor(0, color, 255));
					painter.drawPoint(j,i);
				}
			}
		}

}

void MatcherDialog::mouseChild(QMouseEvent *event)
{
	if (buffer1 == NULL && buffer2 == NULL)
		return;
/*	int x = event->x();
	int y = event->y();
	if (x > 0 && x < showBuffer->w && y >0 && y < showBuffer->w)
	{
		pointSelected(event->pos());
	}*/
}


void MatcherDialog::notifyRecalculate(void)
{
	//emit needCoratgeListUpdate();

//	ui.recalculateButton->setEnabled(false);
	if (buffer1 == NULL || buffer2 == NULL)
		return;


	int zoneSize = ui.zoneSizeBox->value();
	int hitsThres = ui.maxDeviationBox->value();
	int hitsLimit = ui.goodSamplesBox->value();
	int cutOut = ui.maxSigBox->value();
	int shouldFilter = ui.shouldFilterBox->isChecked();


	integralBuffer *II1 = integralBufferCreateFromG12(buffer1);
	integralBuffer *II2 = integralBufferCreateFromG12(buffer2);

    signaturesBuffer *S1 = signaturesBufferCreateFromIntegralx86fastIP(II1, &sParam);
	signaturesBuffer *S2 = signaturesBufferCreateFromIntegralx86fastIP(II2, &sParam);

	FlowBuffer *newFlow = calculateTheFlowSimple(S1, S2, cutOut);
	if (shouldFilter)
	{
		FlowBuffer *filteredFlow = filterFlowSimple(newFlow, zoneSize, hitsThres, hitsLimit);
		flowBufferDelete(newFlow);
		newFlow = filteredFlow;
	}

	signaturesBufferDelete(S1);
	signaturesBufferDelete(S2);

	integralBufferDelete(II1);
	integralBufferDelete(II2);

	if (flow != NULL)
		flowBufferDelete(flow);
	flow = newFlow;
	int density = flowCountDensity(flow);
	double persent = (double)density * 100.0 / (flow->h * flow->w);
	ui.statisticsLabel->setText(QString("%1 %").arg(persent, 3, 'f', 3));

	Correspondance *oldList = corrList;
	generateCorrespondanceList(flow, &corrList, &corrNumber);

	emit corrListChanged(corrList, corrNumber);

	if (oldList != NULL)
		dv_free(oldList);
	ui.widget->update();
}


MatcherDialog::~MatcherDialog()
{

}
