#include "pch.h"
#include "TsneControlPanel.h"
#include <QPushButton>
#include <QProgressBar>
#include <QGridLayout>
#include <QSpacerItem>
#include <QLineEdit>
#include <QSlider>

TsneControlPanel::TsneControlPanel(QWidget *parent)
	: QWidget(parent)
{
	plott->setVisibleWindow(-20, 20, -20, 20);


	QVBoxLayout* layout = new QVBoxLayout(this);
	layout->setContentsMargins(0, 0, 0, 0);
	QHBoxLayout* buttonLayout = new QHBoxLayout();
	buttonLayout->setContentsMargins(0, 0, 0, 0);
	layout->addWidget(plott);
	layout->addLayout(buttonLayout);

	//ButtonPanel
	showOptionsButton = new QPushButton("Hide Options");
	connect(showOptionsButton, &QPushButton::pressed, this, &TsneControlPanel::toggleOptions);
	QPushButton* startButton = new QPushButton("Start");
	connect(startButton, &QPushButton::pressed, this, &TsneControlPanel::start);
	QPushButton* pauseButton = new QPushButton("Pause");
	connect(pauseButton, &QPushButton::pressed, this, &TsneControlPanel::pause);
	iterationLabel->setText("Iteration: 0");
	progressBar->setSizePolicy(QSizePolicy::Policy::Expanding, QSizePolicy::Policy::Preferred); 
	progressBar->setAlignment(Qt::AlignCenter);
	progressBar->setValue(0);
	progressBar->setMaximum(tsneSettings->maxIter - 1);
	buttonLayout->addWidget(startButton);
	buttonLayout->addWidget(pauseButton);
	buttonLayout->addWidget(iterationLabel);
	buttonLayout->addWidget(progressBar);
	buttonLayout->addWidget(showOptionsButton);
	
	
	layout->addWidget(tsneSettings);
	
	layout->addWidget(slider);

	//Slider
	slider->setTitle("Iteration:");
	connect(slider, &RangeSlider::maxChanged, plott, &TsnePlott::setMaximumIterationToDispaly);
	connect(slider, &RangeSlider::minChanged, plott, &TsnePlott::setMinimumIterationToDispaly);
	
	
	//Gradient
	layout->addWidget(gradient);
	connect(gradient, &ColorGradient::gradientChanged, this, [this]() {this->plott->updateColors(*gradient); });

	//Settings
	QSettings settings("settings.ini", QSettings::IniFormat, this);
	settings.beginGroup("Tsne");
	if (settings.value("hideOptions", true).toBool()) {
		toggleOptions();
	}
	settings.endGroup();
}

TsneControlPanel::~TsneControlPanel()
{
	//Settings
	QSettings settings("settings.ini", QSettings::IniFormat, this);
	settings.beginGroup("Tsne");
	settings.setValue("hideOptions", this->isOptionHidden);
	settings.endGroup();
}

void TsneControlPanel::assignData(std::vector<SolutionPointData>::iterator begin, std::vector<SolutionPointData>::iterator end, QString runName)
{
	this->begin = begin;
	this->end = end;
	runName = runName;
	plott->setDisplayLabel(runName);
	resetPanel();
	plott->clear();
}

void TsneControlPanel::clear()
{
	begin = std::vector<SolutionPointData>::iterator();
	end = std::vector<SolutionPointData>::iterator();
	runName = "";
	resetPanel();
	plott->clear();
}


void TsneControlPanel::toggleOptions()
{
	this->isOptionHidden = !this->isOptionHidden;
	showOptionsButton->setText(this->isOptionHidden ? "More Options" : "Hide Options");
	this->slider->setHidden(this->isOptionHidden);
	this->gradient->setHidden(this->isOptionHidden);
	this->tsneSettings->setHidden(this->isOptionHidden);
}

void TsneControlPanel::resetPanel()
{
	if (algo != nullptr) {
		delete algo;
		algo = nullptr;
	}
	iterationChanged(0);
}


void TsneControlPanel::pause()
{
	if (algo != nullptr) {
		algo->pause();
	}
}

void TsneControlPanel::iterationChanged(int iter)
{
	iterationLabel->setText("Iteration: " + QString::number(iter));
	plott->update();
	progressBar->setValue(iter);
}

void TsneControlPanel::start()
{
	qDebug() << "start";
	if (begin == end) {
		qDebug() << "NoData";
		return;
	}
	double* matrixY = nullptr;
	double** matrixYPtr = &matrixY;
	resetPanel();
	algo = new tSneAlgo(begin, end, matrixYPtr, tsneSettings->perplexity, tsneSettings->learnrate, tsneSettings->maxIter);
	connect(algo, &tSneAlgo::changedIter, this, &TsneControlPanel::iterationChanged);
	connect(algo, &tSneAlgo::algoDone, this, &TsneControlPanel::finished);
	emit started();
	algo->start();
	qDebug() << "Y:" << matrixY;
	plott->assignMatrix(begin, end, matrixY, std::distance(begin, end), *gradient);
}
