#ifndef TTR_DEFINITIONS
#define TTR_DEFINITIONS
#include <enum_functions.hpp>
#include <string.h>

//-- parameters to the model --
// DO NOT ASSIGN VALUES TO ENUM ITEMS
// KEEP COUNT LAST
// ENTER NEW ENUM ITEMS INTO NAMES ARRAY

// SH replaced constexpr with inline constexpr

enum class AlphaParameter{
  //alpha
  LC_bsum_1,
  LC_bsum_2,
  AET_bsum_1,
  AET_bsum_2,
  COUNT
};

template <>
inline constexpr EnumNames<AlphaParameter> enum_names<AlphaParameter>{
  "LC_bsum_1",
  "LC_bsum_2",
  "AET_bsum_1",
  "AET_bsum_2",
};

enum class BetaParameter{
  //beta
  CU_tcur_1,
  CU_tcur_2,
  CU_tcur_3,
  CU_tcur_4,
  CU_ppfd_1,
  CU_ppfd_2,
  CU_swc_1,
  CU_swc_2,
  CU_Ns_1,
  CU_Ns_2,
  NU_tnur_1,
  NU_tnur_2,
  NU_Nsoil_1,
  NU_Nsoil_2,
  NU_swc_1,
  NU_swc_2,
  NU_swc_3,
  NU_swc_4,
  g_tgrowth_1,
  g_tgrowth_2,
  g_tgrowth_3,
  g_tgrowth_4,
  g_swc_1,
  g_swc_2,
  r_tloss_1,
  r_tloss_2,
  L_tloss_1,
  L_tloss_2,
  L_swc_1,
  L_swc_2,
  phen_t_0,
  phen_t_1,
  phen_t_2,
  phen_t_3,
  phen_t_4,
  L_fire_1,
  L_fire_2,
  L_mix_1,
  L_mix_2,
  L_mix_3,
  iM,
  //process error
  pe_Ms,
  pe_Mr,
  pe_Cs,
  pe_Cr,
  pe_Ns,
  pe_Nr,
  COUNT
};

template <>
inline constexpr EnumNames<BetaParameter> enum_names<BetaParameter>{
  "CU_tcur_1",
  "CU_tcur_2",
  "CU_tcur_3",
  "CU_tcur_4",
  "CU_ppfd_1",
  "CU_ppfd_2",
  "CU_swc_1",
  "CU_swc_2",
  "CU_Ns_1",
  "CU_Ns_2",
  "NU_tnur_1",
  "NU_tnur_2",
  "NU_Nsoil_1",
  "NU_Nsoil_2",
  "NU_swc_1",
  "NU_swc_2",
  "NU_swc_3",
  "NU_swc_4",
  "g_tgrowth_1",
  "g_tgrowth_2",
  "g_tgrowth_3",
  "g_tgrowth_4",
  "g_swc_1",
  "g_swc_2",
  "r_tloss_1",
  "r_tloss_2",
  "L_tloss_1",
  "L_tloss_2",
  "L_swc_1",
  "L_swc_2",
  "phen_t_0",
  "phen_t_1",
  "phen_t_2",
  "phen_t_3",
  "phen_t_4",
  "L_fire_1",
  "L_fire_2",
  "L_mix_1",
  "L_mix_2",
  "L_mix_3",
  "iM",
  //process error
  "pe_Ms",
  "pe_Mr",
  "pe_Cs",
  "pe_Cr",
  "pe_Ns",
  "pe_Nr"
};

//abbreviation for code, these are used a lot in ttr_support_functions.hpp
using APar = AlphaParameter;
using BPar = BetaParameter;

//-- variables which are inputs to the model --
//these are all independent of species

//input variables which are timeseries per site
enum class TimeSeries{
  tcur,
  tnur,
  tgrowth,
  tloss,
  ppfd,
  swc,
  prec,
  pet,
  C3p,
  C4p,
  fire,
  COUNT
};

template <>
inline constexpr EnumNames<TimeSeries> enum_names<TimeSeries>{
  "tcur",
  "tnur",
  "tgrowth",
  "tloss",
  "ppfd",
  "swc",
  "prec",
  "pet",
  "C3p",
  "C4p",
  "fire"
};

//time-independent variables per site
enum class TimeInvariant{
  wp,
  fc,
  nsoil,
  COUNT
};

template <>
inline constexpr EnumNames<TimeInvariant> enum_names<TimeInvariant>{
  "wp",
  "fc",
  "nsoil"
};

//time- and site-independent variables
enum class Global{
  mmax,
  gmax,
  KM,
  CUmax,
  NUmax,
  KA,
  Jc,
  Jn,
  q,
  RHOc,
  RHOn,
  Fc,
  Fn,
  COUNT
};

