#ifndef FITSTATEFACTORY_H
#define FITSTATEFACTORY_H
//_____________________________________________________________________________
/// \class FitStateFactory 
///
/// \brief FitStateFactory - creates FitState objects
/// 
///
/// FitStateFactory creates FitState objects. Pointers
/// to functions creating different types of FitState are in 
/// a map, keyed by names of the fitter state types. Creator
/// functions have to be registered with FSFactory using 
/// 'RegisterFitState' method, so that new types of histogram
/// blocks can be added without changing FSFactory code. FSFactory
/// is a singleton.
///
/// \author Sergei avva@fnal.gov
///
/// $Id: FitStateFactory.h,v 1.1 2006/02/04 07:14:12 avva Exp $ 

#include <string>
#include <map> 

class FitState;

class FitStateFactory { 

public:
    /// pointer to function creating fitter state  
    typedef FitState* (*FSCreator)(); 

private:
    /// map of creator function pointers keyed by name 
    typedef std::map<std::string, FSCreator> CallbackMap; 
    typedef std::map<std::string, FitState*> StateMap;
    
public:

    /// get reference to the FSFactory singleton  
    static  FitStateFactory&      Instance();
    
    /// create fitter state given its name 
    FitState* GetFitState(const std::string& fitStateId); 
    FitState* GetFitState(const char* fitStateId); 
    
    
    /// Returns 'true' if registration was successful 
    bool    RegisterFitState      (const std::string& FitStateId,
                                        FSCreator creator); 
    
    /// Returns 'true' if the FitStateId was registered before 
    bool    UnregisterFitState    (const std::string& FitStateId);
    

    
private: 
    static FitStateFactory* fInstance;
    CallbackMap fCallbacks; 
    StateMap    fFitStates;
    
    /// create fitter state given its name 
    FitState* CreateFitState(const std::string& FitStateId); 
    /// Those are private    
    FitStateFactory();
    FitStateFactory(const FitStateFactory&);
    //FitStateFactory& operator=(const FitStateFactory&); 
    //~FitStateFactory();
    
}; // class FitStateFactory

#endif
