/**
 * @file
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 *
 * This file is part of The iWear Framework.
 *
 * The iWear Framework 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 as in version 2 of the License.

 * 
 * The iWear Framework 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
 * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


#ifndef __IWEAR_PLUGIN_HANDLE_H
#define __IWEAR_PLUGIN_HANDLE_H

#ifndef __IWEAR_EXCEPTIONS_H
#include <iwear/exceptions.h>
#endif

extern "C" {
#include <dlfcn.h>
}
    
#include <list>
using std::list;

namespace iwear
{
struct plugin_descriptor
{
    plugin_descriptor( ) : func_ptr(NULL),func_name(NULL) {}
    plugin_descriptor( void** fp, const char * fn) : func_ptr(fp), func_name(fn) {}
    template<class T> plugin_descriptor( T** fp, const char * fn) 
	: func_ptr(reinterpret_cast<void**>(reinterpret_cast<void(**)()>(fp))), 
	func_name(fn) {}
    void** func_ptr;
    const char * func_name;
//    inline bool operator !=  ( const plugin_descriptor& pd) const { return func_ptr == pd.func_ptr; }
};

class PluginHandle
{
private:
protected:
   void * handle; 
public:
   PluginHandle();
   virtual ~PluginHandle();
   /**
    * This library name will directly be passed to the dlopen call. So if you
    * want a special directory to be searched for, you need to assemble the
    * full absolute path yourself.
    * @note This will try to load all functions and check for the
    * IWEAR_VERSION_CODE and if the code is not the same as the running
    * application this will throw a version_error exception.
    */
    void load_from( const string& libname );

    list<plugin_descriptor> desc_list;
};
}
#endif
