/*************************************************************************
* Project: Library of Evolutionary Algoriths
*************************************************************************
* Author: Changhe Li & Ming Yang
* Email: changhe.lw@google.com Or yangming0702@gmail.com
* Language: C++
*************************************************************************
*  This file is part of EAlib. This library is free software;
*  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, or (at your option) any later version.
*************************************************************************/
// Created: 21 September 2011
// Last modified:
#ifndef INDIVIDUAL_H
#define INDIVIDUAL_H

#include "Chromosome.h"

class Individual
{
    public:
        Individual():m_id(-1),m_index(-1),m_ranking(-1){}
        virtual ~Individual() {}
        virtual void initialize(int rIdx,int rID,PopInitMethod rMethod, int rPopsize,bool mode=true){
            m_id=rID;
            m_index=rIdx;
            if(rMethod==POP_INIT_ORTHONORM){
                 m_pself.initialize(mode,rMethod,rIdx,rPopsize);
            }
            m_pself.initialize(mode);
        }
        virtual void initialize(int rIdx,int rID,bool mode=true){
            m_id=rID;
            m_index=rIdx;
            m_pself.initialize(mode);
        }
        virtual void initialize(bool mode=true){
            m_pself.initialize(mode);
        }
        virtual void initialize(Chromosome &x,int rIdx,int rID){
            m_id=rID;
            m_index=rIdx;
            m_pself=x;
        }
		virtual void initialize(Chromosome *w=0, int mode=1,bool mode2=true){
			if(w==0){
				m_pself.initialize(mode2);
			}else{
				if(mode==1){
					m_pself=*w;
				}else if(mode ==2){
					m_pself.initialize(*w,1,mode2);
				}
			}

		}
		virtual void initialize(Chromosome &p,double radius,const int rIdx,const int rID,bool mode){
            m_id=rID;
            m_index=rIdx;
            m_pself.initialize(p,radius,mode);
		}
        Individual(Individual &rIndi){
            m_pself=rIndi.m_pself;
            m_id=rIndi.m_id;
            m_index=rIndi.m_index;
            m_ranking=rIndi.m_ranking;
        }
        Individual & operator=(Individual &rIndi){
            if(this== &rIndi) return *this;
            m_pself=rIndi.m_pself;
            m_id=rIndi.m_id;
            m_index=rIndi.m_index;
            m_ranking=rIndi.m_ranking;
            return *this;
        }
        virtual void printToFile(ofstream & out){
            m_pself.printToFile(out);
        }

        virtual void increaseDimension(){
            m_pself.increaseDimension();
        }
        virtual void decreaseDimension(){
            m_pself.decreaseDimension();
        }
        virtual Chromosome & getRepresentative(){
            return m_pself;
        }
        virtual void updateMemory(){
            m_pself.evaluate(false);
        }
		virtual bool operator<=( Individual &p){
			return getRepresentative().operator<=(p.getRepresentative());
		}
		virtual bool operator>=( Individual &p){
			return getRepresentative().operator>=(p.getRepresentative());
		}
		virtual bool operator==( Individual &p){
			return getRepresentative().operator==(p.getRepresentative());
		}
		virtual bool operator<( Individual &p){
			return getRepresentative().operator<(p.getRepresentative());
		}
		virtual bool operator>( Individual &p){
			return getRepresentative().operator>(p.getRepresentative());
		}
        void setID(const int id){
            m_id=id;
        }
    public:
        Chromosome m_pself;
        int m_id,m_index;
        int m_ranking;

};

#endif // INDIVIDUAL_H
