///////////////////////////////////////////////////////////
//                                                       //
//                         SAGA                          //
//                                                       //
//      System for Automated Geoscientific Analyses      //
//                                                       //
//                    Module Library:                    //
//                      ihacres_v1                       //
//                                                       //
//-------------------------------------------------------//
//                                                       //
//                    ihacres_v1.cpp                     //
//                                                       //
//                 Copyright (C) 2006 by                 //
//                     Stefan Liersch                    //
//-------------------------------------------------------//
//                                                       //
//    e-mail:     stefan.liersch@ufz.de                  //
//                stefan.liersch@gmail.com                   //
//                                                       //
//                     2006-08-31                        //
//-------------------------------------------------------//
//                                                       
// References:											 
// Jakeman, A.J. / Hornberger, G.M (1993).				 
//   How Much Complexity Is Warranted in a				 
//	 Rainfall-Runoff Model?								 
//	 Water Resources Research, (29), NO. 8 (2637-2649)   
// Kokkonen, T. S. et al. (2003).
//   Predicting daily flows in ungauged catchments:
//   model regionalization from catchment descriptors
//   at the Coweeta Hydrologic Laboratory, North Carolina
//   Hydrological Processes (17), 2219-2238
// Croke, B. F. W., W. S. Merritt, et al. (2004).
//   A dynamic model for predicting hydrologic response
//   to land cover changes in gauged and
//   ungauged catchments.
//   Journal Of Hydrology 291(1-2): 115-131.
//-------------------------------------------------------//

//---------------------------------------------------------
#include <iostream> // used for textfile output (test only)
#include <fstream>  // used for textfile output (test only)

#include "ihacres_v1.h"
//#include "ihacres_cal.h"
#include "../model_tools.h"
//---------------------------------------------------------

// constructor
Cihacres_v1::Cihacres_v1(void)
{
	//-----------------------------------------------------
	// 1. Info...
	Set_Name("IHACRES Version 1.0");

	Set_Author("copyrights (c) 2008 Stefan Liersch");

	Set_Description("The Rainfall-Runoff Model IHACRES \n \n \n"
		"Reference: \n \n"
		"Jakeman, A.J. / Hornberger, G.M. (1993). \n"
		"How Much Complexity Is Warranted in a Rainfall-Runoff Model? \n"
		"Water Resources Research, (29), NO. 8 (2637-2649) \n \n"   
		"Croke, B. F. W. et al.(2004).\n"
		"A dynamic model for predicting hydrologic response "
		"to land cover changes in gauged and "
		"ungauged catchments. \n"
		"Journal Of Hydrology 291(1-2): 115-131."
	);

	///////////////////////////////////////////////////////////////////
	// FIRST MODULE DIALOG
	CreateDialog1();
	///////////////////////////////////////////////////////////////////
}

//---------------------------------------------------------
// destructor
Cihacres_v1::~Cihacres_v1(void)
{}

//---------------------------------------------------------

