#include "..\Header\MainWindow.h"
#include "..\Header\OpenGlViewer.h"
#include "..\Header\MshFile.h"
#include "..\Header\defines.h"
#include <QKeyEvent>
#include <QMessageBox>
#include <QFileDialog>


/////////////////////////////////////////////////////////////////////////
// constructor/destructor

MainWindow::MainWindow(QWidget *parent)
	: QMainWindow(parent)
	, ui (new Ui::MainWindowClass)
{
	setupWindow();
}

MainWindow::~MainWindow()
{
	delete ui;
}


/////////////////////////////////////////////////////////////////////////
// private functions

void MainWindow::setupWindow()
{
	ui->setupUi(this);

	this->setWindowTitle(WINDOW_NAME);
	this->setWindowIcon(QIcon(":/MainWindow/icon.ico"));
	this->resize(WINDOW_WIDTH, WINDOW_HEIGHT);

	this->setCentralWidget(new OpenGlViewer(this));

	ui->mainToolBar->addAction("Open File", this, &MainWindow::openFile);
	ui->mainToolBar->addAction("File Info", this, &MainWindow::aboutFile);

	ui->statusBar->showMessage(DEFAULT_STATUS_MESSAGE);
}

void MainWindow::import(const char * path)
{
	// variables
	std::vector<Model*>* tmp_models = nullptr;
	std::vector<TextureData*>* tmp_textures = new std::vector<TextureData*>;
	std::vector<std::string> tmp_texNames;
	BoundingBox tmp_bbox;

	// model file
	try
	{
		MshFile file(path);
		tmp_models = file.getModels();
		tmp_texNames = file.getTextureNames();
		tmp_bbox = file.getBoundingBox();
	}
	catch (std::invalid_argument e)
	{
		QMessageBox msg(this);
		msg.addButton(QMessageBox::Ok);
		msg.setText(QString::fromStdString(e.what()));
		msg.setIcon(QMessageBox::Critical);
		msg.setWindowTitle("Open File Error");

		msg.exec();
		return;
	}

	// parth to texture
	std::string tmp_path = path;
	while (tmp_path.back() != '/' && tmp_path.back() != '\\')
		tmp_path.pop_back();

	// load all textures
	for (auto& texIt : tmp_texNames)
	{
		TextureData* new_data = new TextureData;
		try
		{
			TextureTGA tmp_texFile(std::string(tmp_path + texIt).c_str());

			new_data->alpha = tmp_texFile.hasAlpha();
			new_data->width = tmp_texFile.getWidth();
			new_data->height = tmp_texFile.getHeight();
			new_data->data = tmp_texFile.getData();
		}
		catch (std::invalid_argument e)
		{
			new_data->alpha = true;
			new_data->width = 1;
			new_data->height = 1;
			new_data->data = new std::vector<std::uint8_t>({ 0, 0, 255, 255 });
		}

		tmp_textures->push_back(new_data);
	}

	// add a solid default color at the end (maybe there is an invalid index later)
	TextureData* new_data = new TextureData;
	new_data->alpha = true;
	new_data->width = 1;
	new_data->height = 1;
	new_data->data = new std::vector<std::uint8_t>({ 0, 0, 255, 255 });
	tmp_textures->push_back(new_data);

	// clean up texture name list
	tmp_texNames.clear();

	// give the data to the viewer
	OpenGlViewer* tmp_viewer = dynamic_cast<OpenGlViewer*>(centralWidget());
	tmp_viewer->setData(tmp_models, tmp_textures, tmp_bbox);
}


/////////////////////////////////////////////////////////////////////////
// private slots

void MainWindow::openFile()
{
	QString fileName = QFileDialog::getOpenFileName(this, "Open File", "../Release/Msh", "Mesh (*.msh)");

	import(fileName.toStdString().c_str());
}

void MainWindow::aboutFile()
{
	//TODO: Open Window with file information
	QMessageBox* dialog = new QMessageBox(QMessageBox::Information, WINDOW_NAME, "File Info", QMessageBox::StandardButton::Close, this, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
	dialog->setDetailedText("This is the cool detailed text\n");
	dialog->exec();
}


/////////////////////////////////////////////////////////////////////////
// events

void MainWindow::keyPressEvent(QKeyEvent * keyEvent)
{
	switch (keyEvent->key())
	{
	case Qt::Key::Key_Escape:
		close();
		break;
	}

	QMainWindow::keyPressEvent(keyEvent);
}
