/*************************************************************************
* Project:
* Function:
*************************************************************************
* : Changhe Li $
* : changhe.lw@google.com $
*************************************************************************
*
* Copyright 2011 by China University of Geoscience
*
************************************************************************/

#ifndef CHROMOSOME_H
#define CHROMOSOME_H

#include "../ToolnDef/Global.h"

using namespace std;

class Chromosome{
    public:
        static unsigned int ms_objNumbers;
        unsigned int mc_length;
        static SolutionValidation ms_validationMode;
    private:
        double * mp_obj;
        //can take composite encoding scheme,e.g., A b 1.23 ! & true 59 ....
        Gene * mp_gene;

    public:

    Chromosome();
	Chromosome(const Chromosome &);
	//Chromosome(Chromosome &);
    ~Chromosome();
    void evaluate(const bool rFlag=true);
    void allocateMemory(Gene * rGene,const int rLength);
    void freeMemory();
    void initialize(const bool mode=true,PopInitMethod rMethod=POP_INIT_UNIFORM,const int rIndex=0,const int rSize=0);
    void initialize( Chromosome & rhs,double radius=1,bool mode=true);
    template <typename T>
    T* operator[](const int i){
        return ((T*) mp_gene[i].mp_value);
    }

    template <typename T>
    T& getGene(const int i, const int j=0){
        return ((T*) mp_gene[i].mp_value)[j];
    }
    Gene & getGene(const int idx){
        return mp_gene[idx];
    }

    Chromosome& operator=( Chromosome& rhs);
    //better than or equal to p
    bool operator>=(const Chromosome &p);
    //worse than or equal to p
    bool operator<=(const Chromosome &p);
    //worse than p
    bool operator<(const Chromosome &p);
    //better than p
    bool operator>(const Chromosome &p);
    bool operator>(const double obj);
    bool operator>(const double *obj);
    //equal to p
    bool operator==( Chromosome &p);
    // not eqaul to p
    bool operator!=( Chromosome &p);
    double getObj(int const i=0);
    bool isValid();
    double getDistance( Chromosome & rhs,DistanceMode mode=DIS_EUCLIDEAN);
    double getDistance(double * loc);
    void increaseDimension();
    void decreaseDimension();

    void printToScreen();
    void printToFile(ofstream &out);

    void validate();

};

#endif // CHROMOSOME_H