bool Cihacres_v1::On_Execute(void)
{
	///////////////////////////////////////////////////////////////////
	//
	//								VARIABLES
	//
	///////////////////////////////////////////////////////////////////
	int				j,k;		//counter
	CSG_Table		*pTable, *pTable_out, *pTable_parms, *pTable_settings;

	bool			bTMP;		// true, if temperature data are used to
								// to refine wetness index estimation.
	bool			writeAllTimeSeries;
	int				storconf;	// storage configuration
								// 0 = single, 1 = two parallel, 2 = two in series

	// Assign Parameters from first Module Dialog
	//---------------------------------------------------------
	pTable			= Parameters("TABLE")			->asTable();
	// Field numbers
	dateField		= Parameters("DATE_Field")		->asInt();
	dischargeField	= Parameters("DISCHARGE_Field")	->asInt();
	pcpField		= Parameters("PCP_Field")		->asInt();
	tmpField		= Parameters("TMP_Field")		->asInt();

	bTMP			= Parameters("USE_TMP")			->asBool();
	c				= Parameters("CFAC")			->asDouble();
	TwConst			= Parameters("TwFAC")			->asDouble();
	m_area			= Parameters("AREA")			->asDouble();
	storconf		= Parameters("STORAGE")			->asInt();
	IHAC_version	= Parameters("IHACVERS")		->asInt();
	bSnowModule		= Parameters("SNOW_MODULE")		->asBool();
	writeAllTimeSeries = Parameters("WRITEALL_TS")	->asBool();
	first = last	= 0;
	//---------------------------------------------------------

	///////////////////////////////////////////////////////////////////
	// Create Second Dialog and assign linear module parameters
	if ( CreateDialog2(bTMP, storconf, IHAC_version, pTable, dateField, dischargeField) ) {
		///////////////////////////////////////////////////////////////////

		///////////////////////////////////////////////////////////////
		// searching the first and the last record of the time range
		ihacres->AssignFirstLastRec(*pTable, first, last, date1, date2, dateField);
		///////////////////////////////////////////////////////////////

		///////////////////////////////////////////////////////////////
		//					INITIALIZE VECTORS
		sizeAll = last - first + 1;
		// global array variables
		date.resize(sizeAll);
		m_Q_obs_m3s.resize(sizeAll);
		m_Q_obs_mmday.resize(sizeAll);
		precipitation.resize(sizeAll);
		if (bTMP) temperature.resize(sizeAll);

		for (j = 0, k = first; j < sizeAll, k < last + 1; j++, k++)
		{
			date[j].append(pTable->Get_Record(k)->asString(dateField));
			m_Q_obs_m3s[j]			 = pTable->Get_Record(k)->asDouble(dischargeField);
			precipitation[j]		 = pTable->Get_Record(k)->asDouble(pcpField);
			if (bTMP) temperature[j] = pTable->Get_Record(k)->asDouble(tmpField);
		}

		if (bSnowModule && bTMP)
		{
			m_pSnowModule = new CSnowModule(temperature, precipitation, T_Rain, T_Melt, DD_FAC);
			if (!bSnowModule) m_pSnowModule = NULL;
			//m_pSnowModule->MeltRate = new double[sizeAll];
			//m_pSnowModule->SnowStorage = new double[sizeAll];
		}

		//---------------------------------------------------------
		// Convert streamflow from m3/s to mm/day
		///////////////////////////////////////////////////////////////


		///////////////////////////////////////////////////////////////
		//
		//					INSTANTIATE CLASS IHACRES
		//
		///////////////////////////////////////////////////////////////

		// different constructors are available for class ihacres_eq,
		// depending on availability of temperature data,
		// storage characteristics, and data storage properties (vector / arrays)

		switch(storconf)
		{
		case 0: // single storage
			ihacres = new Cihacres_eq(date,
									  m_Q_obs_m3s,
									  precipitation,
									  temperature,
									  TwConst, f, c, l, p,
									  a, 0, b, 0,
									  m_area,
									  bTMP,
									  IHAC_version,
									  storconf,
									  bSnowModule,
									  m_pSnowModule,
									  delay);
			break;
		case 1: // two storages in parallel
			// if temperature data available
			// and using vectors to store time series data
			// and 2 storages in parallel
			ihacres = new Cihacres_eq(date,
									  m_Q_obs_m3s,
									  precipitation,
									  temperature,
									  TwConst, f, c, l, p,
									  aq, as, bq, bs,
									  m_area,
									  bTMP,
									  IHAC_version,
									  storconf,
									  bSnowModule,
									  m_pSnowModule,
									  delay);
			break;
		} // end switch

		//---------------------------------------------------------
		// create output tables and add them to SAGA workspace
		//---------------------------------------------------------
		pTable_out   = SG_Create_Table();
		CreateTableSim(pTable_out, date, m_Q_obs_m3s, ihacres->get_streamflow_sim());//ihacres->streamflow_sim);
		// add tables to SAGA Workspace
		pTable_out->Set_Name("IHACRES_Sim");
		Parameters("TABLEout")->Set_Value(pTable_out);
			
		pTable_settings   = SG_Create_Table();
		if (bSnowModule)
		{
			CreateTableSettings(pTable_settings, TwConst, c, f, aq, as, bq, bs,
								ihacres->get_vq(), ihacres->get_vs(),
								bSnowModule, m_pSnowModule->Get_T_Rain(), m_pSnowModule->Get_T_Melt(), m_pSnowModule->Get_DD_FAC(),
								delay,
								model_tools::CalcRunoffCoeff(m_Q_obs_mmday,precipitation), ihacres->get_NSE(),
								m_area);
		} else {
			CreateTableSettings(pTable_settings, TwConst, c, f, aq, as, bq, bs,
								ihacres->get_vq(), ihacres->get_vs(),
								bSnowModule, 0, 0, 0,
								delay,
								model_tools::CalcRunoffCoeff(m_Q_obs_mmday,precipitation), ihacres->get_NSE(),
								m_area);
		}
		pTable_settings->Set_Name("IHACRES_Settings");
		Parameters("TABLEsettings")->Set_Value(pTable_settings);

		if (writeAllTimeSeries)
		{
			pTable_parms = SG_Create_Table();
			CreateTableParms(pTable_parms, date, m_Q_obs_m3s, precipitation, temperature,
							ihacres->get_streamflow_sim(), ihacres->get_excessRain(),
							ihacres->get_WetnessIndex(), ihacres->get_Tw());
			pTable_parms->Set_Name("IHACRES_Parms");
			Parameters("TABLEparms")->Set_Value(pTable_parms);
		}

		///////////////////////////////////////////////////////////////
		//						DELETE AND RESIZE
		///////////////////////////////////////////////////////////////
		delete ihacres;
		date.resize(0);
		m_Q_obs_m3s.resize(0);
		m_Q_obs_mmday.resize(0);
		precipitation.resize(0);
		if (bTMP) temperature.resize(0);
		if (bSnowModule) delete m_pSnowModule;
		///////////////////////////////////////////////////////////////

		//---------------------------------------------------------
		return( true );   // bool Cihacres_cal::On_Execute(void)
	} else {
		return(false);
	}
} // end function On_Execute()


