// src/backend/plugin_manager.cc - Copyright 2005, 2006, University
//               of Padova, dept. of Pure and Applied
//               Mathematics
//
// This file is part of SGPEMv2.
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// SGPEMv2 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with SGPEMv2; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

#include "config.h"

#include <sgpemv2/plugin_manager.hh>
#include <sgpemv2/module.hh>
#include <sgpemv2/global_preferences.hh>

#include <sgpemv2/templates/deletor.tcc>
#include <sgpemv2/templates/singleton.tcc>

#include <glibmm/fileutils.h>
#include <glibmm/pattern.h>

#include <iostream>

using namespace sgpem;
using namespace std;

template class SG_DLLEXPORT Singleton<PluginManager>;


std::vector<Module*>
PluginManager::get_module_list() const
{
  return _modules;
}

void
PluginManager::rescan_dirs()
{
  Module* module = NULL;

  for_each(_modules.begin(), _modules.end(),
           memory::deletor<Module>());
  _modules.clear();

  GlobalPreferences& prefs = GlobalPreferences::get_instance();
  GlobalPreferences::dir_iterator it = prefs.modules_dir_begin();


  Glib::PatternSpec shared_obj(Glib::ustring("*.") + G_MODULE_SUFFIX);

  while (it != prefs.modules_dir_end())
  {
    Glib::Dir dir(*it);

    for (Glib::DirIterator dir_it = dir.begin(); dir_it != dir.end(); ++dir_it)
    {
      // only attempt to load .so files
      if (shared_obj.match(*dir_it))
      {
        std::string module_path = Module::build_path(*it, *dir_it);

        std::cerr << "Attempting to load module at path " << module_path << std::endl;

        try
        {
          module = new Module(module_path);
          _modules.push_back(module);
          std::cerr << "\tSuccess" << std::endl;
        }
        catch (InvalidPluginException e)
        {
          std::cerr << "\tFailed, invalid plugin: " << e.what() << std::endl;
        }
      }
    }

    it++;
  }
}

PluginManager::PluginManager()
{
  rescan_dirs();
}

