///////////////////////////////////////////////////////////
// File:			rr_preprocessing.h
//
// Author:			Stefan Liersch
// Contact:			stefan.liersch@googlemail.com,
//					stefan.liersch@ufz.de
//
// Date:			2007-08-04
// last modified:	2007-08-23
//
//---------------------------------------------------------
// DESCRIPTION
//---------------------------------------------------------
// Preprocessing time series data for rainfall-runoff models
//
//---------------------------------------------------------
// ToDo
//---------------------------------------------------------
// 
//
///////////////////////////////////////////////////////////

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

#ifndef __RR_PREPROCESSING_H__
#define __RR_PREPROCESSING_H__
//---------------------------------------------------------

#include "wx/datetime.h"
#include "wx/arrstr.h"

#include "pgsql/pgdatabase.h"
#include "hydrology/pg_timeseries.h"
//---------------------------------------------------------

class CRR_preprocessing
{
public:
	CRR_preprocessing();

	CRR_preprocessing(CTimeSeries *pTS, int nTS,
					  wxDateTime Period_Begin, wxDateTime Period_End);

	CRR_preprocessing(CTimeSeries *pDischarge, int nDischarge,
					  CTimeSeries *pPCP, int nPCP,
					  CTimeSeries *pTMP, int nTMP,
					  wxDateTime Period_Begin, wxDateTime Period_End);

	~CRR_preprocessing();

	wxDateTime		Get_Period_Begin()	{return(m_begin_period); }
	wxDateTime		Get_Period_End()	{return(m_end_period); }
	int				Get_nDaysPeriod()	{return(m_nvalues);}// returns the number of days of simulation period

	double			Get_TimeSeries1(int i);	// precipitation
	double			Get_TimeSeries2(int i);	// temperature / potential evapotranspiration

private:
	//-----------------------------------------------------------------
	// PRIVATE MEMBER VARIABLES
	//-----------------------------------------------------------------
	wxDateTime		m_begin_period;
	wxDateTime		m_end_period;

	unsigned int	m_nDischargeStations;// should be 1 usually
	unsigned int	m_nPCPStations;		// number of selected pcp stations
	unsigned int	m_nTMPStations;		// number of selected temperature stations

	double*			m_pTimeSeries1;		// precipitation time series (IHACRES, GRJ4)
	double*			m_pTimeSeries2;		// temperature time series (IHACRES)
										// temperature or potential evapotranspiration (GR4J)
	int				m_nvalues;			// number of days in the simulation period

	wxArrayString	m_date;				// date column of discharge time series
	wxArrayString	m_validPeriods;		// used to store (fractions of) the valid simulation period

	// In order to receive valid simulation periods we must know if climate data
	// are available for each day. If data are missing, the simulation period is broken.
	// Following boolean arrays are containing boolean values for each day of the simulation period
	bool*			m_p_availableTS1;	// Time series 1
	bool*			m_p_availableTS2;	// Time series 2
	bool*			m_p_available;		// both time series together (true if TS1 AND TS2 = true)

	bool			m_bPCPall;			// true, if precipitation time series is unbroken
	bool			m_bTMPall;			// true, if temperature time series is unbroken

	//-----------------------------------------------------------------
	// PRIVATE MEMBER FUNCTIONS
	//-----------------------------------------------------------------
	void			_ZeroAll();

	// Getting the first day of time series as begin
	wxDateTime		_Get_Period_Begin(const char* tablename, const char* date_col);
	// Getting the last day of time series as end
	wxDateTime		_Get_Period_End(const char* tablename, const char* date_col);

	bool			_Check_DischargePeriod(CTimeSeries *pDischarge);

	void			_Set_TimeSeriesPeriod(CTimeSeries *pTS, int nTS);

	int				_Get_nDays_TimeSeries(wxDateTime begin, wxDateTime end);
	void			_Set_nDays_Period();
	void			_InitArrays(int nvals);

	// Get discharge and climate time series from database
	bool			_Calc_TimeSeries(unsigned int nStations,
									 CTimeSeries *discharge,
									 CTimeSeries *station,
									 int ts12);
	//
	bool			_Calc_TimeSeries(unsigned int nTS, CTimeSeries *pTS, const char* date_table);

	bool			_Calc_Mean(CTimeSeries* ts, int nTimeSeries, double* mean, int ts12);

	wxString		_Get_SQL_LEFT_JOIN(const char* left_table, const char* left_col, const char* left_val,
									   const char* right_table, const char* right_col, const char* right_val,
									   wxDateTime begin, wxDateTime end);
	
	wxString		_Get_SQL_LEFT_JOIN2(const char* left_table, const char* left_date,
										const char* right_table, const char* right_date, const char* right_val,
										wxDateTime begin, wxDateTime end);

	void			_Set_AvailablePeriod(int nvalues);
	void			_Set_AvailablePeriod2(int nvalues);

	// In case begin and end period have been modified,
	// or a period within the simulation period has been choosen,
	// begin and end as well as the double data array must be renewed
	// The wxArrayString m_date will be renewed as well here.
	bool			_Get_FinalDischargeData(CTimeSeries *pDischarge, wxDateTime begin, wxDateTime end);

	wxString		_Create_DLG_Period(wxArrayString validPeriods, bool &b_ok);

	wxString		_GetFirstDate(wxString selected_period);
	wxString		_GetLastDate(wxString selected_period);
	// ISO date format: YYYY-MM-DD
	// function converts a date in ISO format as wxString to wxDateTime
	wxDateTime		_ISO2wxDate(wxString date);

	void			_Create_RRModelInput(CTimeSeries *pDischarge, wxArrayString &date_col, double *TS1, double *TS2, int begin, int nvalues);
	void			_Create_RRModelInput(wxArrayString &date_col, double *TS1, int begin, int nvalues);

};

#endif /* __RR_PREPROCESSING_H__ */