///////////////////////////////////////////////////////////////////////
//
//                          PRIVATE FUNCTIONS
//
///////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////
//
//                          CREATE OUTPUT TABLES
//
///////////////////////////////////////////////////////////////////////

void Cihacres_v1::CreateTableSim(CSG_Table *pTable, date_array date, vector_d strfl_obs, vector_d strfl_sim)
{
	int i = 0; // used in function Get_Record(i)
	CSG_Table_Record	*pRecord;

	// creating the column titles
	pTable->Add_Field("Date",		TABLE_FIELDTYPE_String);
	pTable->Add_Field("Flow OBS",	TABLE_FIELDTYPE_Double);
	pTable->Add_Field("Flow SIM",	TABLE_FIELDTYPE_Double);

	for (unsigned int j = 0; j < date.size(); j++)
	{
		pTable->Add_Record();
		pRecord = pTable->Get_Record(i);

		// writing the data into the rows
		pRecord->Set_Value(0,date[j].c_str());
		pRecord->Set_Value(1,strfl_obs[j]);
		pRecord->Set_Value(2,model_tools::mmday_to_m3s(strfl_sim[j],m_area));
		i++;
	}
}

void Cihacres_v1::CreateTableParms(CSG_Table *pTable, date_array date, vector_d strfl_obs, vector_d precipitation, vector_d temperature,
								   vector_d strfl_sim, vector_d excessRain, vector_d wi, vector_d Tw)
{
	int i = 0; // used in function Get_Record(i)
	CSG_Table_Record	*pRecord;

	// creating the column titles
	pTable->Add_Field("Date",			TABLE_FIELDTYPE_String);
	pTable->Add_Field("Flow OBS",		TABLE_FIELDTYPE_Double);
	pTable->Add_Field("Flow SIM",		TABLE_FIELDTYPE_Double);
	pTable->Add_Field("TMP",			TABLE_FIELDTYPE_Double);
	pTable->Add_Field("PCP",			TABLE_FIELDTYPE_Double);
	pTable->Add_Field("ExcessRain",		TABLE_FIELDTYPE_Double);
	pTable->Add_Field("WetnessIndex",	TABLE_FIELDTYPE_Double);
	pTable->Add_Field("Tau",			TABLE_FIELDTYPE_Double);

	for (unsigned int j = 0; j < date.size(); j++)
	{
		pTable->Add_Record();
		pRecord = pTable->Get_Record(i);

		// writing the data into the rows
		pRecord->Set_Value(0,date[j].c_str());
		pRecord->Set_Value(1,strfl_obs[j]);
		pRecord->Set_Value(2,model_tools::mmday_to_m3s(strfl_sim[j], m_area));
		pRecord->Set_Value(3,temperature[j]);
		pRecord->Set_Value(4,precipitation[j]);
		pRecord->Set_Value(5,excessRain[j]);
		pRecord->Set_Value(6,wi[j]);
		pRecord->Set_Value(7,Tw[j]);
		i++;
	}
}

