#include "mainwindow.h"

#include "piqt.h"
#include "qad_locations.h"

#include <QActionGroup>
#include <QFileInfo>
#include <QMetaEnum>
#include <QMimeData>
#include <pifile.h>
#include <pijson.h>
#include <pivaluetree.h>
#include <pivaluetree_conversions.h>


MainWindow::MainWindow(QWidget * parent): EMainWindow(parent), Ui::MainWindow() {
	setupUi(this);
	setRecentMenu(menuOpen_recent);
	setAcceptDrops(true);
	session.setFile(QAD::userPath(QAD::ltConfig, "session_valuetreeeditor"));
	session.addEntry(this);
	session.load();
	auto * ag = new QActionGroup(this);
	ag->setExclusive(true);
	connect(ag, &QActionGroup::triggered, [this](QAction * a) { widget->setGrouping((PIValueTreeEdit::Grouping)a->data().toInt()); });
	auto mo = PIValueTreeEdit::staticMetaObject;
	auto me = mo.enumerator(mo.indexOfEnumerator("Grouping"));
	for (int i = 0; i < me.keyCount(); ++i) {
		auto * a = ag->addAction(me.key(i));
		a->setCheckable(true);
		a->setData(me.value(i));
		if (me.value(i) == PIValueTreeEdit::Groups) a->setChecked(true);
	}
	menuView->addActions(ag->actions());
	widget->setFullEditMode(actionFull_edit_mode->isChecked());
}


MainWindow::~MainWindow() {
	session.save();
	session.clear(true);
}


void MainWindow::reset(bool) {
	widget->setValue(PIValueTree());
	setWindowTitle(tr("PIValueTree Editor"));
	file_name.clear();
}


bool MainWindow::load(const QString & path) {
	PIFile f(Q2PIString(path), PIIODevice::ReadOnly);
	if (!f.isOpened()) return false;
	PIString ext = PIFile::FileInfo(f.path()).extension().toLowerCase();
	file_name    = path;
	PIValueTree v;
	if (ext == "conf" || ext == "ini")
		v = PIValueTreeConversions::fromText(&f);
	else if (ext == "json")
		v = PIValueTreeConversions::fromJSON(PIJSON::fromJSON(PIString::fromUTF8(f.readAll())));
	else if (ext == "bin")
		v = piDeserialize<PIValueTree>(f.readAll());
	widget->setValue(v);
	setWindowTitle(tr("PIValueTree Editor - %1").arg(QFileInfo(path).fileName()));
	return true;
}


bool MainWindow::save(const QString & path) {
	PIFile f(Q2PIString(path), PIIODevice::ReadWrite);
	if (!f.isOpened()) return false;
	f.clear();
	file_name    = path;
	PIString ext = PIFile::FileInfo(f.path()).extension().toLowerCase();
	auto v       = widget->value();
	if (ext == "conf" || ext == "ini")
		f.write(PIValueTreeConversions::toText(v).toUTF8());
	else if (ext == "json")
		f.write(PIValueTreeConversions::toJSON(v).toJSON(PIJSON::Tree, false).toUTF8());
	else if (ext == "bin")
		f.write(piSerialize(v));
	setWindowTitle(tr("PIValueTree Editor - %1").arg(QFileInfo(path).fileName()));
	return true;
}


void MainWindow::changeEvent(QEvent * e) {
	QMainWindow::changeEvent(e);
	switch (e->type()) {
	case QEvent::LanguageChange: retranslateUi(this); break;
	default: break;
	}
}


void MainWindow::dragEnterEvent(QDragEnterEvent * e) {
	if (!e->mimeData()) return;
	QString str = e->mimeData()->text();
	if (str.isEmpty()) return;
	static QStringList exts({"conf", "ini", "json", "bin"});
	if (exts.contains(QFileInfo(str).suffix().toLower().trimmed())) {
		e->accept();
	}
}


void MainWindow::dropEvent(QDropEvent * e) {
	if (!e->mimeData()) return;
	auto path = QUrl(e->mimeData()->text()).toLocalFile();
	if (load(path)) addToRecent(path);
}


void MainWindow::loadingSession(QPIConfig & conf) {
	setRecentFiles(conf.getValue("recent files").toStringList());
}


void MainWindow::savingSession(QPIConfig & conf) {
	conf.setValue("recent files", recentFiles());
}


QString MainWindow::loadFilter() {
	return "All types(*.conf *.ini *.json *.bin);;INI format(*.conf *.ini);;JSON(*.json);;Binary(*.bin)";
}


void MainWindow::on_actionFull_edit_mode_toggled(bool on) {
	widget->setFullEditMode(on);
}


void MainWindow::on_actionRead_only_toggled(bool on) {
	widget->setReadOnly(on);
}
