#include "InflowsToSurfaceCalc.h"
#include <iostream>


void InflowsToSurfaceCalc::InflowsToSurfacePervious(Inputs *input, CompactRagged* beC, int MapPixel_ID, int DataFolder_ID, int timeStep)
{
	//Irrigation_ImperviousDepressionStorage_m reset to zero at each entry to function
	beC->by_key(MapPixel_ID, DataFolder_ID, "Irrigation_PerviousDepressionStorage_m") = 0;

	//If (Precipitation_RainSnowMelt_underTreeCanopy_m + Precipitation_RainSnowMelt_underSVegCanopy_m + Precipitation_RainSnowMelt_noCanopy_m + Flux_Impervious_to_Pervious_m) <= 0 and ...
	//... Storage_PerviousPondedWater_m <= 0 and ...
	//... StorageDeficit_FieldCapacity_SoilEvapZone_m < StorageDeficit_FieldCapacity_SoilEvapZone_Max_m ...
	//... then enter to consider irrigation scenario
	//Note: Irrigation should only occur when no precipitation or runon is occuring
	if (
		Inputs::isLessThanOrAlmostEqual(beC->by_key(MapPixel_ID, DataFolder_ID, "Precipitation_RainSnowMelt_underTreeCanopy_m") + beC->by_key(MapPixel_ID, DataFolder_ID, "Precipitation_RainSnowMelt_underSVegCanopy_m") + beC->by_key(MapPixel_ID, DataFolder_ID, "Precipitation_RainSnowMelt_noCanopy_m") + beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_Impervious_to_Pervious_m"), 0) &&
		Inputs::isLessThanOrAlmostEqual(beC->by_key(MapPixel_ID, DataFolder_ID, "Storage_PerviousPondedWater_m"), 0) &&
		Inputs::isLessThan(beC->by_key(MapPixel_ID, DataFolder_ID, "StorageDeficit_FieldCapacity_SoilEvapZone_m"),beC->by_key(MapPixel_ID, DataFolder_ID, "StorageDeficit_FieldCapacity_SoilEvapZone_Max_m")))
		{
		//Flag_Scenario_CoolAir_Irrigate_str = to_string(input->SimulationScenarios["Flag_Scenario_CoolAir_Irrigate"])
		string Flag_Scenario_CoolAir_Irrigate_str = to_string(input->SimulationScenarios["Flag_Scenario_CoolAir_Irrigate"]);
		//If input->isReferenceStationPixel(MapPixel_ID) is false and ...
		//... Model_Selection is SpatialTemperatureHydro and ...
		//... Flag_Scenario_CoolAir_Irrigate is for 3 or 5, Pervious
		if (!input->isReferenceStationPixel(MapPixel_ID) &&
			input->SimulationStringParams["Model_Selection"] == "SpatialTemperatureHydro" &&
			(Flag_Scenario_CoolAir_Irrigate_str.find('3') != string::npos ||
				Flag_Scenario_CoolAir_Irrigate_str.find('5') != string::npos)) {

			//LandCoverType = "PerviousCover"
			string LandCoverType = "PerviousCover";
			//Flag_IsAppropriateLandCover = input->IsAppropriateLandCoverForScenario(MapPixel_ID,Scenario_CoolAir_Irrigate_LandCover_Class)
			//Note: Determine whether to suppress irrigation based on land cover rule
			bool Flag_IsAppropriateLandCover = input->IsAppropriateLandCoverForScenario(MapPixel_ID, input->SimulationScenarios["Scenario_CoolAir_Irrigate_LandCover_Class"]);

			//Flag_IsAppropriateDay_or_Night = input->IsAppropriateDay_or_NightForScenario(timeStep, ElevationAngle_Solar_rad,Scenario_CoolAir_Irrigate_Day_or_Night)
			//Note: Determine whether to allow irrigation for the Day or Night rule; 0=day and night; 1=day; 2=night
			bool Flag_IsAppropriateDay_or_Night = input->IsAppropriateDay_or_NightForScenario(timeStep, beC->by_key(MapPixel_ID, DataFolder_ID, "ElevationAngle_Solar_rad"), input->SimulationScenarios["Scenario_CoolAir_Irrigate_Day_or_Night"]);

			//Flag_IsAppropriateTimesPerDay = input->IsAppropriateTimesPerDay(MapPixel_ID, SimulationDate_YYYYMMDD, LandCoverType, Scenario_CoolAir_Irrigate_MaxPerDay)
			//Note: Determine count of irrigation for each distinct MapPixel, Date, and land cover type
			bool Flag_IsAppropriateTimesPerDay = input->IsAppropriateTimesPerDay(MapPixel_ID, input->SimulationDate_YYYYMMDD[timeStep], LandCoverType, input->SimulationScenarios["Scenario_CoolAir_Irrigate_MaxPerDay"]);

			//If Flag_IsAppropriateLandCover & Flag_IsAppropriateDay_or_Night & Flag_IsAppropriateTimesPerDay = true then appropriate conditions scenario
			if (Flag_IsAppropriateLandCover && Flag_IsAppropriateDay_or_Night && Flag_IsAppropriateTimesPerDay) {

				//Tair_K intialized
				double Tair_K;
				//If !beC->has_var("Tair_K"); checks if beC->by_key(MapPixel_ID, DataFolder_ID, "Tair_K") initialized after timeStep 1
				if (!beC->has_var("Tair_K")) {
					//Tair_K = input->Tair_C for reference station, converted to K
					Tair_K = input->Tair_C[timeStep] + 273.15;
				}
				//Else Tair_K initialized
				else {
					//Tair_K = beC->by_key(MapPixel_ID, DataFolder_ID, "Tair_K") defined for folder
					Tair_K = beC->by_key(MapPixel_ID, DataFolder_ID, "Tair_K");
				}

				//If Scenario_CoolAir_Irrigate_Tair_K < Tair_K then enter for irrigation scenario
				if (Inputs::isLessThanOrAlmostEqual(input->SimulationScenarios["Scenario_CoolAir_Irrigate_Tair_K"], Tair_K)) {

					//DepressionStorageDepth_fraction (frac) is defined by default as 1.0 of total storage
					double DepressionStorageDepth_fraction = 1.0;
					//Irrigated_frac (frac) initialized to 1.0
					double Irrigated_frac = 1.0;
					//If input->map_Irrigation_Area_frac.size() > 0 then redefine 
					if (input->map_Irrigation_Area_frac.size() > 0) { 
						//Irrigated_frac = input->map_Irrigation_Area_frac[MapPixel_ID]
						Irrigated_frac = input->map_Irrigation_Area_frac[MapPixel_ID];
					}

					//Irrigation_PerviousDepressionStorage_m is DepressionStorageDepth_fraction * Storage_PerviousPondedWater_Max_m * Irrigated_frac
					//Note: Scenario activated to provide cooling
					beC->by_key(MapPixel_ID, DataFolder_ID, "Irrigation_PerviousDepressionStorage_m") = DepressionStorageDepth_fraction * beC->by_key(MapPixel_ID, DataFolder_ID, "Storage_PerviousPondedWater_Max_m") * Irrigated_frac;

					//If Irrigation_PerviousDepressionStorage_m > StorageDeficit_FieldCapacity_SoilEvapZone_m then set it equal to the available storage deficit
					//Note: Conditional ensures irrigation will fill capillary storage and not result in gravitational drainage
					if (Inputs::isGreaterThan(beC->by_key(MapPixel_ID, DataFolder_ID, "Irrigation_PerviousDepressionStorage_m"), beC->by_key(MapPixel_ID, DataFolder_ID, "StorageDeficit_FieldCapacity_SoilEvapZone_m"))) {
						//Irrigation_PerviousDepressionStorage_m = StorageDeficit_FieldCapacity_SoilEvapZone_m
						beC->by_key(MapPixel_ID, DataFolder_ID, "Irrigation_PerviousDepressionStorage_m") = beC->by_key(MapPixel_ID, DataFolder_ID, "StorageDeficit_FieldCapacity_SoilEvapZone_m");
					}
					//input->IncreaseTimesPerDay(MapPixel_ID, input->SimulationDate_YYYYMMDD[timeStep], LandCoverType); increases irrigation count
					input->IncreaseTimesPerDay(MapPixel_ID, input->SimulationDate_YYYYMMDD[timeStep], LandCoverType);
				}
			}
		}
	}//End Scenario
	
	//Note: Multiplication of variables by fractional area below is to adjust depths from one analysis area to entire folder area
	//Rationale: 1. variables arrive as depths for an analysis area (e.g., pervious area)
	//Rationale: 2. multiplying these depths by their analysis area gives a volume, which is conserved when transfered between different areas
	//Rationale: 3. multiplying these depths by their fractional area is equivalent to multiplying by their analysis area and dividing by the folder area, getting depth for folder area
	//Note: Multiplication is equivalent to multiplying by ratio of analysis area to folder area to convert from /analysis_area to /folder_area

	//Note: Division of variables by fractional area below is to adjust depths from entire folder area to one analysis area
	//Rationale: 1. variables arrive as depths for the entire folder area
	//Rationale: 2. multiplying these depths by the folder area gives a volume
	//Rationale: 3. dividing these depths by the analysis area is equivalent to multiplying by the folder area and dividing by the analysis area, getting depth for analysis area
	//Note: Division is equivalent to multiplying by ratio of folder area to analysis area to convert from /folder_area to /analysis_area

	// 1st: Summing 3 fractional area contributions, each adjusted to depth over folder area (e.g., bulk area) by multiplying by folder area fraction in analysis area
	//Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m (m) is folder area depth and equals Precipitation_RainSnowMelt_underTreeCanopy_m * TreeCanopyCover_overPervious_frac (fraction)
	//Note: Precipitation_RainSnowMelt_underTreeCanopy_m is cover area depth, multiplying by TreeCanopyCover_overPervious_frac (fraction) converts to folder area depth
	beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m") = beC->by_key(MapPixel_ID, DataFolder_ID, "Precipitation_RainSnowMelt_underTreeCanopy_m") * beC->by_key(MapPixel_ID, DataFolder_ID, "TreeCanopyCover_overPervious_frac");
	//Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m (m) is folder area depth and increased by Precipitation_RainSnowMelt_underSVegCanopy_m * ShortVegCover_noTreeCanopy_frac
	//Note: Precipitation_RainSnowMelt_underSVegCanopy_m (m) is cover area depth, multiplying by ShortVegCover_noTreeCanopy_frac (fraction) equals folder area depth
	beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m") = beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m") + beC->by_key(MapPixel_ID, DataFolder_ID, "Precipitation_RainSnowMelt_underSVegCanopy_m") * beC->by_key(MapPixel_ID, DataFolder_ID, "ShortVegCover_noTreeCanopy_frac");
	//Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m (m) is folder area depth and increased by Precipitation_RainSnowMelt_noCanopy_m (m) * (SoilCover_noTreeCanopy_frac + PermeablePavementCover_noTreeCanopy_frac)
	//Note: Precipitation_RainSnowMelt_noCanopy_m (m) is cover area depth, multiplying by (SoilCover_noTreeCanopy_frac + PermeablePavementCover_noTreeCanopy_frac) (fraction) equals folder area depth
	beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m") = beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m") + beC->by_key(MapPixel_ID, DataFolder_ID, "Precipitation_RainSnowMelt_noCanopy_m") * (beC->by_key(MapPixel_ID, DataFolder_ID, "SoilCover_noTreeCanopy_frac") + beC->by_key(MapPixel_ID, DataFolder_ID, "PermeablePavementCover_noTreeCanopy_frac"));

	// 2nd: Adding Irrigation
	//Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m (m) is folder area depth and increased by Irrigation_PerviousDepressionStorage_m (m) * PerviousCover_frac (fraction)
	//Note: Irrigation_PerviousDepressionStorage_m (m) is cover area depth, multiplying by PerviousCover_frac (fraction) converts to folder area depth
	beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m") = beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m") + beC->by_key(MapPixel_ID, DataFolder_ID, "Irrigation_PerviousDepressionStorage_m") * beC->by_key(MapPixel_ID, DataFolder_ID, "PerviousCover_frac");

	// 3rd: Adjusting Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m becomes pervious area depth (m) with division by PerviousCover_frac to convert from folder depth to cover type depth 
	//Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m (m) adjusted to pervious area depth by division with PerviousCover_frac
	//Note: Division is equivalent to multiplying by ratio of folder area to analysis area to convert from /folder_area to /analysis_area
	//Note: Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m (m) arrives as folder area depth by above multiplication w/ SoilCover_noTreeCanopy_frac, ShortVegCover_noTreeCanopy_frac, PermeablePavementCover_noTreeCanopy_frac, etc.
	//Note: PerviousCover_frac = fraction of watershed with tree cover on pervious area + fraction of watershed with ShortVeg cover + bare soil area
	beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m") = input->SafeDivide(beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m"), beC->by_key(MapPixel_ID, DataFolder_ID, "PerviousCover_frac"));

	// 4th: Adjusting Flux_Impervious_to_Pervious_m to pervious area depth (m) with division by PerviousCover_frac
	//Flux_Impervious_to_Pervious_m (m) remains folder depth, but added on RHS as pervious area depth by division with PerviousCover_frac
	//Note: Division is equivalent to multiplying by ratio of folder area to analysis area to convert from /folder_area to /analysis_area
	//Note: Flux_Impervious_to_Pervious_m (m) arrives as folder area depth by earlier multiplication w/ ImperviousCover_DrainsToPervious_frac in ImperviousDepressionStorageCalc.cpp
	//Note: Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_ImpRunon_m (m) represents pervious area depth in functors for infiltration
	beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_ImpRunon_m") = beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_m") +
		input->SafeDivide(beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_Impervious_to_Pervious_m"), beC->by_key(MapPixel_ID, DataFolder_ID, "PerviousCover_frac"));

	// Storing Flux_to_PerviousArea_Rain_SnowMelt_Irrigation_ImpRunon_m as waterToPerArea, with impervious area runon included
	if (beC->by_key_str(MapPixel_ID, DataFolder_ID, "Type") == "BulkArea") {

		//Flux_to_GI_PerviousArea_BARunon_m (m) defined as zero for BA
		beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_GI_PerviousArea_BARunon_m") = 0.0;
	}
	//If Type not BulkArea then divide by PerviousCover_frac for transfer of water from BulkArea to GI infiltration
	//Note: Consider refactor to pass this water to GI infiltration from Inflow_StormwaterDevice.cpp
	if (beC->by_key_str(MapPixel_ID, DataFolder_ID, "Type") != "BulkArea") {

		//PerviousCover_m2 (m2) is product of GI Area_m2 and PerviousCover_frac; Area_m2 is area of all GI units in DataFolder
		double PerviousCover_m2 = beC->by_key(MapPixel_ID, DataFolder_ID, "Area_m2") * beC->by_key(MapPixel_ID, DataFolder_ID, "PerviousCover_frac");

		//Flux_to_GI_PerviousArea_BARunon_m (m) goes to functors["calculateInfiltration"] 
		//Note: Flux_to_GI_PerviousArea_BARunon_m is sum of BulkArea transfers to GI, scaled from folder volume to pervious area depth
		//Note: All BulkArea transfers to GI presumed to go to GI pervious area, regardless of GI ImperviousCover_frac
		beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_GI_PerviousArea_BARunon_m") = input->SafeDivide((input->RepoDict["Runoff_Impervious_BAtoGI_m3"] +
			input->RepoDict["Runoff_SatExcess_BAtoGI_m3"] + input->RepoDict["Runoff_InfilExcess_BAtoGI_m3"]),
			PerviousCover_m2);
	}
}

