/*************************************************************************
 *    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 SIMULATOR_H
#define SIMULATOR_H

#include "PluginManager.h"
#include "Steppable.h"
#include <map>
#include <CompuCell3D/Potts3D/Potts3D.h>

#include <XMLCereal/XMLSerializable.h>

namespace CompuCell3D {
  class ClassRegistry;
   template <typename Y> class Field3DImpl;
  
  class Simulator : public Steppable {
    unsigned int numSteps;

    double flip2DimRatio;

    double temperature;

    ClassRegistry *classRegistry;

    Potts3D potts;

    int currstep;

    unsigned int anneal;
    bool simulatorIsStepping;
    std::map<std::string,Field3DImpl<float>*> concentrationFieldNameMap;
    
  public:
    static PluginManager pluginManager;

    Simulator();
    virtual ~Simulator();
    PluginManager::plugins_t & getPluginMap(){return pluginManager.getPluginMap();}
    unsigned int getNumSteps() {return numSteps;}
    int getStep() {return currstep;}
    bool isStepping(){return simulatorIsStepping;}
    Potts3D *getPotts() {return &potts;}
    ClassRegistry *getClassRegistry() {return classRegistry;}
    void registerConcentrationField(std::string _name,Field3DImpl<float>* _fieldPtr);
    std::map<std::string,Field3DImpl<float>*> & getConcentrationFieldNameMap(){
      return concentrationFieldNameMap;
    }
    
    
    // Begin Steppable interface
    virtual void start();
    virtual void extraInit();///initialize plugins after all steppables have been initialized
    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
