/*****************************************************************************
 * $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 "qt_bindings.h"
#include "extensionmanager_bindings.h"
#include "docstrings.h"

#include <ExtensionManager.h>
#include <Component.h>
#include <ComponentExtension.h>

namespace camitk {

/// This trampoline class is required for having python ComponentExtension derived class as 
/// ComponentExtension has four pure virtual methods
class PyComponentExtension : public camitk::ComponentExtension {
public:
    using camitk::ComponentExtension::ComponentExtension;  // inherit constructors

    virtual QString getName() const override {
        PYBIND11_OVERRIDE_PURE(
            QString,        // Return type
            camitk::ComponentExtension,   // Parent class
            getName         // Name in C++
        );
    }
    
    virtual QString getDescription() const override {
        PYBIND11_OVERRIDE_PURE(
            QString,        // Return type
            camitk::ComponentExtension,   // Parent class
            getDescription // Name in C++
        );
    }

    virtual QStringList getFileExtensions() const override {
        PYBIND11_OVERRIDE_PURE(
            QStringList,        // Return type
            camitk::ComponentExtension,   // Parent class
            getFileExtensions // Name in C++            
        );
    }

    virtual camitk::Component* open(const QString& file) override {
        PYBIND11_OVERRIDE_PURE(
            camitk::Component*,        // Return type
            camitk::ComponentExtension,   // Parent class
            open, // Name in C++
            file            // Arguments
        );
    }

    bool save(camitk::Component* component) const override {
        PYBIND11_OVERRIDE(
            bool,        // Return type
            camitk::ComponentExtension,   // Parent class
            save,        // Name of function in C++
            component        // Arguments
        );
    }

    virtual bool hasDataDirectory() const override {
        PYBIND11_OVERRIDE(
            bool,        // Return type
            camitk::ComponentExtension,   // Parent class
            hasDataDirectory        // Name of function in C++
        );
    }
};

} // namespace camitk

void add_extensionmanager_bindings(py::module_& m) {

    // --------------- ExtensionManager ---------------
    py::class_<camitk::ExtensionManager> extensionManager(m, "ExtensionManager",
        DOC(camitk_ExtensionManager));

    extensionManager.def_static("registerNewComponentExtension", &camitk::ExtensionManager::registerNewComponentExtension,
        DOC(camitk_ExtensionManager_registerNewComponentExtension));

    extensionManager.def_static("getFileExtensions", &camitk::ExtensionManager::getFileExtensions,
        DOC(camitk_ExtensionManager_getFileExtensions));

    extensionManager.def_static("getDataDirectoryExtNames", &camitk::ExtensionManager::getDataDirectoryExtNames,
        DOC(camitk_ExtensionManager_getDataDirectoryExtNames));

    // --------------- ComponentExtension ---------------

    py::class_<camitk::ComponentExtension, camitk::PyComponentExtension> componentExtension(m, "ComponentExtension",
        DOC(camitk_ComponentExtension));

    componentExtension.def(py::init<>(),DOC(camitk_ComponentExtension_ComponentExtension));

    componentExtension.def("getName", &camitk::ComponentExtension::getName,
        DOC(camitk_ComponentExtension_getName));
    
    componentExtension.def("getDescription", &camitk::ComponentExtension::getDescription,
        DOC(camitk_ComponentExtension_getDescription));
    
    componentExtension.def("getFileExtensions", &camitk::ComponentExtension::getFileExtensions,
        DOC(camitk_ComponentExtension_getFileExtensions));
    
    componentExtension.def("open", &camitk::ComponentExtension::open,
        DOC(camitk_ComponentExtension_open));
    
    componentExtension.def("save", &camitk::ComponentExtension::save,
        DOC(camitk_ComponentExtension_save));

    componentExtension.def("hasDataDirectory", &camitk::ComponentExtension::hasDataDirectory,
        DOC(camitk_ComponentExtension_hasDataDirectory));
}

