/*
 *  Open BEAGLE
 *  Copyright (C) 2001-2004 by Christian Gagne and Marc Parizeau
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *  Contact:
 *  Laboratoire de Vision et Systemes Numeriques
 *  Departement de genie electrique et de genie informatique
 *  Universite Laval, Quebec, Canada, G1K 7P4
 *  http://vision.gel.ulaval.ca
 *
 */

/*!
 *  \file   beagle/Context.hpp
 *  \brief  Definition of the class Context.
 *  \author Christian Gagne
 *  \author Marc Parizeau
 *  $Revision: 1.3 $
 *  $Date: 2004/04/25 23:12:20 $
 */

#ifndef Beagle_Context_hpp
#define Beagle_Context_hpp

#include "beagle/config.hpp"
#include "beagle/macros.hpp"
#include "beagle/Object.hpp"
#include "beagle/AllocatorT.hpp"
#include "beagle/PointerT.hpp"
#include "beagle/ContainerT.hpp"
#include "beagle/WrapperT.hpp"
#include "beagle/Genotype.hpp"
#include "beagle/Individual.hpp"
#include "beagle/Deme.hpp"
#include "beagle/Vivarium.hpp"
#include "beagle/System.hpp"
#include "beagle/Evolver.hpp"

namespace Beagle {

/*!
 *  \class Context beagle/Context.hpp "beagle/Context.hpp"
 *  \brief Evolutionary context.
 *  \ingroup ECF
 *  \ingroup Sys
 */
class Context : public Object {

public:

  //! Context allocator type.
  typedef AllocatorT<Context,Object::Alloc>
          Alloc;
  //! Context handle type.
  typedef PointerT<Context,Object::Handle>
          Handle;
  //! Context bag type.
  typedef ContainerT<Context,Object::Bag>
          Bag;

           Context();
  virtual ~Context() { }

  /*!
   *  \brief Return the continuing flag value.
   *  \return Continuing flag value.
   */
  inline bool getContinueFlag() const
  {
    return mContinueFlag;
  }

  /*!
   *  \brief Return a constant reference to the actual deme.
   *  \return Actual deme constant reference.
   */
  inline const Deme& getDeme() const
  {
    return *mDemeHandle;
  }

  /*!
   *  \brief Return a reference to the actual deme.
   *  \return Actual deme reference.
   */
  inline Deme& getDeme()
  {
    return *mDemeHandle;
  }

  /*!
   *  \brief Return a handle to the actual deme.
   *  \return Actual deme handle.
   */
  inline Deme::Handle getDemeHandle()
  {
    return mDemeHandle;
  }

  /*!
   *  \brief Return the actual deme index.
   *  \return Actual deme index.
   */
  inline unsigned int getDemeIndex() const
  {
    return mDemeIndex;
  }

  /*!
   *  \brief Return a constant reference to the actual evolver.
   *  \return Actual evolver constant reference.
   */
  inline const Evolver& getEvolver() const
  {
    return *mEvolverHandle;
  }

  /*!
   *  \brief Return a reference to the actual evolver.
   *  \return Actual evolver reference.
   */
  inline Evolver& getEvolver()
  {
    return *mEvolverHandle;
  }

  /*!
   *  \brief Return a handle to the actual evolver.
   *  \return Actual evolver handle.
   */
  inline Evolver::Handle getEvolverHandle()
  {
    return mEvolverHandle;
  }
  
  /*!
   *  \brief Return a constant reference to the actual individual.
   *  \return Actual individual constant reference.
   */
  inline const Individual& getIndividual() const
  {
    return *mIndividualHandle;
  }

  /*!
   *  \brief Return a reference to the actual individual.
   *  \return Actual individual reference.
   */
  inline Individual& getIndividual()
  {
    return *mIndividualHandle;
  }

  /*!
   *  \brief Return a handle to the actual individual.
   *  \return Actual individual handle.
   */
  inline Individual::Handle getIndividualHandle()
  {
    return mIndividualHandle;
  }

  /*!
   *  \brief Return the actual individual index.
   *  \return Actual individual index.
   */
  inline unsigned int getIndividualIndex() const
  {
    return mIndividualIndex;
  }

