// ****************************************************************************
//
//          Aevol - An in silico experimental evolution platform
//
// ****************************************************************************
//
// Copyright: See the AUTHORS file provided with the package or <www.aevol.fr>
// Web: http://www.aevol.fr/
// E-mail: See <http://www.aevol.fr/contact/>
// Original Authors : Guillaume Beslon, Carole Knibbe, David Parsons
//
// This program 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 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, see <http://www.gnu.org/licenses/>.
//
// ****************************************************************************

#include "AA_2_MWH_Value_Mapping.h"

#include "AminoAcid.h"
#include "utils/utility.h"

namespace aevol_4b {

AA_2_MWH_Value_Mapping::AA_2_MWH_Value_Mapping() {
  for(int8_t i = 0; i < NB_AMINO_ACIDS; i++) {
    aa_base_m_[i] = -1;
    aa_base_w_[i] = -1;
    aa_base_h_[i] = -1;
  }

  // randomly generated no epistasis code

  aa_base_m_[std::to_underlying(AminoAcid::ARGININE)] = 2;
  aa_base_m_[std::to_underlying(AminoAcid::ASPARAGINE)] = 4;
  aa_base_m_[std::to_underlying(AminoAcid::ASPARTIC_ACID)] = 5;
  aa_base_m_[std::to_underlying(AminoAcid::GLUTAMIC_ACID)] = 6;
  aa_base_m_[std::to_underlying(AminoAcid::GLUTAMINE)] = 0;
  aa_base_m_[std::to_underlying(AminoAcid::HISTIDINE)] = 1;
  aa_base_m_[std::to_underlying(AminoAcid::SERINE)] = 3;

  aa_base_w_[std::to_underlying(AminoAcid::ALANINE)] = 5;
  aa_base_w_[std::to_underlying(AminoAcid::CYSTEINE)] = 0;
  aa_base_w_[std::to_underlying(AminoAcid::ISOLEUCINE)] = 4;
  aa_base_w_[std::to_underlying(AminoAcid::LEUCINE)] = 3;
  aa_base_w_[std::to_underlying(AminoAcid::THREONINE)] = 1;
  aa_base_w_[std::to_underlying(AminoAcid::PHENYLALANINE)] = 2;

  aa_base_h_[std::to_underlying(AminoAcid::GLYCINE)] = 3;
  aa_base_h_[std::to_underlying(AminoAcid::METHIONINE)] = 2;
  aa_base_h_[std::to_underlying(AminoAcid::LYSINE)] = 5;
  aa_base_h_[std::to_underlying(AminoAcid::PROLINE)] = 6;
  aa_base_h_[std::to_underlying(AminoAcid::TRYPTOPHAN)] = 1;
  aa_base_h_[std::to_underlying(AminoAcid::TYROSINE)] = 4;
  aa_base_h_[std::to_underlying(AminoAcid::VALINE)] = 0;

  /*
  aa_base_x_[ALANINE] = ;
  aa_base_x_[ARGININE] = ;
  aa_base_x_[ASPARAGINE] = ;
  aa_base_x_[ASPARTIC_ACID] = ;
  aa_base_x_[CYSTEINE] = ;
  aa_base_x_[GLUTAMIC_ACID] = ;
  aa_base_x_[GLUTAMINE] = ;
  aa_base_x_[GLYCINE] = ;
  aa_base_x_[HISTIDINE] = ;
  aa_base_x_[ISOLEUCINE] = ;
  aa_base_x_[LEUCINE] = ;
  aa_base_x_[LYSINE] = ;
  aa_base_x_[METHIONINE] = ;
  aa_base_x_[PHENYLALANINE] = ;
  aa_base_x_[PROLINE] = ;
  aa_base_x_[SERINE] = ;
  aa_base_x_[THREONINE] = ;
  aa_base_x_[TRYPTOPHAN] = ;
  aa_base_x_[TYROSINE] = ;
  aa_base_x_[VALINE] = ;
 */

  // GB 07/01/22 randomly generated full code

  // aa_base_m_[ALANINE] = 9;
  // aa_base_m_[ARGININE] = 2;
  // aa_base_m_[ASPARAGINE] = 4;
  // aa_base_m_[ASPARTIC_ACID] = 5;
  // aa_base_m_[CYSTEINE] = 14;
  // aa_base_m_[GLUTAMIC_ACID] = 6;
  // aa_base_m_[GLUTAMINE] = 0;
  // aa_base_m_[GLYCINE] = 16;
  // aa_base_m_[HISTIDINE] = 1;
  // aa_base_m_[ISOLEUCINE] = 17;
  // aa_base_m_[LEUCINE] = 19;
  // aa_base_m_[LYSINE] = 11;
  // aa_base_m_[METHIONINE] = 10;
  // aa_base_m_[PHENYLALANINE] = 12;
  // aa_base_m_[PROLINE] = 15;
  // aa_base_m_[SERINE] = 3;
  // aa_base_m_[THREONINE] = 8;
  // aa_base_m_[TRYPTOPHAN] = 7;
  // aa_base_m_[TYROSINE] = 13;
  // aa_base_m_[VALINE] = 18;

  // aa_base_w_[ALANINE] = 5;
  // aa_base_w_[ARGININE] = 0;
  // aa_base_w_[ASPARAGINE] = 7;
  // aa_base_w_[ASPARTIC_ACID] = 4;
  // aa_base_w_[CYSTEINE] = 13;
  // aa_base_w_[GLUTAMIC_ACID] = 15;
  // aa_base_w_[GLUTAMINE] = 10;
  // aa_base_w_[GLYCINE] = 12;
  // aa_base_w_[HISTIDINE] = 19;
  // aa_base_w_[ISOLEUCINE] = 11;
  // aa_base_w_[LEUCINE] = 3;
  // aa_base_w_[LYSINE] = 1;
  // aa_base_w_[METHIONINE] = 18;
  // aa_base_w_[PHENYLALANINE] = 14;
  // aa_base_w_[PROLINE] = 8;
  // aa_base_w_[SERINE] = 17;
  // aa_base_w_[THREONINE] = 6;
  // aa_base_w_[TRYPTOPHAN] = 2;
  // aa_base_w_[TYROSINE] = 9;
  // aa_base_w_[VALINE] = 16;

  // aa_base_h_[ALANINE] = 13;
  // aa_base_h_[ARGININE] = 3;
  // aa_base_h_[ASPARAGINE] = 2;
  // aa_base_h_[ASPARTIC_ACID] = 15;
  // aa_base_h_[CYSTEINE] = 14;
  // aa_base_h_[GLUTAMIC_ACID] = 10;
  // aa_base_h_[GLUTAMINE] = 7;
  // aa_base_h_[GLYCINE] = 9;
  // aa_base_h_[HISTIDINE] = 8;
  // aa_base_h_[ISOLEUCINE] = 17;
  // aa_base_h_[LEUCINE] = 12;
  // aa_base_h_[LYSINE] = 5;
  // aa_base_h_[METHIONINE] = 19;
  // aa_base_h_[PHENYLALANINE] = 16;
  // aa_base_h_[PROLINE] = 6;
  // aa_base_h_[SERINE] = 18;
  // aa_base_h_[THREONINE] = 11;
  // aa_base_h_[TRYPTOPHAN] = 1;
  // aa_base_h_[TYROSINE] = 4;
  // aa_base_h_[VALINE] = 0;


  /* Standard code
aa_base_m_[PHENYLALANINE] = 0;  // 2
  aa_base_m_[LEUCINE] = 1;        // 6
  aa_base_m_[ISOLEUCINE] = 2;     // 3+1
  aa_base_m_[METHIONINE] = 2;
  aa_base_m_[VALINE] = 3;         // 4
  aa_base_m_[SERINE] = 4;         // 6
                                // TOTAL = 2+6+4+4+6 = 22

  aa_base_w_[PROLINE] = 0;        // 4
  aa_base_w_[THREONINE] = 1;      // 4
  aa_base_w_[ALANINE] = 2;        // 4
  aa_base_w_[TYROSINE] = 3;       // 2+2
  aa_base_w_[HISTIDINE] = 3;
  aa_base_w_[GLUTAMINE] = 4;      // 2+2
  aa_base_w_[ASPARAGINE] = 4;
  aa_base_w_[LYSINE] = 5;         // 2
                                // TOTAL = 4+4+4+4+4+2 = 22

  aa_base_h_[ASPARAGINE] = 0;     // 2+2
  aa_base_h_[LYSINE] = 0;
  aa_base_h_[ASPARTIC_ACID] = 1;  // 2+2+2
  aa_base_h_[CYSTEINE] = 1;
  aa_base_h_[GLUTAMIC_ACID] = 1;
  aa_base_h_[TRYPTOPHAN] = 2;     // 1+4
  aa_base_h_[ARGININE] = 3;       // 4
  aa_base_h_[GLYCINE] = 4;        // 4
                                // TOTAL = 4+6+5+4+4 = 23
				*/
  // Compute bases sizes
  aa_base_m_size_ = 0;
  aa_base_w_size_ = 0;
  aa_base_h_size_ = 0;

  for(int8_t i = 0; i < NB_AMINO_ACIDS; i++) {
    if(aa_base_m_[i] > aa_base_m_size_)
      aa_base_m_size_ = aa_base_m_[i];

    if(aa_base_w_[i] > aa_base_w_size_)
      aa_base_w_size_ = aa_base_w_[i];

    if(aa_base_h_[i] > aa_base_h_size_)
      aa_base_h_size_ = aa_base_h_[i];
  }
  aa_base_m_size_++; // base_size = max_digit + 1
  aa_base_w_size_++;
  aa_base_h_size_++;
}

void AA_2_MWH_Value_Mapping::reset_aa_base_m(const int8_t *base_m) {
  aa_base_m_size_ = 0;
  for(int8_t i = 0; i < NB_AMINO_ACIDS; i++) {
    aa_base_m_[i] = base_m[i];

    if(base_m[i] > aa_base_m_size_)
      aa_base_m_size_ = base_m[i];
  }
  aa_base_m_size_++; // base_size = base_max + 1
}

void AA_2_MWH_Value_Mapping::reset_aa_base_w(const int8_t *base_w) {
  aa_base_w_size_ = 0;
  for(int8_t i = 0; i < NB_AMINO_ACIDS; i++) {
    aa_base_w_[i] = base_w[i];

    if(base_w[i] > aa_base_w_size_)
      aa_base_w_size_ = base_w[i];
  }
  aa_base_w_size_++; // base_size = base_max + 1
}

void AA_2_MWH_Value_Mapping::reset_aa_base_h(const int8_t *base_h) {
  aa_base_h_size_ = 0;
  for(int8_t i = 0; i < NB_AMINO_ACIDS; i++) {
    aa_base_h_[i] = base_h[i];

    if(base_h[i] > aa_base_h_size_)
      aa_base_h_size_ = base_h[i];
  }
  aa_base_h_size_++; // base_size = base_max + 1
}

}  // namespace aevol_4b