void Cihacres_v1::CreateTableSettings(CSG_Table *pTable, double Tw, double c, double f,
									  double aq, double as, double bq, double bs,
									  double vq , double vs,
									  bool bSnowModule, double T_Rain, double T_Melt, double DD_FAC,
									  int delay,
									  double RRCoef, double NSE,
									  double m_area)
{
	int count = 1;
	CSG_Table_Record	*pRecord;

	// creating the column titles
	pTable->Add_Field("Parameters",	TABLE_FIELDTYPE_String);
	pTable->Add_Field("Settings",	TABLE_FIELDTYPE_Double);

	pTable->Add_Record();
	pRecord = pTable->Get_Record(0);
	pRecord->Set_Value(0,"Tau");
	pRecord->Set_Value(1,Tw);	

	pTable->Add_Record();
	pRecord = pTable->Get_Record(1);
	pRecord->Set_Value(0,"c");
	pRecord->Set_Value(1,c);	

	pTable->Add_Record();
	pRecord = pTable->Get_Record(2);
	pRecord->Set_Value(0,"f");
	pRecord->Set_Value(1,f);

	pTable->Add_Record();
	pRecord = pTable->Get_Record(3);
	pRecord->Set_Value(0,"a(q)");
	pRecord->Set_Value(1,aq);

	pTable->Add_Record();
	pRecord = pTable->Get_Record(4);
	pRecord->Set_Value(0,"a(s)");
	pRecord->Set_Value(1,as);

	pTable->Add_Record();
	pRecord = pTable->Get_Record(5);
	pRecord->Set_Value(0,"b(q)");
	pRecord->Set_Value(1,bq);

	pTable->Add_Record();
	pRecord = pTable->Get_Record(6);
	pRecord->Set_Value(0,"b(s)");
	pRecord->Set_Value(1,bs);
	//pRecord->Set_Value(1,vs * (1 + as));

	pTable->Add_Record();
	pRecord = pTable->Get_Record(7);
	pRecord->Set_Value(0,"v(q)");
	pRecord->Set_Value(1,vq);

	pTable->Add_Record();
	pRecord = pTable->Get_Record(8);
	pRecord->Set_Value(0,"v(s)");
	pRecord->Set_Value(1,vs);

	pTable->Add_Record();
	pRecord= pTable->Get_Record(9);
	pRecord->Set_Value(0,"T(q)");
	pRecord->Set_Value(1,ihacres->Calc_TimeOfDecay(aq));

	pTable->Add_Record();
	pRecord= pTable->Get_Record(10);
	pRecord->Set_Value(0,"T(s)");
	pRecord->Set_Value(1,ihacres->Calc_TimeOfDecay(as));

	if (bSnowModule)
	{
		pTable->Add_Record();
		pRecord = pTable->Get_Record(10+count);
		pRecord->Set_Value(0,"T_Rain");
		pRecord->Set_Value(1,T_Rain);
		count++;

		pTable->Add_Record();
		pRecord = pTable->Get_Record(10+count);
		pRecord->Set_Value(0,"T_Melt");
		pRecord->Set_Value(1,T_Melt);
		count++;

		pTable->Add_Record();
		pRecord = pTable->Get_Record(10+count);
		pRecord->Set_Value(0,"DD_Fac");
		pRecord->Set_Value(1,DD_FAC);
		count++;
	}

	pTable->Add_Record();
	pRecord = pTable->Get_Record(10+count);
	pRecord->Set_Value(0,"RR-Delay");
	pRecord->Set_Value(1,delay);
	count++;

	pTable->Add_Record();
	pRecord = pTable->Get_Record(10+count);
	pRecord->Set_Value(0,"RRCoef");
	pRecord->Set_Value(1,RRCoef);
	count++;

	pTable->Add_Record();
	pRecord = pTable->Get_Record(10+count);
	pRecord->Set_Value(0,"NSE");
	pRecord->Set_Value(1,NSE);
	count++;

	pTable->Add_Record();
	pRecord = pTable->Get_Record(10+count);
	pRecord->Set_Value(0,"Area");
	pRecord->Set_Value(1,m_area);
	count++;
}


