//
// C++ Implementation: NativePresetFactory
//
// Description: 
//
//
// Author: Carmelo Piccione <carmelo.piccione@gmail.com>, (C) 2008
//
// Copyright: See COPYING file that comes with this distribution
//
//

extern "C" {
#  include <dlfcn.h>
}

#include "NativePresetFactory.hpp"

typedef void Handle;
typedef void DestroyFunctor(Preset*);
typedef Preset * CreateFunctor(const char * url);

class LibraryPreset : public Preset {
public:
	LibraryPreset(Preset * preset, DestroyFunctor * destroyFun) : Preset(preset->name(), preset->author()), _internalPreset(preset), _destroyFunctor(destroyFun) {}
	inline Pipeline & pipeline() { return _internalPreset->pipeline(); }
	inline virtual ~LibraryPreset() { _destroyFunctor(_internalPreset); }
	inline void Render(const BeatDetect &music, const PipelineContext &context) {
		return _internalPreset->Render(music, context);
	}
private:
	Preset * _internalPreset;
	DestroyFunctor * _destroyFunctor;
};

class PresetLibrary {

	public:
		PresetLibrary(Handle * h, CreateFunctor * create, DestroyFunctor * destroy) :
			_handle(h), _createFunctor(create), _destroyFunctor(destroy) {}

		Handle * handle() { return _handle; }
		CreateFunctor * createFunctor() { return _createFunctor; }
		DestroyFunctor * destroyFunctor() { return _destroyFunctor; }

		~PresetLibrary() {
			dlclose(handle());
		}

	private:
		Handle * _handle; 
		CreateFunctor * _createFunctor;
		DestroyFunctor * _destroyFunctor;
	
};

NativePresetFactory::NativePresetFactory() {}

NativePresetFactory::~NativePresetFactory() {

for (PresetLibraryMap::iterator pos = _libraries.begin(); pos != _libraries.end(); ++pos) {
	std::cerr << "deleting preset library" << std::endl;
	delete(pos->second);
}


}

PresetLibrary * NativePresetFactory::loadLibrary(const std::string & url) {

    if (_libraries.count(url))
	return _libraries[url];

    // load the preset library
    void* handle = dlopen(url.c_str(), RTLD_LAZY);
    if (!handle) {
        std::cerr << "[NativePresetFactory] Cannot load library: " << dlerror() << '\n';
        return 0;
    }

    // reset errors
    dlerror();

    // load the symbols
    CreateFunctor * create = (CreateFunctor*) dlsym(handle, "create");
    const char * dlsym_error = dlerror();
    if (dlsym_error) {
        std::cerr << "[NativePresetFactory] Cannot load symbol create: " << dlsym_error << '\n';
        return 0;
    }

    DestroyFunctor * destroy = (DestroyFunctor*) dlsym(handle, "destroy");
    dlsym_error = dlerror();
    if (dlsym_error) {
        std::cerr << "[NativePresetFactory] Cannot load symbol destroy: " << dlsym_error << '\n';
        return 0;
    }

    std::cerr << "[NativePresetFactory] creating preset library from url " << url << std::endl;

    PresetLibrary * library = new PresetLibrary(handle, create, destroy);

    _libraries.insert(std::make_pair(url, library));
    return library;
}


std::auto_ptr<Preset> NativePresetFactory::allocate
	(const std::string & url, const std::string & name, const std::string & author) {
		
	PresetLibrary * library;
	
	if ((library = loadLibrary(url)) == 0)
		return std::auto_ptr<Preset>(0);
	
	return std::auto_ptr<Preset>(new LibraryPreset
		(library->createFunctor()(url.c_str()), library->destroyFunctor()));
		 
}
