/*
-----------------------------------------------------------------------
Copyright: 2010-2014, iMinds-Vision Lab, University of Antwerp
                2014, CWI, Amsterdam
Contact: astra@uantwerpen.be
Website: http://sf.net/projects/astra-toolbox
This file is part of the ASTRA Toolbox.
The ASTRA Toolbox 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 3 of the License, or
(at your option) any later version.
The ASTRA Toolbox 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 ASTRA Toolbox. If not, see .
-----------------------------------------------------------------------
$Id$
*/
#ifndef _INC_ASTRA_ASTRAOBJECTFACTORY
#define _INC_ASTRA_ASTRAOBJECTFACTORY
#include "Globals.h"
#include "Config.h"
#include "Singleton.h"
#include "Utilities.h"
#include "TypeList.h"
#include "ProjectorTypelist.h"
#include "AlgorithmTypelist.h"
namespace astra {
/**
 * This class contains functionality to create data objects based on their type or on a configuration object.
 */
template 
class CAstraObjectFactory : public Singleton > {
public:
	/** A default constructor that contains not a single line of code.
	 */
	CAstraObjectFactory();
	/** Destructor.  
	 */
	~CAstraObjectFactory();
	/** Create, but don't initialize, a new projector object.
	 *
	 * @param _sType Type of the new projector.
	 * @return Pointer to a new, unitialized projector.
	 */
	T* create(std::string _sType);
	/** Create and initialize a new projector object.
	 *
	 * @param _cfg Configuration object to create and initialize a new projector.
	 * @return Pointer to a new, initialized projector.
	 */
	T* create(const Config& _cfg);
};
//----------------------------------------------------------------------------------------
// Constructor
template 
CAstraObjectFactory::CAstraObjectFactory()
{
}
//----------------------------------------------------------------------------------------
// Destructor
template 
CAstraObjectFactory::~CAstraObjectFactory()
{
}
//----------------------------------------------------------------------------------------
// Create 
template 
T* CAstraObjectFactory::create(std::string _sType) 
{
	functor_find finder = functor_find();
	finder.tofind = _sType;
	CreateObject::find(finder);
	return finder.res;
}
//----------------------------------------------------------------------------------------
// Create with XML
template 
T* CAstraObjectFactory::create(const Config& _cfg)
{
	functor_find finder = functor_find();
	finder.tofind = _cfg.self->getAttribute("type");
	CreateObject::find(finder);
	if (finder.res == NULL) return NULL;
	if (finder.res->initialize(_cfg))
		return finder.res;
	delete finder.res;
	return NULL;
}
//----------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------
// Create the necessary Object Managers
/**
 * Class used to create algorithms from a string or a config object
*/
class _AstraExport CAlgorithmFactory : public CAstraObjectFactory {};
/**
 * Class used to create 2D projectors from a string or a config object
*/
class _AstraExport CProjector2DFactory : public CAstraObjectFactory {};
/**
 * Class used to create 3D projectors from a string or a config object
*/
class _AstraExport CProjector3DFactory : public CAstraObjectFactory {};
} // end namespace
#endif