///////////////////////////////////////////////////////////////////////
//
//		                          DIALOGS
//
///////////////////////////////////////////////////////////////////////

void Cihacres_v1::CreateDialog1()
{
	CSG_Parameter	*pNode;
	CSG_String s;

	pNode = Parameters.Add_Table(
		NULL	, "TABLE"	, _TL("Table"),
		"",
		PARAMETER_INPUT
	);

	Parameters.Add_Table_Field(
		pNode	, "DATE_Field"	, _TL("Date Column"),
		"Select the column containing the Date"
	);

	Parameters.Add_Table_Field(
		pNode	, "DISCHARGE_Field"	, _TL("Streamflow Column"),
		"Select the Column containing Discharge Values"
	);

	Parameters.Add_Table_Field(
		pNode	, "PCP_Field"	, _TL("Precipitation Column"),
		"Select the Column containing precipitation Values"
	);

	Parameters.Add_Table_Field(
		pNode	, "TMP_Field"	, _TL("Temperature Column"),
		"Select the Column containing Temperature Values"
	);

	Parameters.Add_Value(
		pNode,	"USE_TMP",	_TL("Using temperature data?"),
		_TL("If checked, then temperature data are used."),
		PARAMETER_TYPE_Bool, true
	);

	pNode = Parameters.Add_Value(
		NULL,	"AREA",	_TL("Area of the Watershed in [km2]"),
		_TL("Area of the Watershed in [km2] used for unit conversion"),
		PARAMETER_TYPE_Double,
		100.0, 0.00001, true, 0.0, false
	);

	s.Printf("Node2", 2);
		pNode = Parameters.Add_Node(NULL,s,"Non-Linear Module","");

	Parameters.Add_Value(
		pNode,	"CFAC",	_TL("Parameter (c)"),
		_TL("Parameter (c) to fit streamflow volume"),
		PARAMETER_TYPE_Double,
		0.001, 0.0, true, 1.0, true
	);
	Parameters.Add_Value(
		pNode,	"TwFAC",	_TL("(Tw) wetness decline time constant"),
		_TL("Tw is approximately the time constant, or inversely,"
		"the rate at which the catchment wetness declines in the absence of rainfall"),
		PARAMETER_TYPE_Double,
		1.0, 0.01, true, 150.0, true
	);

	s.Printf("Node3", 3);
	pNode = Parameters.Add_Node(NULL,s,"Storage Configuration","");

	Parameters.Add_Choice(
		pNode	, "STORAGE"		, "Storage",
		"",
		CSG_String::Format("%s|%s|%s|",
			_TL("Single Storage"),			//  0
			_TL("Two Parallel Storages"),	//  1 
			_TL("Two Storages in Series !!! not yet implemented !!!")	//  2 
		)
	);

	s.Printf("Node4", 4);
	pNode = Parameters.Add_Node(NULL,s,"IHACRES Version","");

	Parameters.Add_Choice(
		pNode	, "IHACVERS"		, "IHACRES Version",
		"",
		CSG_String::Format("%s|%s|",
			_TL("Jakeman & Hornberger (1993)"),	//  0
			_TL("Croke et al. (2005)")	//	1

		)
	);

	Parameters.Add_Value(
		pNode,	"SNOW_MODULE",	_TL("Using the snow-melt module?"),
		_TL("If checked, snow-melt module is used."),
		PARAMETER_TYPE_Bool, false
	);

	Parameters.Add_Value(
		NULL,	"WRITEALL_TS",	_TL("Write all calculated Time Series in a table?"),
		_TL("If checked, then a second output table with all Time Series data is created."),
		PARAMETER_TYPE_Bool, true
	);

	Parameters.Add_Table_Output(
		NULL	, "TABLEout"	, _TL("Table"),
		""
	);
	Parameters.Add_Table_Output(
		NULL	, "TABLEparms"	, _TL("Table"),
		""
	);
	Parameters.Add_Table_Output(
		NULL	, "TABLEsettings", _TL("Table"),
		""
	);
}
//---------------------------------------------------------------------
// DIALOG 2
//---------------------------------------------------------------------