  /*!
   *  \brief Return a constant reference to the actual genotype.
   *  \return Actual genotype constant reference.
   */
  inline const Genotype& getGenotype() const
  {
    return *mGenotypeHandle;
  }

  /*!
   *  \brief Return a reference to the actual genotype.
   *  \return Actual genotype reference.
   */
  inline Genotype& getGenotype()
  {
    return *mGenotypeHandle;
  }

  /*!
   *  \brief Return a handle to the actual genotype.
   *  \return Actual genotype handle.
   */
  inline Genotype::Handle getGenotypeHandle()
  {
    return mGenotypeHandle;
  }

  /*!
   *  \brief Return the actual genotype index.
   *  \return Actual genotype index.
   */
  inline unsigned int getGenotypeIndex() const
  {
    return mGenotypeIndex;
  }

  /*!
   *  \brief Return the actual generation number.
   *  \return Actual generation number.
   */
  inline unsigned int getGeneration() const
  {
    return mGeneration;
  }

  /*!
   *  \return Number of individuals processed by the actual deme in this generation.
   */
  inline unsigned int getProcessedDeme() const
  {
    return mProcessedDeme;
  }

  /*!
   *  \return Total number of individuals processed by the actual deme in the evolution.
   */
  inline unsigned int getTotalProcessedDeme() const
  {
    return mTotalProcDeme;
  }

  /*!
   *  \return Number of individuals processed by the actual vivarium in this generation.
   */
  inline unsigned int getProcessedVivarium() const
  {
    return mProcessedViva;
  }

  /*!
   *  \return Total number of individuals processed by the actual vivarium in the evolution.
   */
  inline unsigned int getTotalProcessedVivarium() const
  {
    return mTotalProcViva;
  }
                  
  /*!
   *  \brief Return a constant reference to the system.
   *  \return Evolution system constant reference.
   */
  inline const System& getSystem() const
  {
    return *mSystemHandle;
  }

  /*!
   *  \brief Return a reference to the system.
   *  \return Evolution system reference.
   */
  inline System& getSystem()
  {  
    return *mSystemHandle;
  }

  /*!
   *  \brief Return a handle to the system.
   *  \return Evolution system handle.
   */
  inline System::Handle getSystemHandle()
  {
    return mSystemHandle;
  }

  /*!
   *  \brief Return a constant reference to the vivarium.
   *  \return Evolution vivarium constant reference.
   */
  inline const Vivarium& getVivarium() const
  {
    return *mVivariumHandle;
  }

  /*!
   *  \brief Return a reference to the vivarium.
   *  \return Evolution vivarium reference.
   */
  inline Vivarium& getVivarium()
  {
    return *mVivariumHandle;
  }

  /*!
   *  \brief Return a handle to the vivarium.
   *  \return Evolution vivarium handle.
   */
  inline Vivarium::Handle getVivariumHandle()
  {
    return mVivariumHandle;
  }

  /*!
   *  \brief Set the evolution continuing flag.
   *  \param inContinueFlag Continuing flag value.
   */
  inline void setContinueFlag(bool inContinueFlag)
  {
    mContinueFlag = inContinueFlag;
  }

  /*!
   *  \brief Set an handle to the actual deme.
   *  \param inDemeHandle Actual deme handle.
   */
  inline void setDemeHandle(Deme::Handle inDemeHandle)
  {
    mDemeHandle = inDemeHandle;
  }

  /*!
   *  \brief Set the actual deme index.
   *  \param inDemeIndex Actual deme index.
   */
  inline void setDemeIndex(unsigned int inDemeIndex)
  {
    mDemeIndex = inDemeIndex;
  }

  /*!
   *  \brief Set an handle to the evolver.
   *  \param inEvolverHandle Evolver handle.
   */
  inline void setEvolverHandle(Evolver::Handle inEvolverHandle)
  {
    mEvolverHandle = inEvolverHandle;
  }
  
  /*!
   *  \brief Set an handle to the actual individual.
   *  \param inIndividualHandle Actual individual handle.
   */
  inline void setIndividualHandle(Individual::Handle inIndividualHandle)
  {
    mIndividualHandle = inIndividualHandle;
  }

