text: /* Distributed under the Apache License, Version 2.0.
     See accompanying NOTICE file for details.*/
  
  #pragma once
  #include "Controller/System.h"
  #include "system/physiology/SERenalSystem.h"
  #include "utils/RunningAverage.h"
  #include "properties/SEScalarMass.h"
  
  class SEUrinalysis;
  
  
  
  /**
   * @brief @copydoc Physiology_RenalSystemData
   */  
  class PULSE_DECL Renal : public SERenalSystem, public PulseSystem
  {
    friend PulseController;
    friend class PulseEngineTest;
  protected:
    Renal(PulseController& data);
    PulseController& m_data;
  
    double m_dt;
    
  public:
    virtual ~Renal();
  
    void Clear();
  
    // Set members to a stable homeostatic state
    void Initialize();
  
    static void Load(const pulse::RenalSystemData& src, Renal& dst);
    static pulse::RenalSystemData* Unload(const Renal& src);
  protected:
    static void Serialize(const pulse::RenalSystemData& src, Renal& dst);
    static void Serialize(const Renal& src, pulse::RenalSystemData& dst);
  
    // Set pointers and other member varialbes common to both homeostatic initialization and loading a state
    void SetUp();
  
  public:
    void AtSteadyState();
    void PreProcess();  
    void Process();  
    void PostProcess();
  
    // Assessments
    bool CalculateUrinalysis(SEUrinalysis& u);
  
  protected:
  
    struct ActiveTransport
    {
    public:
      double leftGlucoseReabsorptionMass_mg;
      double rightGlucoseReabsorptionMass_mg;
      double leftLactateExcretedMass_mg;
      double rightLactateExcretedMass_mg;
    };
  
  
    // Initialization
    void CalculateFilterability(SESubstance& sub);
    //Conditions
    void ConsumeMeal(double elapsedTime_s);
  
    //Preprocess
    void CalculateUltrafiltrationFeedback();
    void   CalculateColloidOsmoticPressure(SEScalarMassPerVolume& albuminConcentration, SEScalarPressure& osmoticPressure);
    void CalculateReabsorptionFeedback();
    void   CalculateOsmoreceptorFeedback();
    void   CalculateFluidPermeability();
    void CalculateTubuloglomerularFeedback();  
    void UpdateBladderVolume();
    void ProcessActions();
    void   Urinate();
  
    //Process
    void CalculateActiveTransport();  
    void   CalculateGlomerularTransport(SESubstance& sub);
    void   CalculateReabsorptionTransport(SESubstance& sub);
    void   CalculateSecretion();
    void   CalculateExcretion(SESubstance& sub);
    void   CalculateAutomaticClearance(SESubstance& sub);
    void   CalculateGluconeogenesis();
    void CalculateVitalSigns();
  
    // Serializable member variables (Set in Initialize and in schema)
    bool   m_Urinating;
    //Tubuloglomerular Feedback
    double m_leftAfferentResistance_mmHg_s_Per_mL;
    double m_rightAfferentResistance_mmHg_s_Per_mL;
    double m_leftSodiumFlowSetPoint_mg_Per_s;
    double m_rightSodiumFlowSetPoint_mg_Per_s;
    //Events
    RunningAverage m_urineProductionRate_mL_Per_min_runningAvg;
    RunningAverage m_urineOsmolarity_mOsm_Per_L_runningAvg;
    RunningAverage m_sodiumConcentration_mg_Per_mL_runningAvg;
    RunningAverage m_sodiumExcretionRate_mg_Per_min_runningAvg;
    RunningAverage m_leftSodiumFlow_mg_Per_s_runningAvg;
    RunningAverage m_rightSodiumFlow_mg_Per_s_runningAvg;
    RunningAverage m_leftRenalArterialPressure_mmHg_runningAvg;
    RunningAverage m_rightRenalArterialPressure_mmHg_runningAvg;
    
    // Stateless member variable (Set in SetUp())
    SEPatient*          m_patient;
    //Circuits
    SEFluidCircuit*     m_RenalCircuit;
    //Nodes
    SEFluidCircuitNode* m_leftGlomerularNode;
    SEFluidCircuitNode* m_leftBowmansNode;
    SEFluidCircuitNode* m_leftPeritubularNode;
    SEFluidCircuitNode* m_leftTubulesNode;
    SEFluidCircuitNode* m_leftRenalArteryNode;
    SEFluidCircuitNode* m_rightGlomerularNode;
    SEFluidCircuitNode* m_rightBowmansNode;
    SEFluidCircuitNode* m_rightPeritubularNode;
    SEFluidCircuitNode* m_rightTubulesNode;
    SEFluidCircuitNode* m_rightRenalArteryNode;
    SEFluidCircuitNode* m_bladderNode;
    SEFluidCircuitNode* m_leftNetGlomerularCapillariesNode;
    SEFluidCircuitNode* m_leftNetBowmansCapsulesNode;
    SEFluidCircuitNode* m_leftNetPeritubularCapillariesNode;
    SEFluidCircuitNode* m_leftNetTubulesNode;
    SEFluidCircuitNode* m_rightNetGlomerularCapillariesNode;
    SEFluidCircuitNode* m_rightNetBowmansCapsulesNode;
    SEFluidCircuitNode* m_rightNetPeritubularCapillariesNode;
    SEFluidCircuitNode* m_rightNetTubulesNode;
    //Paths
    SEFluidCircuitPath* m_leftGlomerularOsmoticSourcePath;
    SEFluidCircuitPath* m_leftBowmansOsmoticSourcePath;
    SEFluidCircuitPath* m_leftReabsorptionResistancePath;
    SEFluidCircuitPath* m_leftTubulesOsmoticSourcePath;
    SEFluidCircuitPath* m_leftPeritubularOsmoticSourcePath;
    SEFluidCircuitPath* m_leftUreterPath;
    SEFluidCircuitPath* m_leftGlomerularFilterResistancePath;
    SEFluidCircuitPath* m_leftAfferentArteriolePath;
    SEFluidCircuitPath* m_rightReabsorptionResistancePath;
    SEFluidCircuitPath* m_rightGlomerularOsmoticSourcePath;
    SEFluidCircuitPath* m_rightBowmansOsmoticSourcePath;
    SEFluidCircuitPath* m_rightTubulesOsmoticSourcePath;
    SEFluidCircuitPath* m_rightPeritubularOsmoticSourcePath;
    SEFluidCircuitPath* m_rightUreterPath;
    SEFluidCircuitPath* m_rightGlomerularFilterResistancePath;
    SEFluidCircuitPath* m_rightAfferentArteriolePath;
    SEFluidCircuitPath* m_bladderToGroundPressurePath;
    SEFluidCircuitPath* m_urethraPath;
    SEFluidCircuitPath* m_leftTubulesPath;
    SEFluidCircuitPath* m_rightTubulesPath;
    SEFluidCircuitPath* m_leftEfferentArteriolePath;
    SEFluidCircuitPath* m_rightEfferentArteriolePath;
   
    //Substances
    SESubstance* m_sodium;
    SESubstance* m_urea;
    SESubstance* m_glucose;
    SESubstance* m_lactate;
    SESubstance* m_potassium;
    //Compartments
    SELiquidCompartment* m_aorta;
    SELiquidCompartment* m_venaCava;
    SELiquidCompartment* m_bladder;
    SETissueCompartment* m_rightKidneyTissue;
    SETissueCompartment* m_leftKidneyTissue;  
    SELiquidCompartment* m_leftUreter;
    SELiquidCompartment* m_leftPeritubular;
    SELiquidCompartment* m_rightUreter;
    SELiquidCompartment* m_rightPeritubular;  
    SELiquidCompartment* m_leftGlomerular;
    SELiquidCompartment* m_leftBowmans;
    SELiquidCompartment* m_rightGlomerular;
    SELiquidCompartment* m_rightBowmans;
    SELiquidCompartment* m_leftTubules;
    SELiquidCompartment* m_rightTubules;
    SELiquidCompartment* m_ground;
    // Compartment Substance Quantites
    SELiquidSubstanceQuantity* m_aortaLactate;
  
    SELiquidSubstanceQuantity* m_leftPeritubularGlucose;
    SELiquidSubstanceQuantity* m_leftPeritubularPotassium;
    SELiquidSubstanceQuantity* m_leftUreterPotassium;
    SELiquidSubstanceQuantity* m_leftUreterLactate;
  
    SELiquidSubstanceQuantity* m_rightPeritubularGlucose;
    SELiquidSubstanceQuantity* m_rightPeritubularPotassium;
    SELiquidSubstanceQuantity* m_rightUreterPotassium;
    SELiquidSubstanceQuantity* m_rightUreterLactate;
  
    SELiquidSubstanceQuantity* m_bladderGlucose;
    SELiquidSubstanceQuantity* m_bladderPotassium;
    SELiquidSubstanceQuantity* m_bladderSodium;
    SELiquidSubstanceQuantity* m_bladderUrea;
    SELiquidSubstanceQuantity* m_leftTubulesSodium;
    SELiquidSubstanceQuantity* m_rightTubulesSodium;
  
    SELiquidSubstanceQuantity* m_leftKidneyIntracellularLactate;
    SELiquidSubstanceQuantity* m_rightKidneyIntracellularLactate;
  
    // Configuration 
    double m_defaultOpenResistance_mmHg_s_Per_mL;
    double m_defaultClosedResistance_mmHg_s_Per_mL;
    //   Ultrafiltration
    double m_CVOpenResistance_mmHg_s_Per_mL;
    //   Tubuloglomerular Feedback
    double m_maxLeftAfferentResistance_mmHg_s_Per_mL;
    double m_minLeftAfferentResistance_mmHg_s_Per_mL;
    double m_maxRightAfferentResistance_mmHg_s_Per_mL;
    double m_minRightAfferentResistance_mmHg_s_Per_mL;
    //   Osmoreceptor Feedback
    double m_leftReabsorptionPermeabilityModificationFactor;
    double m_rightReabsorptionPermeabilityModificationFactor;
    double m_sodiumPlasmaConcentrationSetpoint_mg_Per_mL;
    //   Secretion
    double m_baselinePotassiumConcentration_g_Per_dL;
    //   Reabsorption
    double m_leftReabsorptionPermeabilitySetpoint_mL_Per_s_mmHg_m2;
    double m_rightReabsorptionPermeabilitySetpoint_mL_Per_s_mmHg_m2;
  
    // Utility/ScratchPads
    SEScalarMass m_spCleared;
    ActiveTransport m_SubstanceTransport;
  };
  