template <>
inline constexpr EnumNames<Global> enum_names<Global>{
  "mmax",
  "gmax",
  "KM",
  "CUmax",
  "NUmax",
  "KA",
  "Jc",
  "Jn",
  "q",
  "RHOc",
  "RHOn",
  "Fc",
  "Fn"
};

//Simulation State
enum class State{
  Ms,
  Mr,
  Cs,
  Cr,
  Ns,
  Nr,
  COUNT
};

template <>
inline constexpr EnumNames<State> enum_names<State>{
  "Ms",
  "Mr",
  "Cs",
  "Cr",
  "Ns",
  "Nr"
};

//-- biotic variables to be calculated --
//depend on time, site and species
enum class Biotic{
  Ms,
  Mr,
  Cs,
  Cr,
  Ns,
  Nr,
  TAUc,
  TAUn,
  Uc,
  Un,
  Gs,
  Gr,
  Ms_loss,
  Mr_loss,
  CUR,
  NUR,
  g,
  loss,
  COUNT
};

template <>
inline constexpr EnumNames<Biotic> enum_names<Biotic>{
  "Ms",
  "Mr",
  "Cs",
  "Cr",
  "Ns",
  "Nr",
  "TAUc",
  "TAUn",
  "Uc",
  "Un",
  "Gs",
  "Gr",
  "Ms_loss",
  "Mr_loss",
  "CUR",
  "NUR",
  "g",
  "loss"
};

//-- options --
//the variants of the model
enum class TTRVariant{
  std,
  red,
  fqr,
  oak,
  COUNT
};

template <>
inline constexpr EnumNames<TTRVariant> enum_names<TTRVariant>{
  "std",
  "red",
  "fqr",
  "oak"
};

//the global photosynthesis type to use
enum class PhotoType{
  c3,
  c4,
  COUNT
};

template <>
inline constexpr EnumNames<PhotoType> enum_names<PhotoType>{
  "c3",
  "c4",
};

enum class p4{
  Vcmax25,
  Jmax25,
  Jscale,
  Vpmax25,
  ps2a25,
  ps2b25,
  ps2c25,
  x,
  alpha,
  Vpr,
  Kc25,
  Ko25,
  Kp25,
  Sco25,
  gbs25,
  Rd25,
  a025,
  EVcmax,
  EJmax,
  ToptVcmax,
  ToptJmax,
  HVcmax,
  HJmax,
  EVpmax,
  Eps2a,
  Eps2b,
  Eps2c,
  EKc,
  EKo,
  EKp,
  ESco,
  Egbs,
  Toptgbs,
  Hgbs,
  ERd,
  Ea0,
  z,
  m,
  b,
  g0,
  g1,
  bb,
  COUNT
};

template <>
inline constexpr EnumNames<p4> enum_names<p4>{
  "Vcmax25",
  "Jmax25",
  "Jscale",
  "Vpmax25",
  "ps2a25",
  "ps2b25",
  "ps2c25",
  "x",
  "alpha",
  "Vpr",
  "Kc25",
  "Ko25",
  "Kp25",
  "Sco25",
  "gbs25",
  "Rd25",
  "a025",
  "EVcmax",
  "EJmax",
  "ToptVcmax",
  "ToptJmax",
  "HVcmax",
  "HJmax",
  "EVpmax",
  "Eps2a",
  "Eps2b",
  "Eps2c",
  "EKc",
  "EKo",
  "EKp",
  "ESco",
  "Egbs",
  "Toptgbs",
  "Hgbs",
  "ERd",
  "Ea0",
  "z",
  "m",
  "b",
  "g0",
  "g1",
  "bb"
};

enum class p3{
  Vcmax25,
  Jmax25,
  Jscale,
  ps2a25,
  ps2b25,
  ps2c25,
  Kc25,
  Ko25,
  Gstar25,
  gm25,
  Rd25,
  EVcmax,
  EJmax,
  ToptVcmax,
  ToptJmax,
  HVcmax,
  HJmax,
  Eps2a,
  Eps2b,
  Eps2c,
  EKc,
  EKo,
  EGstar,
  Egm,
  Toptgm,
  Hgm,
  ERd,
  m,
  b,
  g0,
  g1,
  bb,
  COUNT
};

template <>
inline constexpr EnumNames<p3> enum_names<p3>{
  "Vcmax25",
  "Jmax25",
  "Jscale",
  "ps2a25",
  "ps2b25",
  "ps2c25",
  "Kc25",
  "Ko25",
  "Gstar25",
  "gm25",
  "Rd25",
  "EVcmax",
  "EJmax",
  "ToptVcmax",
  "ToptJmax",
  "HVcmax",
  "HJmax",
  "Eps2a",
  "Eps2b",
  "Eps2c",
  "EKc",
  "EKo",
  "EGstar",
  "Egm",
  "Toptgm",
  "Hgm",
  "ERd",
  "m",
  "b",
  "g0",
  "g1",
  "bb"
};

#endif //TTR_DEFINITIONS