void InflowsToSurfaceCalc::InflowsToSurfaceImpervious(Inputs *input, CompactRagged* beC, int MapPixel_ID, int DataFolder_ID, int timeStep)
{
	//Irrigation_ImperviousDepressionStorage_m reset to zero at each entry to function
	beC->by_key(MapPixel_ID, DataFolder_ID, "Irrigation_ImperviousDepressionStorage_m") = 0.0;
	//Initialize variable
	beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m") = 0.0;

	//If (Precipitation_RainSnowMelt_underTreeCanopy_m + Precipitation_RainSnowMelt_noCanopy_m) <= 0 and ...
	//... Storage_PerviousPondedWater_m <= 0 then enter to consider irrigation scenario
	//Note: Irrigation should only occur when no precipitation or runon is occuring
	if (Inputs::isLessThanOrAlmostEqual(beC->by_key(MapPixel_ID, DataFolder_ID, "Precipitation_RainSnowMelt_underTreeCanopy_m") + beC->by_key(MapPixel_ID, DataFolder_ID, "Precipitation_RainSnowMelt_noCanopy_m"),0) && Inputs::isLessThanOrAlmostEqual(beC->by_key(MapPixel_ID, DataFolder_ID, "Storage_ImperviousPondedWater_m"),0)) {

		//Flag_Scenario_CoolAir_Irrigate_str = to_string(input->SimulationScenarios["Flag_Scenario_CoolAir_Irrigate"])
		string Flag_Scenario_CoolAir_Irrigate_str = to_string(input->SimulationScenarios["Flag_Scenario_CoolAir_Irrigate"]);
		//If input->isReferenceStationPixel(MapPixel_ID) is false and ...
		//... Model_Selection is SpatialTemperatureHydro and ...
		//... Flag_Scenario_CoolAir_Irrigate is for 4 or 5, Impervious
		if (!input->isReferenceStationPixel(MapPixel_ID) &&
			input->SimulationStringParams["Model_Selection"] == "SpatialTemperatureHydro" &&
			(Flag_Scenario_CoolAir_Irrigate_str.find('4') != string::npos ||
				Flag_Scenario_CoolAir_Irrigate_str.find('5') != string::npos)) {

			//LandCoverType = "ImperviousCover"
			string LandCoverType = "ImperviousCover";
			//Flag_IsAppropriateLandCover = input->IsAppropriateLandCoverForScenario(MapPixel_ID,Scenario_CoolAir_Irrigate_LandCover_Class)
			//Note: Determine whether to suppress irrigation based on land cover rule
			bool Flag_IsAppropriateLandCover = input->IsAppropriateLandCoverForScenario(MapPixel_ID, input->SimulationScenarios["Scenario_CoolAir_Irrigate_LandCover_Class"]);

			//Flag_IsAppropriateDay_or_Night = input->IsAppropriateDay_or_NightForScenario(timeStep, ElevationAngle_Solar_rad,Scenario_CoolAir_Irrigate_Day_or_Night)
			//Note: Determine whether to allow irrigation for the Day or Night rule; 0=day and night; 1=day; 2=night
			bool Flag_IsAppropriateDay_or_Night = input->IsAppropriateDay_or_NightForScenario(timeStep, beC->by_key(MapPixel_ID, DataFolder_ID, "ElevationAngle_Solar_rad"), input->SimulationScenarios["Scenario_CoolAir_Irrigate_Day_or_Night"]);

			//Flag_IsAppropriateTimesPerDay = input->IsAppropriateTimesPerDay(MapPixel_ID, SimulationDate_YYYYMMDD, LandCoverType, Scenario_CoolAir_Irrigate_MaxPerDay)
			//Note: Determine count of irrigation for each distinct MapPixel, Date, and land cover type
			bool Flag_IsAppropriateTimesPerDay = input->IsAppropriateTimesPerDay(MapPixel_ID, input->SimulationDate_YYYYMMDD[timeStep], LandCoverType, input->SimulationScenarios["Scenario_CoolAir_Irrigate_MaxPerDay"]);

			//If Flag_IsAppropriateLandCover & Flag_IsAppropriateDay_or_Night & Flag_IsAppropriateTimesPerDay = true then appropriate conditions scenario
			if (Flag_IsAppropriateLandCover && Flag_IsAppropriateDay_or_Night && Flag_IsAppropriateTimesPerDay) {

				//Tair_K intialized
				double Tair_K;
				//If !beC->has_var("Tair_K"); checks if beC->by_key(MapPixel_ID, DataFolder_ID, "Tair_K") initialized after timeStep 1
				if (!beC->has_var("Tair_K")) {
					//Tair_K = input->Tair_C for reference station, converted to K
					Tair_K = input->Tair_C[timeStep] + 273.15;
				}
				//Else Tair_K initialized
				else {
					//Tair_K = beC->by_key(MapPixel_ID, DataFolder_ID, "Tair_K") defined for folder
					Tair_K = beC->by_key(MapPixel_ID, DataFolder_ID, "Tair_K");
				}

				//If Scenario_CoolAir_Irrigate_Tair_K < Tair_K then enter for irrigation scenario
				if (Inputs::isLessThanOrAlmostEqual(input->SimulationScenarios["Scenario_CoolAir_Irrigate_Tair_K"], Tair_K)) {

					//DepressionStorageDepth_fraction (frac) is defined by default as 1.0 of total storage
					double DepressionStorageDepth_fraction = 1.0;
					//Irrigated_frac (frac) initialized to 1.0
					double Irrigated_frac = 1.0;
					//If input->map_Irrigation_Area_frac.size() > 0 then redefine 
					if (input->map_Irrigation_Area_frac.size() > 0) {
						//Irrigated_frac = input->map_Irrigation_Area_frac[MapPixel_ID]
						Irrigated_frac = input->map_Irrigation_Area_frac[MapPixel_ID];
					}

					//Irrigation_ImperviousDepressionStorage_m is DepressionStorageDepth_fraction * Storage_ImperviousPondedWater_Max_m * Irrigated_frac
					//Note: Scenario activated to provide cooling
					beC->by_key(MapPixel_ID, DataFolder_ID, "Irrigation_ImperviousDepressionStorage_m") = DepressionStorageDepth_fraction * beC->by_key(MapPixel_ID, DataFolder_ID, "Storage_ImperviousPondedWater_Max_m") * Irrigated_frac;
					//input->IncreaseTimesPerDay(MapPixel_ID, input->SimulationDate_YYYYMMDD[timeStep], LandCoverType); increases irrigation count
					input->IncreaseTimesPerDay(MapPixel_ID, input->SimulationDate_YYYYMMDD[timeStep], LandCoverType);
				}
			}
		}
	}//End Scenario

	//Note: Multiplication of variables by fractional area below is to adjust depths from one analysis area to entire folder area
	//Rationale: 1. variables arrive as depths for an analysis area (e.g., pervious area)
	//Rationale: 2. multiplying these depths by their analysis area gives a volume, which is conserved when transfered between different areas
	//Rationale: 3. multiplying these depths by their fractional area is equivalent to multiplying by their analysis area and dividing by the folder area, getting depth for folder area
	//Note: Multiplication is equivalent to multiplying by ratio of analysis area to folder area to convert from /analysis_area to /folder_area

	//Note: Division of variables by fractional area below is to adjust depths from entire folder area to one analysis area
	//Rationale: 1. variables arrive as depths for the entire folder area
	//Rationale: 2. multiplying these depths by the folder area gives a volume
	//Rationale: 3. dividing these depths by the analysis area is equivalent to multiplying by the folder area and dividing by the analysis area, getting depth for analysis area
	//Note: Division is equivalent to multiplying by ratio of folder area to analysis area to convert from /folder_area to /analysis_area

	//Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m (m) is folder area depth and equals Precipitation_RainSnowMelt_underTreeCanopy_m (m) * TreeCanopyCover_overImpervious_frac (fraction)
	//Note: Precipitation_RainSnowMelt_underTreeCanopy_m (m) is cover area depth, multiplying by TreeCanopyCover_overImpervious_frac (fraction) converts to folder area depth
	beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m") = beC->by_key(MapPixel_ID, DataFolder_ID, "Precipitation_RainSnowMelt_underTreeCanopy_m") * beC->by_key(MapPixel_ID, DataFolder_ID, "TreeCanopyCover_overImpervious_frac");

	//Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m (m) is folder area depth and increased by Precipitation_RainSnowMelt_noCanopy_m (m) * ImperviousCover_noTreeCanopy_frac (fraction)
	//Note: Precipitation_RainSnowMelt_noCanopy_m (m) is cover area depth, multiplying by ImperviousCover_noTreeCanopy_frac (fraction) converts to folder area depth
	beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m") = beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m") + beC->by_key(MapPixel_ID, DataFolder_ID, "Precipitation_RainSnowMelt_noCanopy_m") * beC->by_key(MapPixel_ID, DataFolder_ID, "ImperviousCover_noTreeCanopy_frac");
		
	//Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m (m) is folder area depth and increased by Irrigation_ImperviousDepressionStorage_m (m) * ImperviousCover_frac (fraction)
	//Note: Irrigation_ImperviousDepressionStorage_m (m) is cover area depth, multiplying by ImperviousCover_frac (fraction) converts to folder area depth
	beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m") = beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m") + beC->by_key(MapPixel_ID, DataFolder_ID, "Irrigation_ImperviousDepressionStorage_m") * beC->by_key(MapPixel_ID, DataFolder_ID, "ImperviousCover_frac");

	//Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m (m) becomes impervious area depth (m) when divided by ImperviousCover_frac (fraction) to convert from folder depth to cover type depth 
	//Note: For BulkArea with no GI, Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m (m) will have the fraction DCIA sent to outlet 
	//Note: For BulkArea with GI, Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m (m) may have a fraction of DCIA sent to GI
	//Note: For GI, Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m (m) may have DCIA send flow to outlet, or retain flux for GI processing
	beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m") = input->SafeDivide(beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_ImperviousArea_Rain_SnowMelt_Irrigation_m"), beC->by_key(MapPixel_ID, DataFolder_ID, "ImperviousCover_frac"));
}

