#include "pch.h"
#include <QTreeWidget>
#include <QAction>
#include <QMenu>
#include "ProjectManager.h"
#include <QtConcurrent>

ProjectManager::ProjectManager(metavis* owner)
	: QWidget(owner), owner(owner)
{
	QGridLayout* gridlayout = new QGridLayout();
	gridlayout->setContentsMargins(0, 0, 0, 0);
	treeWidget = new QTreeWidget();
	treeWidget->setColumnCount(1);
	treeWidget->setHeaderHidden(true);
	treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
	connect(treeWidget, &QTreeWidget::customContextMenuRequested, this, &ProjectManager::prepareMenu);
	connect(treeWidget, &QTreeWidget::itemActivated, this, &ProjectManager::itemClicked);
	projectItem = new QTreeWidgetItem(treeWidget, QStringList("Project"), ProjectManager::Types::ProjectHeader);
	projectItem->setExpanded(true);
	gridlayout->addWidget(treeWidget);
	this->setLayout(gridlayout);


	//Create Menus
	projectMenu = new QMenu(this);
	QAction* metaLogAddAction = new QAction("Add .csv-File...");
	QIcon test(":/metavis/Resources/file.svg");
	metaLogAddAction->setIcon(test);
	connect(metaLogAddAction, &QAction::triggered, this, &ProjectManager::openFileDialog);
	//connect(metaLogAddAction, &QAction::triggered, this, [this]() { project.addFile(); });
	QAction* removeAllFilesAction = new QAction("Remove all .csv-Files");
	removeAllFilesAction->setIcon(QIcon(":/metavis/Resources/csv_remove.svg"));
	connect(removeAllFilesAction, &QAction::triggered, this, [this]() {
		for (RunData& data : project.getRunList()) {
			this->owner->removeRunDataFromAllViews(&data);
		}
		project.clearDataList();
		createTreeWidget();
		});
	projectMenu->addAction(metaLogAddAction);
	projectMenu->addAction(removeAllFilesAction);
	
	metalogFileMenu = new QMenu(this);
	QIcon removeIcon(":/metavis/Resources/close_big_red.svg");
	removeMetalogFileAction = new QAction("Remove");
	removeMetalogFileAction->setIcon(removeIcon);
	//connect(removeMetalogFileAction, &QAction::triggered, this, [this]() {project.clearDataList(); });
	selectAction = new QAction("Show");
	selectAction->setIcon(QIcon(":/metavis/Resources/arrow_right.svg"));
	metalogFileMenu->addAction(selectAction);
	metalogFileMenu->addAction(removeMetalogFileAction);
	singleRunMenu = new QMenu(this);
	singleRunMenu->addAction(selectAction);
	connect(&watcher, &QFutureWatcher<void>::finished, this, &ProjectManager::displayNewFile);
	
	//Settings
	QSettings settings("settings.ini", QSettings::IniFormat, this);
	settings.beginGroup("ProjectManager");
	lastPath = settings.value("path", "").toString();
	settings.endGroup();
}

ProjectManager::~ProjectManager()
{
	//Settings
	QSettings settings("settings.ini", QSettings::IniFormat, this);
	settings.beginGroup("ProjectManager");
	settings.setValue("path", lastPath);
	settings.endGroup();
}




void ProjectManager::openFileDialog()
{
	qDebug() << "openFile";
	this->lastPath != "";
	QStringList pathList = QFileDialog::getOpenFileNames(this, "Open logFile",(this->lastPath != "")? lastPath :QStandardPaths::displayName(QStandardPaths::DesktopLocation), "Logfile (*.csv)");
	if (pathList.isEmpty()) {
		qDebug() << "No file selected";
		return;
	}
	QDir d = QFileInfo(pathList.front()).absoluteDir();
	lastPath = d.absolutePath();
	owner->showStatusBarLoading();
	//this->loadingFuture = std::async(std::launch::async, static_cast<void(ProjectManager::*)(std::list<QString>)>(&ProjectManager::openFiles), this, stdList);
	future = QtConcurrent::run(this, &ProjectManager::openFiles, pathList);
	watcher.setFuture(future);
}