  /*!
   *  \brief Set the actual individual index.
   *  \param inIndividualIndex Actual individual index.
   */
  inline void setIndividualIndex(unsigned int inIndividualIndex)
  {
    mIndividualIndex = inIndividualIndex;
  }

  /*!
   *  \brief Set an handle to the actual genotype.
   *  \param inGenotypeHandle Actual genotype handle.
   */
  inline void setGenotypeHandle(Genotype::Handle inGenotypeHandle)
  {
    mGenotypeHandle = inGenotypeHandle;
  }

  /*!
   *  \brief Set the actual genotype index.
   *  \param inGenotypeIndex Actual genotype index.
   */
  inline void setGenotypeIndex(unsigned int inGenotypeIndex)
  {
    mGenotypeIndex = inGenotypeIndex;
  }

  /*!
   *  \brief Set the actual generation number.
   *  \param inGeneration Actual generation number.
   */
  inline void setGeneration(unsigned int inGeneration)
  {
    mGeneration = inGeneration;
  }

  /*!
   *  \brief Set the number of individuals processed by the deme for the actual generation.
   *  \param inProcessedDeme Number of individuals processed by the deme.
   */
  inline void setProcessedDeme(unsigned int inProcessedDeme)
  {
    mProcessedDeme = inProcessedDeme;
  }

  /*!
   *  \brief Set the total number of individuals processed by the deme for the evolution.
   *  \param inTotalProcDeme Total number of individuals processed by the deme.
   */
  inline void setTotalProcessedDeme(unsigned int inTotalProcDeme)
  {
    mTotalProcDeme = inTotalProcDeme;
  }


  /*!
   *  \brief Set the number of individuals processed by the vivarium for the actual generation.
   *  \param inProcessedViva Number of individuals processed by the vivarium.
   */
  inline void setProcessedVivarium(unsigned int inProcessedViva)
  {
    mProcessedViva = inProcessedViva;
  }

  /*!
   *  \brief Set the total number of individuals processed by the vivarium for the evolution.
   *  \param inTotalProcViva Total number of individuals processed by the vivarium.
   */
  inline void setTotalProcessedVivarium(unsigned int inTotalProcViva)
  {
    mTotalProcViva = inTotalProcViva;
  }
      
  /*!
   *  \brief Set the system handle.
   *  \param inSystemHandle Handle to the system.
   */
  inline void setSystemHandle(System::Handle inSystemHandle)
  {
    mSystemHandle = inSystemHandle;
  }

  /*!
   *  \brief Set the vivarium handle.
   *  \param inVivariumHandle Handle to the vivarium.
   */
  inline void setVivariumHandle(Vivarium::Handle inVivariumHandle)
  {
    mVivariumHandle = inVivariumHandle;
  }

protected:
  System::Handle     mSystemHandle;       //!< Handle to the system of the evolution.
  Evolver::Handle    mEvolverHandle;      //!< Handle to the evolver of the evolution.
  Vivarium::Handle   mVivariumHandle;     //!< Handle to the vivarium of the evolution.
  Deme::Handle       mDemeHandle;         //!< Handle to the actual deme of the evolution.
  unsigned int       mDemeIndex;          //!< Index of the actual deme of the evolution.
  Individual::Handle mIndividualHandle;   //!< Handle to the actual individual of the evolution.
  unsigned int       mIndividualIndex;    //!< Index of the actual individual of the evolution.
  Genotype::Handle   mGenotypeHandle;     //!< Handle to the actual genotype of the evolution.
  unsigned int       mGenotypeIndex;      //!< Index of the actual genotype of the evolution.
  unsigned int       mGeneration;         //!< Actual generation number of the evolution.
  unsigned int       mProcessedDeme;      //!< # of indiv. processed by deme during actual gen.
  unsigned int       mTotalProcDeme;      //!< Total # of indiv. processed by the deme.
  unsigned int       mProcessedViva;      //!< # of indiv. processed by vivarium during actual gen.
  unsigned int       mTotalProcViva;      //!< Total # of indiv. processed by the vivarium.
  bool               mContinueFlag;       //!< Flag set if the evolution must continue.
  
};

}

#endif // Beagle_Context_hpp
