#include "modelcreator.h"
#include "ui_modelcreator.h"
#include <QFileDialog>
#include <QMessageBox>
#include "modelcreatordata.h"
#include <string.h>
#include "m3derror.h"

ModelCreator::ModelCreator(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::modelCreator)
{
    ui->setupUi(this);
    ui->tabWidget->setTabEnabled(6, false);
    ui->tabWidget->setTabEnabled(7, false);
    MCD = new ModelCreatorData;
}

ModelCreator::~ModelCreator()
{
    if(MCD)delete MCD;
    delete ui;
}

void ModelCreator::on_action_Open_triggered()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open model"), "", tr("Magic3D model files (*.m3dm)"));
    if(!fileName.isEmpty()) loadModel(fileName);
}
void ModelCreator::materialFileSelect()
{
    QFileDialog dialog(this);
    dialog.setFileMode(QFileDialog::AnyFile);
    QString fileName = dialog.getOpenFileName(this, tr("Open material"), "", tr("Magic3D material files (*.m3dml)"));
    if(fileName.isEmpty())return;
    loadMaterial(fileName);
}
void ModelCreator::surfaceNameSelect()
{
    QFileDialog dialog(this);
    dialog.setFileMode(QFileDialog::AnyFile);
    QString fileName = dialog.getOpenFileName(this, tr("Open surface"), "", tr("Magic3D surface files (*.m3dme)"));
    if(fileName.isEmpty())return;
    emit setSurfaceName(fileName);
}
void ModelCreator::enableBumpMap(int)
{
    ui->tabWidget->setTabEnabled(6, ui->enableBumpMap->checkState());
}
void ModelCreator::enableNormalMap(int)
{
    ui->tabWidget->setTabEnabled(7, ui->enableNormalMap->checkState());
}

void ModelCreator::on_action_Create_triggered()
{
    if(MCD)delete MCD;
    MCD = new ModelCreatorData;
}

void ModelCreator::on_actionSave_As_triggered()
{
    QFileDialog dialog;
    dialog.setDefaultSuffix("m3dm");
    dialog.setNameFilter(tr("Magic3D model file (*.m3dm)"));
    dialog.setLabelText(QFileDialog::Accept, tr("Save"));
    dialog.setAcceptMode(QFileDialog::AcceptSave);
    dialog.setViewMode(QFileDialog::Detail);
    QString saveFileName;
    if(dialog.exec())
    {
        QStringList saveFileNames = dialog.selectedFiles();
        saveFileName = saveFileNames.at(0);

        QString model_name = ui->modelName->text();
        SET_VALUE(model, model_name, model_name);
        QString material_name = ui->materialName->text();
        SET_VALUE(model, material_name, material_name);
        QString mesh_name = ui->meshName->text();
        SET_VALUE(model, mesh_name, mesh_name);
        QString base_path = ui->modelBastePath->text();
        SET_VALUE(model, base_path, base_path);

        MCD->model.set_header(&MCD->model_header);
        MCD->model.set_data(&MCD->model_data);
        MCD->model.save(saveFileName.toUtf8().data());
    }
}
void ModelCreator::saveModel()
{
    QFileDialog dialog;
    dialog.setDefaultSuffix("m3dml");
    dialog.setNameFilter(tr("Magic3D material file (*.m3dml)"));
    dialog.setLabelText(QFileDialog::Accept, tr("Save"));
    dialog.setAcceptMode(QFileDialog::AcceptSave);
    dialog.setViewMode(QFileDialog::Detail);
    QString saveFileName;
    int lnumber = 6;
    if(dialog.exec())
    {
        QStringList saveFileNames = dialog.selectedFiles();
        saveFileName = saveFileNames.at(0);

        ui->difuseTab->saveLayer();
        ui->ambientTab->saveLayer();
        ui->shininessTab->saveLayer();
        ui->specularTab->saveLayer();
        ui->emissionTab->saveLayer();
        ui->roughnessTab->saveLayer();

        if(ui->enableNormalMap->isChecked()){ui->normalMapTab->saveLayer();lnumber++;}
        if(ui->enableBumpMap->isChecked()){ui->bumpMapTab->saveLayer();lnumber++;}

        QString shader_name = ui->shaderName->text();
        MCD->material_header.layers_number = lnumber;
        MCD->material_header.shader_path_length = shader_name.length()+1;
        ALLOC_N(MCD->material_shader_path, char, shader_name.length()+1);
        strncpy(MCD->material_shader_path, shader_name.toUtf8().data(), shader_name.length()+1);
        MCD->material.set_shader_path(MCD->material_shader_path);

        MCD->material.set_header_(&MCD->material_header);
        MCD->material.save(saveFileName.toUtf8().data());
    }
}