//Note: Function could be simplified to remove multiplication followed by division, yet ...
//Note: ... these steps allow elaboration of water cover types as in FluxToImpervious and FluxToPervious
void InflowsToSurfaceCalc::InflowsToSurfaceWater(Inputs *input, CompactRagged* beC, int MapPixel_ID, int DataFolder_ID, int timeStep)
{
	//Note: Multiplication of variables by fractional area below is to adjust depths from one analysis area to entire folder area
	//Rationale: 1. variables arrive as depths for an analysis area (e.g., pervious area)
	//Rationale: 2. multiplying these depths by their analysis area gives a volume, which is conserved when transfered between different areas
	//Rationale: 3. multiplying these depths by their fractional area is equivalent to multiplying by their analysis area and dividing by the folder area, getting depth for folder area
	//Note: Multiplication is equivalent to multiplying by ratio of analysis area to folder area to convert from /analysis_area to /folder_area

	//Note: Division of variables by fractional area below is to adjust depths from entire folder area to one analysis area
	//Rationale: 1. variables arrive as depths for the entire folder area
	//Rationale: 2. multiplying these depths by the folder area gives a volume
	//Rationale: 3. dividing these depths by the analysis area is equivalent to multiplying by the folder area and dividing by the analysis area, getting depth for analysis area
	//Note: Division is equivalent to multiplying by ratio of folder area to analysis area to convert from /folder_area to /analysis_area

	//Flux_to_WaterArea_Rain_SnowMelt_m (m) accumulates precipitation flux on water cover
    //Flux_to_WaterArea_Rain_SnowMelt_m (m) is folder area depth and equals Precipitation_RainSnowMelt_noCanopy_m (m) * WaterCover_noTreeCanopy_frac (fraction)
    //Note: Precipitation_RainSnowMelt_noCanopy_m (m) is cover area depth, multiplying by WaterCover_noTreeCanopy_frac (fraction) converts to folder area depth
    beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_WaterArea_Rain_SnowMelt_m") = beC->by_key(MapPixel_ID, DataFolder_ID, "Precipitation_RainSnowMelt_noCanopy_m") * beC->by_key(MapPixel_ID, DataFolder_ID, "WaterCover_noTreeCanopy_frac");

	//Flux_to_WaterArea_Rain_SnowMelt_m (m) arrives as folder area depth by above multiplication with Flux_to_WaterArea_Rain_SnowMelt_m
	//Flux_to_WaterArea_Rain_SnowMelt_m (m) adjusted to cover type area depth by division with Flux_to_WaterArea_Rain_SnowMelt_m
	beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_WaterArea_Rain_SnowMelt_m") = input->SafeDivide(beC->by_key(MapPixel_ID, DataFolder_ID, "Flux_to_WaterArea_Rain_SnowMelt_m"), beC->by_key(MapPixel_ID, DataFolder_ID, "WaterCover_noTreeCanopy_frac"));
}
