#ifndef __PARAMETERS_H_
#define __PARAMETERS_H_

#include "Definitions.h"

class Parameters {
  private:
    static Parameters *instance;

    static const AlleleType maxAlleleTypeValue;
    static const unsigned int maxUnsignedIntValue;

    unsigned int n;
    AlleleType* a;
    unsigned int sumA;
    AlleleType maxA;
    FloatType rho;
    FloatType epsilon;
    FloatType convergenceThreshold;
    int p;
    int rank;
    int delta;
    FloatType mu;
    unsigned int gamma;
    unsigned int epochX;
    unsigned int epochY;
    unsigned int epochGenerationLimit;
    unsigned int intervalUpdateParameters;
    unsigned int intervalCheckEpoch;
    unsigned int intervalStoppingLocal;
    unsigned int intervalStoppingGlobal;

    Parameters();
    ~Parameters();
    unsigned int ceilDiv( unsigned int divisor, unsigned int dividend );

  public:
    static Parameters * getInstance();
    static void deleteInstance();

    void updateParameters( bool newEpoch );

    void setNA( unsigned int numberOfGenes, const AlleleType * const numberOfAlleles );
    unsigned int getN() const;
    AlleleType getA( unsigned int locus ) const;
    unsigned int getSumA() const;
    AlleleType getMaxA() const;
    void setRho( const FloatType &value );
    FloatType getRho() const;
    void setEpsilon( const FloatType& value );
    FloatType getEpsilon() const;
    void setConvergenceThreshold( const FloatType& value );
    FloatType getConvergenceThreshold() const;

    void setP( int value );
    int getP() const;
    void setRank( int value );
    int getRank() const;
    void setDelta( int value );
    int getDelta() const;
    void setMu( const FloatType& value );
    FloatType getMu() const;
    void setGamma( unsigned int value );
    unsigned int getGamma() const;
    void setEpochX( unsigned int value );
    unsigned int getEpochX() const;
    void setEpochY( unsigned int value );
    unsigned int getEpochY() const;
    void setEpochGenerationLimit( unsigned int value );
    unsigned int getEpochGenerationLimit() const;

    void setIntervalUpdateParameters( unsigned int value );
    unsigned int getIntervalUpdateParameters() const;
    void setIntervalCheckEpoch( unsigned int value );
    unsigned int getIntervalCheckEpoch() const;
    void setIntervalStoppingLocal( unsigned int value );
    unsigned int getIntervalStoppingLocal() const;
    void setIntervalStoppingGlobal( unsigned int value );
    unsigned int getIntervalStoppingGlobal() const;
};

#endif /* __PARAMETERS_H_ */