void ModelCreator::loadShader()
{
    QFileDialog dialog(this);
    dialog.setFileMode(QFileDialog::AnyFile);
    QString fileName = dialog.getOpenFileName(this, tr("Open shader"), "", tr("Magic3D shader files (*.m3ds)"));
    if(fileName.isEmpty())return;
    loadShader(fileName);
}

void ModelCreator::saveShader()
{
    QFileDialog dialog;
    dialog.setDefaultSuffix("m3ds");
    dialog.setNameFilter(tr("Magic3D shader file (*.m3ds)"));
    dialog.setLabelText(QFileDialog::Accept, tr("Save"));
    dialog.setAcceptMode(QFileDialog::AcceptSave);
    dialog.setViewMode(QFileDialog::Detail);
    QString saveFileName;
    if(dialog.exec())
    {
        QStringList saveFileNames = dialog.selectedFiles();
        saveFileName = saveFileNames.at(0);

        QString vertexShader = ui->vertexShaderCode->toPlainText();
        QString fragmentShader = ui->fragmentShaderCode->toPlainText();

        SET_VALUE_SIZE(shader, vertex_shader, vertexShader);
        SET_VALUE_SIZE(shader, fragment_shader, fragmentShader);

        MCD->shader.set_header(&MCD->shader_header);
        MCD->shader.set_data(&MCD->shader_data);
        MCD->shader.save(saveFileName.toUtf8().data());
    }

}

void ModelCreator::loadShader(QString &file)
{
    try
    {
        MCD->shader.load(file.toUtf8().data());
    }catch(M3DError error)
    {
        QMessageBox::critical(this, tr("Open file error:")+file, QString::fromLocal8Bit(error.get_reason().c_str()));
        return;
    }
    ui->shaderPath->setText(file);

    ui->vertexShaderCode->setPlainText(QString::fromUtf8(MCD->shader.get_data()->vertex_shader));
    ui->fragmentShaderCode->setPlainText(QString::fromUtf8(MCD->shader.get_data()->fragment_shader));
}
void ModelCreator::loadMaterial(QString &material)
{
    try
    {
        MCD->material.load(material.toUtf8().data());
    }catch(M3DError error)
    {
        QMessageBox::critical(this, tr("Open file error"), QString::fromLocal8Bit(error.get_reason().c_str()));
        return;
    }
    emit setMaterialFile(material);
    ui->shaderName->setText(MCD->material.get_shader_path());
    QString baseDir = ui->modelBastePath->text();
    ui->difuseTab->loadLayer(baseDir);
    ui->ambientTab->loadLayer(baseDir);
    ui->shininessTab->loadLayer(baseDir);
    ui->specularTab->loadLayer(baseDir);
    ui->emissionTab->loadLayer(baseDir);
    ui->roughnessTab->loadLayer(baseDir);

    if(ui->normalMapTab->loadLayer(baseDir))ui->enableNormalMap->setChecked(true);
    if(ui->bumpMapTab->loadLayer(baseDir))ui->enableBumpMap->setChecked(true);

    QString shaderPath = baseDir + ui->shaderName->text();
    loadShader(shaderPath);

}
void ModelCreator::loadModel(QString &model)
{
        if(MCD)delete MCD;
        MCD = new ModelCreatorData;
        MCD->model.load(model.toUtf8().data());

        ui->modelName->setText(MCD->model.get_data()->model_name);
        ui->meshName->setText(MCD->model.get_data()->mesh_name);
        ui->materialName->setText(MCD->model.get_data()->material_name);
        ui->modelBastePath->setText(MCD->model.get_data()->base_path);
        QString materialPath = ui->modelBastePath->text() + ui->materialName->text();
        loadMaterial(materialPath);

}