bool Cihacres_v1::CreateDialog2(bool bTMP, int storconf, int IHAC_version,
								CSG_Table *pTable,
								int dateField, int dischargeField)
{
	CSG_String		s;
	CSG_Parameters	P;  // used to add Parameters in the second dialog
	CSG_Parameter	*pNode, *pNode1;

	//	Dialog design
	P.Set_Name(_TL("IHACRES Model Parameters (Calibration)"));

	s.Printf("Node1", 1);
	pNode = P.Add_Node(NULL,s,"Time Range","");

	s.Printf("FDAY" , 1-1);
	P.Add_String(pNode,s,_TL("First Day"),_TL(""),
				 pTable->Get_Record(0)->asString(dateField));

	s.Printf("LDAY" , 1-2);
	P.Add_String(pNode,s,_TL("Last Day"),_TL(""),
				 pTable->Get_Record(pTable->Get_Record_Count()-1)->asString(dateField));


	if (bTMP) // if observed temperature data are used
	{
		s.Printf("Node2", 2);
		pNode = P.Add_Node(NULL,s,"Non-Linear Module","");

		s.Printf("Node2-1", 2-1);
		pNode1 = P.Add_Node(pNode,s,"Temperature Modulation Factor","");

		P.Add_Value(
			pNode1	, "TFac"		, "Temperature Modulation Factor (f)",
			_TL("Temperature Modulation Factor f"),
			PARAMETER_TYPE_Double,
			1.0, 0.0001, true, 10.0, true
		);
	} // End if (bTMP)

	switch(IHAC_version)
	{
	case 0: // Jakeman & Hornberger (1993)
		break;
	case 1: // Croke et al. (2005)
		s.Printf("Node4", 4);
		pNode = P.Add_Node(NULL,s,"Soil Moisture Power Eq.","");

		s.Printf("Node4-1", 4-1);
		pNode1 = P.Add_Node(pNode,s,"Parameter l","");

		P.Add_Value(
			pNode1,"L",_TL("Soil moisture index (l)"),
			_TL(""),
			PARAMETER_TYPE_Double,
			0.0, 0.0, true, 5.0, true
		);
		
		s.Printf("Node4-2", 4-2);
		pNode1 = P.Add_Node(pNode,s,"Parameter p","");

		P.Add_Value(
			pNode1,"P",_TL("Power on soil (p)"),
			_TL(""),
			PARAMETER_TYPE_Double,
			0.0, 0.0, true, 5.0, true
		);
		break;
	} // end switch (IHAC_version)

	switch(storconf)
	{
	case 0: // single storage
		s.Printf("Node3", 3);
		pNode = P.Add_Node(NULL,s,"Linear Module","");

		s.Printf("Node3-1", 3-1);
		pNode1 = P.Add_Node(pNode,s,"Parameter (a)","");

		P.Add_Value(
			pNode1,	"AFAC",	_TL("(a)"),
			_TL(""),
			PARAMETER_TYPE_Double,
			-0.8, -0.99, true, -0.01, true
		);

		s.Printf("Node3-2", 3-2);
		pNode1 = P.Add_Node(pNode,s,"Parameter (b)","");

		P.Add_Value(
			pNode1,	"BFAC",	_TL("(b)"),
			_TL(""),
			PARAMETER_TYPE_Double,
			0.2, 0.001, true, 1.0, true
		);
		break;

	case 1: // two parallel storages
		s.Printf("Node3", 3);
		pNode = P.Add_Node(NULL,s,"Linear Module","");

		// Parameter a
		s.Printf("Node3-1", 3-1);
		pNode1 = P.Add_Node(pNode,s,"Parameter (a)","");

		P.Add_Value(
			pNode1,	"AQ",	_TL("a(q)"),
			_TL(""),
			PARAMETER_TYPE_Double,
			-0.7, -0.99, true, -0.01, true
		);
		P.Add_Value(
			pNode1,	"AS",	_TL("a(s)"),
			_TL(""),
			PARAMETER_TYPE_Double,
			-0.9, -0.99, true, -0.01, true
		);

		// Parameter b
		s.Printf("Node3-2", 3-2);
		pNode1 = P.Add_Node(pNode,s,"Parameter (b)","");

		P.Add_Value(
			pNode1,	"BQ",	_TL("b(q)"),
			_TL(""),
			PARAMETER_TYPE_Double,
			0.0, 0.0, true, 1.0, true
		);
		break;

	case 2: // two storages in series
		break;
	} // end switch (storconf)

	if (bSnowModule)
	{
	s.Printf("Node5", 5);
	pNode1 = P.Add_Node(NULL,s,"Snow Module Parameters","");
		
		P.Add_Value(
			pNode1,	"T_RAIN",	"Temperature Threshold for Rainfall",
			"Below this threshold precipitation will fall as snow",
			PARAMETER_TYPE_Double,
			-1.0, -10.0, true, 10.0, true
		);
		P.Add_Value(
			pNode1,	"T_MELT",	"Temperature Threshold for Melting",
			"Above this threshold snow will start to melt",
			PARAMETER_TYPE_Double,
			1.0, -5.0, true, 10.0, true
		);
		P.Add_Value(
			pNode1,	"DD_FAC",	"Day-Degree Factor",
			"Day-Degree Factor depends on catchment characteristics",
			PARAMETER_TYPE_Double,
			0.7, 0.7, true, 9.2, true
		);
	}
	s.Printf("Node6", 6);
	pNode1 = P.Add_Node(NULL,s,"Time Delay after Start of Rainfall (INTEGER)","");
		
	P.Add_Value(
		pNode1,	"DELAY",	"Time Delay (Rain-Runoff)",
		"The delay after the start of rainfall, before the discharge starts to rise.",
		PARAMETER_TYPE_Int,
		1, 0, true, 100, true
	);

	// End of second dialog design

	if( SG_UI_Dlg_Parameters(&P, _TL("Choose Time Range")) )
	{
		///////////////////////////////////////////////////////////////
		//
		//                ASSIGN DATA FROM SECOND DIALOG
		//
		///////////////////////////////////////////////////////////////
		date1		= P(CSG_String::Format("FDAY",dateField).c_str())
									->asString();
		date2		= P(CSG_String::Format("LDAY",dischargeField).c_str())
									->asString();
		// if observed temperature data are used
		if (bTMP) f	= P("TFac")		->asDouble();

		switch(IHAC_version)
		{
		case 0: break;
		case 1: 
			l		= P("L")			->asDouble();
			p		= P("P")			->asDouble();
			
			break;
		}

		if (bSnowModule)
		{
			T_Rain	= P("T_RAIN")		->asDouble();
			T_Melt	= P("T_MELT")		->asDouble();
			DD_FAC	= P("DD_FAC")		->asDouble();
		}
		switch (storconf)
		{
		case 0: // single storage
			a		= P("AFAC")			->asDouble();
			b		= P("BFAC")			->asDouble();
			delay	= P("DELAY")		->asInt();
			break;
		case 1: // two parallel storages
			aq		= P("AQ")			->asDouble();
			as		= P("AS")			->asDouble();
			bq		= P("BQ")			->asDouble();
			//bs		= P("BS")			->asDouble();
			bs = ihacres->Calc_Parm_BS(aq,as,bq);
			delay	= P("DELAY")		->asInt();
			break;
		case 2: // two storages in series
			break;
		} // end switch (storconf)
		return(true);
	} else {
		return(false);
	}
}