void ProjectManager::openFiles(QStringList pathList)
{
	int size = project.getRunList().size();
	for (QString& string: pathList) {
		qDebug() << "file:" << string;
		project.addFile(string.toStdString());
	}
	for (std::list<RunData>::iterator iter = std::next(project.getRunList().begin(), size); iter != project.getRunList().end(); iter++) {
		//owner->addRunDataToCompareViews(&*iter);
	}
}

void ProjectManager::displayNewFile()
{
	owner->selectRunData(&project.getRunList().back());
	owner->selectSingleRun(&project.getRunList().back().singleRunList.front());
	createTreeWidget();
	owner->clearStatusBar();
}





void ProjectManager::createTreeWidget()
{
	//remove all clidren
	for (QTreeWidgetItem* item : projectItem->takeChildren()) {
		delete item;
	}
	for (RunData& run : project.getRunList()) {
		qDebug() << "RunList add" << QString::fromStdString(run.name);
		QTreeWidgetItem* item = new QTreeWidgetItem(projectItem, QStringList(QString::fromStdString(run.name)), ProjectManager::Types::LogFile);
		QVariant variant(QVariant::fromValue(static_cast<void*>(&run)));
		item->setData(1, Qt::UserRole, variant);
		item->setExpanded(true);
		int count = 0;
		for (SingleRun& srun : run.singleRunList) {
			QTreeWidgetItem* runitem = new QTreeWidgetItem(item, QStringList(QString::fromStdString(run.name) + "[" + QString::number(count) + "]"), ProjectManager::Types::Run);
			QVariant srunVariant(QVariant::fromValue(static_cast<void*>(&srun)));
			runitem->setData(1, Qt::UserRole, srunVariant);
			count++;
		}
	}
	
}

void ProjectManager::showItem(QTreeWidgetItem* item)
{
	switch (item->type()) {
	case LogFile:
	{
		RunData* data = static_cast<RunData*>(item->data(1, Qt::UserRole).value<void*>());
		if (data != nullptr) {
			owner->selectRunData(data);
		}
		break;
	}
	case Run:
	{
		SingleRun* data = static_cast<SingleRun*>(item->data(1, Qt::UserRole).value<void*>());
		if (data != nullptr) {
			owner->selectSingleRun(data);
		}
		break;
	}		
	default:
		break;
	}
	
}





void ProjectManager::itemClicked(QTreeWidgetItem* item, int column)
{
	switch (item->type()) {
	case Types::Graph:
		break;
	case Types::GraphManger:
		break;
	case Types::LogFile:
	case Types::Run:
		showItem(item);
		break;
	case Types::LogManger:
		break;
	default:
		break;
	}
}


void ProjectManager::prepareMenu(const QPoint& pos) {
	QTreeWidgetItem* item = treeWidget->itemAt(pos);
	if (item == nullptr) return;
	switch (item->type()) {
	case Types::Graph:
		//graphMenu->exec(treeWidget->mapToGlobal(pos));
		break;
	case Types::GraphManger:
		break;
	case Types::Run:
	{
		QAction* used = singleRunMenu->exec(treeWidget->mapToGlobal(pos));
		if (used == selectAction) {
			showItem(item);
		}
		break;
	}
	case Types::LogFile:
	{
		QAction* used = metalogFileMenu->exec(treeWidget->mapToGlobal(pos));
		if (used == removeMetalogFileAction) {
			RunData* data = static_cast<RunData*>(item->data(1, Qt::UserRole).value<void*>());
			owner->removeRunDataFromAllViews(data);
			project.removeRunData(data);
			createTreeWidget();
		}
		else if (used == selectAction) {
			showItem(item);
		}
		break;
	}
	
	case Types::ProjectHeader:
		projectMenu->exec(treeWidget->mapToGlobal(pos));
		break;
	default:
		break;
	}

}

