#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>
#include <uvosled.h>
#include <QFileDialog>

#include "../profile.h"

MainWindow::MainWindow(bool viewer, QWidget *parent)
	: QMainWindow(parent)
	, about_(this)
	, ui(new Ui::MainWindow)
{
	ui->setupUi(this);
	ui->statusbar->showMessage("no cameras");
	connect(ui->actionQuit, &QAction::triggered, [this](bool checked){(void)checked; close();});
	connect(ui->actionCameras, &QAction::triggered, [this](bool checked){(void)checked; sigChooseCameras();});
	connect(ui->actionProfile, &QAction::triggered, [this](bool checked){(void)checked; sigEditProfiles();});
	connect(ui->comboBox, &QComboBox::currentTextChanged, this, &MainWindow::sigProfile);
	connect(ui->pushButtonCapture, &QPushButton::clicked, [this](){statusMsg("captureing");});
	connect(ui->pushButtonCapture, &QPushButton::clicked, this, &MainWindow::sigCapture);
	connect(ui->mainViewer, &CvImageViewer::sigValue, this, &MainWindow::setImageValue);
	connect(ui->actionOpen, &QAction::triggered, [this](bool checked){(void)checked; openImage();});
	connect(ui->actionSave_2, &QAction::triggered, [this](bool checked){(void)checked; saveImage();});
	connect(ui->actionAbout, &QAction::triggered, [this](bool checked){(void)checked; about_.show();});
	connect(ui->horizontalSlider_max, &QSlider::sliderMoved, [this](double value){ui->mainViewer->setClamp(value/10.0);});
	connect(ui->mainViewer, &CvImageViewer::sigMax, [this](double max){ui->horizontalSlider_max->setMaximum(max*10.0);});
	refreshProfiles();

	if(viewer)
	{
		ui->groupBoxCameras->setVisible(false);
		ui->groupBox_3->setVisible(false);
	}
}

void MainWindow::setImageValue(size_t x, size_t y, double value)
{
	ui->lcdNumber_3->display((double)x);
	ui->lcdNumber_2->display((double)y);
	ui->lcdNumber->display(value);
}

void MainWindow::setTemperature(double temp)
{
	ui->lcdNumber_temp->display(temp);
}

void MainWindow::saveImage()
{
	if(!ui->mainViewer->getImage().data)
	{
		QMessageBox::warning(this, "No image", "There is no image to save");
		return;
	}

	QString fileName = QFileDialog::getSaveFileName(this, "Save Image", lastSavedPath_, "*.mat");
	if(!fileName.isEmpty())
	{
		lastSavedPath_= fileName.mid(0, fileName.lastIndexOf('/'));
		QStringList tokens = fileName.split('.');
		if(tokens.back() != "mat")
			fileName.append(".mat");
		cv::FileStorage matf(fileName.toStdString(), cv::FileStorage::WRITE);
		matf<<"image"<<ui->mainViewer->getImage();
		matf.release();
	}
}

void MainWindow::openImage()
{
	QString fileName = QFileDialog::getOpenFileName(this, "Open Image", lastSavedPath_, "*.mat");
	if(!fileName.isEmpty())
	{
		cv::Mat image;
		cv::FileStorage matf(fileName.toStdString(), cv::FileStorage::READ);
		try
		{
			matf["image"]>>image;
		}
		catch(const cv::Exception& ex)
		{
			qDebug()<<ex.what();
			QMessageBox::warning(this, "Invalid file", "File selected dose not contain a valid image");
			return;
		}

		if(matf.isOpened() && (!image.data || image.type() != CV_32FC1))
		{
			image.release();
			QMessageBox::warning(this, "Invalid file", "File selected dose not contain a valid image");
		}
		else if(!image.data)
		{
			QMessageBox::warning(this, "Can no open", "Can not open file selected");
		}
		matf.release();
		ui->mainViewer->setImage(Camera::Image(image, 0));
	}
}

void MainWindow::enableCapture(bool enable)
{
	ui->statusbar->showMessage(enable ? "idle" : "cameras not ready" );
	ui->pushButtonCapture->setEnabled(enable);
}

void MainWindow::addCamera(std::shared_ptr<Camera> camera)
{
	viewers_.push_back(new CvImageViewer(this, camera->id()));
	viewers_.back()->setFixedOnWidth(true);
	connect(camera.get(), &Camera::newImage, viewers_.back(), &CvImageViewer::setImage, Qt::QueuedConnection);
	ui->viewerLayout->addWidget(viewers_.back());
}

void MainWindow::statusMsg(QString msg)
{
	ui->statusbar->showMessage(msg);
}

void MainWindow::removeCamera(std::shared_ptr<Camera> camera)
{
	for(size_t i = 0; i < viewers_.size(); ++i)
	{
		if(viewers_[i]->lastId() == camera->id())
		{
			ui->viewerLayout->removeWidget(viewers_[i]);
			delete viewers_[i];
			viewers_.erase(viewers_.begin()+i);
			--i;
		}
	}
}

bool MainWindow::setProfile(const QString& profileName)
{
	ui->comboBox->clear();
	QList<QString> profiles = Profile::avaiableProfiles();
	int selected = -1;
	for(int i = 0; i < profiles.size(); ++i)
	{
		if(profileName == profiles[i])
			selected = i;
		ui->comboBox->addItem(profiles[i]);
	}
	if(selected != -1)
	{
		ui->comboBox->setCurrentIndex(selected);
		return true;
	}
	else
	{
		return false;
	}
}

QString MainWindow::getProfileName()
{
	return ui->comboBox->currentText();
}

void MainWindow::refreshProfiles()
{
	QString tmp = ui->comboBox->currentText();
	ui->comboBox->clear();
	QList<QString> profiles = Profile::avaiableProfiles();
	for(const QString& string : profiles)
		ui->comboBox->addItem(string);
	setProfile(tmp);
}

void MainWindow::profileInconpatible(QString message)
{
	QMessageBox::warning(this, "Profile Incompatible", message);
}

CvImageViewer* MainWindow::mainImageViewer()
{
	return ui->mainViewer;
}

MainWindow::~MainWindow()
{
	for(CvImageViewer* viewer : viewers_)
		delete viewer;
	delete ui;
}
