/**
 * @file Factory.h
 * Defines the Factory class template
 * @author Alexandre Berge
 * @version 1.0
 * @date 24/07/2009
 */
#ifndef FACTORY_H
#define FACTORY_H

#include <map>
#include <string>

template <class Object, class Key=std::string> class Factory  {
  
  public:
  void Register(Key key, Object *obj) {
    if(m_map.find(key) == m_map.end()) {
      m_map[key] = obj;  
    }
  }
  
  Object * Create(const Key& key) {
    Object * tmp = 0;
    typename std::map<Key, Object*>::iterator it = m_map.find(key);
    
    if(it != m_map.end()) 
      tmp = ((*it).second)->Clone();
    
    return tmp;
  }
  
  private:
  std::map<Key, Object *> m_map;
  
};

template  <class Object, class Key=std::string> class SingletonFactory {
  
  public:
  void Register(Key key, Object *obj) {
    if(m_map.find(key) == m_map.end()) {
      m_map[key] = obj;  
    }
  }
  
  Object * Get(const Key& key) {
    Object * tmp = 0;
    typename std::map<Key, Object*>::iterator it = m_map.find(key);
    
    if(it != m_map.end()) 
    tmp = (*it).second;
    
    return tmp;
  }

  private:
  std::map<Key, Object *> m_map;
  
};

#endif
