#include <dlfcn.h>
/* -- */
#include <iostream>
#include <string>
/* -- */
#include <QAction>
#include <QApplication>
#include <QButtonGroup>
#include <QHBoxLayout>
#include <QTabWidget>
#include <QWidget>
#include <QDir>
/* -- */
#include "Plugin.hpp"
#include "PluginWindow.hpp"

using namespace std;

PluginWindow::PluginWindow() : _current_index(0) {
    _layout = new QVBoxLayout();
    _tab_widget = new QTabWidget();
    _execute_button = new QPushButton("Execute");
    _layout->addWidget(_tab_widget);
    _layout->addWidget(_execute_button);
    setLayout(_layout);

    setMinimumSize(800, 600);
    connect(_tab_widget, SIGNAL(currentChanged(int)), this, SLOT(init_plugin(int)));
    connect(_execute_button, SIGNAL(clicked()), this, SLOT(execute_plugin()));

    load_shared_plugins();

    // TODO load "compulsory" plugins (stats for example)
    // Make a link to the menu to open the good tab if possible (menu Preferences->Plugins->...) where ... is the plugin we want to load

    // mainWindow->fillPluginMenu(list<QString> names);
}

PluginWindow::~PluginWindow() {
    for(unsigned int i = 0 ; i < _plugins.size() ; i ++) {
        delete _plugins[i];
        _plugins[i] = NULL;
    }
    _plugins.clear();
}

void PluginWindow::load_shared_plugins() {
    QDir dir(".", "*.so"); /* directory name : ., filter : *.so */
    dir.setFilter(QDir::Files);
    
    QFileInfoList list = dir.entryInfoList();

    for (int i = 0 ; i < list.size() ; ++ i) {
        QFileInfo fileInfo = list.at(i);
        string filename = fileInfo.absoluteFilePath().toStdString();
        /* Loading of a plugin under Linux platforms */
        void *h = dlopen(filename.c_str(), RTLD_LAZY);
        if(!h) {
            cerr << dlerror() << endl;
        }
        else {
            Plugin *(*f)(void) = (Plugin *(*)(void)) dlsym(h, "create");
            if(!f) {
                cerr << "Unable to load " << filename << " because " << dlerror() << endl;
            }
            else {
                Plugin *plug = f();
                add_plugin(plug);
            }
        }
    }
}

void PluginWindow::add_plugin(Plugin *plug) {
    _plugins.push_back(plug);
    _tab_widget->addTab(plug, QString::fromStdString(plug->get_name()));
}

void PluginWindow::init_plugin(int index) {
    //_plugins[_current_index].unload();
    if(index < (int)_plugins.size()) {
        _plugins[index]->init();
        _current_index = index;
    }
}

void PluginWindow::execute_plugin() {
    if(_current_index > (int)_plugins.size() || (_current_index == 0 && _plugins.size() == 0)
)
        return;
    _plugins[_current_index]->execute();
}

void PluginWindow::load_list() {
//     QSettings settings("ViTE", "ViTE");
//     QStringList list = settings.value("pluginsList").toStringList();
//     for(QStringList::const_iterator i = list.begin() ; i != list.end() ; ++ i) {
//         load_plugin((*i).toStdString());
//     }
}

void PluginWindow::load_plugin(const string &plugin_name) {
    Plugin *plug = Plugin::new_instance(plugin_name);
    if(!plug) {
        cerr << "plugin " << plugin_name << " not found" << endl;
        return;
    }
    add_plugin(plug);

//     // To save/add a plugin in the settings
//     QSettings settings("ViTE", "ViTE");
//     QStringList plugin_list = settings.value("pluginsList").toStringList();
//     settings.setValue("recentFiles", files);
//     plugin_list.removeAll(filename);
//     plugin_list.prepend(filename);
//     settings.setValue("pluginsList", files);
}
