/*************************************************************************
 *    CompuCell - A software framework for multimodel simulations of     *
 * biocomplexity problems Copyright (C) 2003 University of Notre Dame,   *
 *                             Indiana                                   *
 *                                                                       *
 * This program is free software; IF YOU AGREE TO CITE USE OF CompuCell  *
 *  IN ALL RELATED RESEARCH PUBLICATIONS according to the terms of the   *
 *  CompuCell GNU General Public License RIDER 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 2 of the   *
 *         License, or (at your option) any later version.               *
 *                                                                       *
 * This program 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 this program; if not, write to the Free Software       *
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.        *
 *************************************************************************/

#ifndef CLASSREGISTRY_H
#define CLASSREGISTRY_H

#include "Steppable.h"

#include <CompuCell3D/Viz/FieldRenderer.h>

#include <XMLCereal/XMLSerializable.h>

#include <BasicUtils/BasicClassRegistry.h>
#include <BasicUtils/BasicSmartPointer.h>

#include <map>
#include <list>
#include <string>

namespace CompuCell3D {
  class Simulator;

  class ClassRegistry : public Steppable {
    BasicClassRegistry<Steppable> steppableRegistry;
    BasicClassRegistry<FieldRenderer> rendererRegistry;

    typedef std::list<BasicSmartPointer<Steppable> > ActiveSteppers_t;
    ActiveSteppers_t activeSteppers;

    typedef std::map<std::string, BasicSmartPointer<Steppable> > ActiveSteppersMap_t;
    ActiveSteppersMap_t activeSteppersMap;

    typedef std::map<std::string, BasicSmartPointer<FieldRenderer> >
    ActiveRenderers_t;
    ActiveRenderers_t activeRenderers;

    Simulator *simulator;

  public:
    ClassRegistry(Simulator *simulator);
    virtual ~ClassRegistry() {}

    void registerSteppable(std::string id,
			  BasicClassFactoryBase<Steppable> *steppable)
    {steppableRegistry.registerFactory(steppable, id);}

    void registerRenderer(std::string id,
			BasicClassFactoryBase<FieldRenderer> *renderer)
    {rendererRegistry.registerFactory(renderer, id);}

    FieldRenderer *getRenderer(std::string id);
    
    Steppable *getStepper(std::string id);
    
    // Begin Steppable interface
    virtual void extraInit(Simulator *simulator);
    
    virtual void start();
    virtual void step(const unsigned int currentStep);
    virtual void finish();    
    // End Steppable interface

    // Begin XMLSerializable interface
    virtual void readXML(XMLPullParser &in);
    virtual void writeXML(XMLSerializer &out);
    // End XMLSerializable interface
  };
};
#endif
