// ****************************************************************************
//
//          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/>.
//
// ****************************************************************************


#ifndef AEVOL_RNA_H_
#define AEVOL_RNA_H_

#include <cstdint>

#include <list>
#include <vector>

#include "macros.h"
#include "Promoter.h"
#include "Strand.h"
#include "utils.h"

namespace aevol {

class Protein;

class Rna {
 public:
 /*
  RNA Constructor
  */
  Rna() = delete;
  Rna(Promoter* promoter, int32_t length, int32_t dna_size);
  Rna(const Rna&) = delete;
  ~Rna() = default;

  auto promoter_pos() const { return begin_; }
  auto first_transcribed_pos() const { return first_transcribed_pos_; }
  auto end() const { return end_; }
  auto strand() const { return strand_; }
  auto expression_level() const { return e_; }
  const auto& rbs_positions() const { return rbs_positions_; }
  const auto& protein_list() const { return protein_list_; }
  auto length() const { return length_; }
  auto is_coding() const { return is_coding_; }
  const auto* promoter() const { return prom_; }

  void add_rbs(Dna::size_type pos) { rbs_positions_.push_back(pos); }
  void add_protein(const Protein* protein) {
    protein_list_.push_back(protein);
    is_coding_ = true;
  }

  void clear_rbs_list() { rbs_positions_.clear(); }

 protected:
  int32_t begin_ = -1; /**< position of the promoter */
  int32_t first_transcribed_pos_ = -1; /**< position of the first transcribed position (= base right after promoter) */
  int32_t end_ = -1; /**< position of the last base of the terminator */
  Strand strand_;
  double e_ = -1.0; /**< expression level */
  std::list<int32_t> rbs_positions_;
  std::list<const Protein*> protein_list_;
  int32_t length_           = -1; /**< length of the RNA (including terminator; not including promoter) */
  bool is_coding_ = false;
  Promoter* prom_ = nullptr;
};

}

#endif  // AEVOL_RNA_H_
