/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2025 Univ. Grenoble Alpes, CNRS, Grenoble INP - UGA, TIMC, 38000 Grenoble, France
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/
#include "SaveActionState.h"

// CamiTK stuff
#include <Application.h>
#include <Component.h>
#include <Log.h>

using namespace camitk;

// Qt stuff
#include <QString>
#include <QFileDialog>



SaveActionState::SaveActionState(QState* parent, QString name, QString description,
                                 QString defaultSaveDirName, QTextStream* logStream)
    : ActionState(parent, name, description, logStream) {
    this->defaultSaveDirName = defaultSaveDirName;
    this->myAction = Application::getAction("Save");
}

void SaveActionState::setInput(QVector<saveComponentsInfo> inputComponentsInfo) {
    this->inputComponentsInfo = inputComponentsInfo;
}

Action::ApplyStatus SaveActionState::applyAction() {
    Action::ApplyStatus status(Action::TRIGGERED);

    if (logStream != nullptr) {
        (*logStream) << "\t\t<applyAction>" << Qt::endl;
        (*logStream) << "\t\t\t<name>" << myAction->getName() << "</name>" << Qt::endl;
        (*logStream) << "\t\t\t<inputs>" << Qt::endl;
    }

    // set input components
    ComponentList allComps = Application::getAllComponents();
    ComponentList::const_iterator compIt;
    ComponentList inputComps;

    for (QVector<saveComponentsInfo>::const_iterator it = inputComponentsInfo.constBegin(); it != inputComponentsInfo.constEnd(); ++it) {

        QString compName = (*it).name;
        QString compType = (*it).type;
        QString compExt  = (*it).extension;
        QString compDir  = (*it).directory;

        // Look for the corresponding component into the list of all components
        compIt = allComps.constBegin();

        while ((compIt != allComps.constEnd()) &&
                (((*compIt)->getName() != compName) ||
                 (!(*compIt)->isInstanceOf(compType)))) {
            ++compIt;
        }

        if (compIt == allComps.constEnd()) {
            status = Action::ERROR;
            CAMITK_ERROR(tr("Cannot find the component named %1 of type %2 in the list of existing components.").arg(compName, compType));
            return status;
        }


        if (compDir.isEmpty()) {
            compDir = this->defaultSaveDirName;

            if (compDir.isEmpty()) {
                compDir = QFileDialog::getExistingDirectory(this->getWidget(),
                          "Please select a directory where to save the component " + compName);
            }
        }

        /*
            Set the component filename before saving.
            Indeed, to save output components somewhere, we cannot use "save as" action as it is "triggered"
            and cannot be applied in a pipeline (TODO: modify this in camitkcore...
            ... but not before the next release !).

            So to not have to trigger save as, we put a filename composed with
                - the save directory for the current ASM
                - the name of the output component
                - a proper file extention precised in the xml file
            (*outIt)->setFileName(saveDirName + "/" + compName + ".mha");
            */
        (*compIt)->setFileName(compDir + "/" + compName + compExt);
        inputComps.append((*compIt));

        if (logStream != nullptr) {
            (*logStream) << "\t\t\t\t<component name='";
            (*logStream) << compDir + "/" + compName + compExt << "' type='" << compType << "'/>" << Qt::endl;
        }
    }

    if (logStream != nullptr) {
        (*logStream) << "\t\t\t</inputs>" << Qt::endl;
    }


    myAction->setInputComponents(inputComps);

    // apply the action
    status = myAction->applyInPipeline();

    // If the image has been saved, then it is not modified any more...
    if (status == Action::SUCCESS) {
        for (compIt = inputComps.constBegin(); compIt != inputComps.constEnd(); ++compIt) {
            (*compIt)->setModified(false);
        }
    }

    if (logStream != nullptr) {
        (*logStream) << "\t\t\t<status>" << Action::getStatusAsString(status) << "</status>" << Qt::endl;
        (*logStream) << "\t\t</applyAction>" << Qt::endl;
    }

    Application::refresh();

    return status;
}
