///////////////////////////////////////////////////////////
// File:			pg_date_dlg.cpp
//
// Author:			Stefan Liersch
// Contact:			stefan.liersch@googlemail.com,
//					stefan.liersch@ufz.de
//
// Date:			2007-02-05
// last modified:	2007-08-10
//
//---------------------------------------------------------
// DESCRIPTION
//---------------------------------------------------------
// DIALOG for
// Selecting a period (begin and end date)
//
//---------------------------------------------------------
// ToDo
//---------------------------------------------------------
// 
//
///////////////////////////////////////////////////////////

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

#include "pg_date_dlg.h"
#include "saga_gui/SAGA_Frame.h"

#include <iostream>
#include <fstream>
using namespace std;

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

BEGIN_EVENT_TABLE(CDateDLG, wxDialog)
EVT_CHOICE(CHOICE_Month1,		CDateDLG::OnChoiceSelected1)
	EVT_CHOICE(CHOICE_Day1,		CDateDLG::OnChoiceSelected1)
	EVT_COMBOBOX(CHOICE_Year1,	CDateDLG::OnChoiceSelected1)
	EVT_TEXT(CHOICE_Year1,		CDateDLG::OnChoiceSelected1)
	EVT_CHOICE(CHOICE_Month2,	CDateDLG::OnChoiceSelected2)
	EVT_CHOICE(CHOICE_Day2,		CDateDLG::OnChoiceSelected2)
	EVT_COMBOBOX(CHOICE_Year2,	CDateDLG::OnChoiceSelected2)
	EVT_TEXT(CHOICE_Year2,		CDateDLG::OnChoiceSelected2)
END_EVENT_TABLE()

//---------------------------------------------------------------------
// Constructor
CDateDLG::CDateDLG()
{}

CDateDLG::CDateDLG(wxWindow *parent, wxWindowID id, const wxString &title)
						: wxDialog(parent, id, title,
						  wxDefaultPosition, wxDefaultSize,
						  wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
	bLimitRange1 = false;
	bLimitRange2 = false;
	CreateDateDLG();
}
//---------------------------------------------------------------------
// Destructor
CDateDLG::~CDateDLG()
{
	//this->Destroy();
	delete	Choice_Day1;
	delete	Choice_Month1;
	delete	Choice_Year1;
	delete	Choice_Day2;
	delete	Choice_Month2;
	delete	Choice_Year2;
};
//---------------------------------------------------------------------



//---------------------------------------------------------------------
// Create the date dialog
//---------------------------------------------------------------------
void CDateDLG::CreateDateDLG()
{
	// Implement window functions
	// Main BoxSizer
    //wxBoxSizer *item0 = new wxBoxSizer( wxHORIZONTAL );
	wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );

	// Begin Date StaticBox
	wxStaticBox *StatBoxBegin = new wxStaticBox( this, -1, wxT("Begin Date") );
	wxStaticBoxSizer *SBSBegin = new wxStaticBoxSizer( StatBoxBegin, wxHORIZONTAL );

	// Box Day ----------------------------------------
    wxBoxSizer *item1 = new wxBoxSizer( wxVERTICAL );

    wxStaticText *item3 = new wxStaticText( this, TXT_Date1, wxT("Day"), wxDefaultPosition, wxDefaultSize, 0 );
    item3->SetToolTip( wxT("Select Day") );

	Choice_Day1 = new wxChoice( this, CHOICE_Day1, wxDefaultPosition, wxSize(40,-1), 0, NULL, 0 );
	wxArrayString strs4;
	strs4 = CreateChoiceEntries(1, 31);
	for (int i = 0; i < 31; i++)
		Choice_Day1->Append(strs4[i]);
	Choice_Day1->SetSelection(0);	
	Choice_Day1->SetToolTip( wxT("Select Day") );

	item1->Add( item3, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
    item1->Add( Choice_Day1, 0, wxALIGN_CENTER|wxALL, 5 );
	SBSBegin->Add(item1, 0, wxALIGN_CENTER|wxALL, 5 );
	
	// Box Month ----------------------------------------
    wxBoxSizer *item5 = new wxBoxSizer( wxVERTICAL );

    wxStaticText *item7 = new wxStaticText( this, TXT_Month1, wxT("Month"), wxDefaultPosition, wxDefaultSize, 0 );
    item7->SetToolTip( wxT("Select Month") );

	Choice_Month1 = new wxChoice( this, CHOICE_Month1, wxDefaultPosition, wxSize(75,-1), 0, NULL, 0 );
    Choice_Month1->SetToolTip( wxT("Select Month") );
	wxArrayString str8 = CreateChoiceEntries_Month();
	for (int i = 0; i < 12; i++)
		Choice_Month1->Append(str8[i]);
	Choice_Month1->SetSelection(0);

    item5->Add( item7, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );	
    item5->Add( Choice_Month1, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
	SBSBegin->Add(item5, 0, wxALIGN_CENTER|wxALL, 5 );

	// Box Year ----------------------------------------
    wxBoxSizer *item9 = new wxBoxSizer( wxVERTICAL );

    wxStaticText *item11 = new wxStaticText( this, TXT_Year1, wxT("Year"), wxDefaultPosition, wxDefaultSize, 0 );
    item11->SetToolTip( wxT("Select Year") );

	Choice_Year1 = new wxComboBox( this, CHOICE_Year1, wxT(""), wxDefaultPosition, wxSize(55,-1), 0, NULL, wxCB_DROPDOWN );
    Choice_Year1->SetToolTip( wxT("Select Year") );
	wxArrayString strs12 = CreateChoiceEntries(1900, 2050);
	for (int i = 0; i < 151; i++)
		Choice_Year1->Append(strs12[i]);
	Choice_Year1->SetSelection(100);

    item9->Add( item11, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
    item9->Add( Choice_Year1, 0, wxALIGN_CENTER|wxALL, 5 );
	SBSBegin->Add(item9, 0, wxALIGN_CENTER|wxALL, 5 );
	
	// Add Begin StaticBox to Main BoxSizer
	item0->Add( SBSBegin, 0, wxALIGN_CENTER|wxALL, 5 );



	// Begin Date StaticBox2 / End Date
	wxStaticBox *StatBoxEnd = new wxStaticBox( this, -1, wxT("End Date") );
	wxStaticBoxSizer *SBSEnd = new wxStaticBoxSizer( StatBoxEnd, wxHORIZONTAL );

	// Box Day ----------------------------------------
    wxBoxSizer *item21 = new wxBoxSizer( wxVERTICAL );

    wxStaticText *item23 = new wxStaticText( this, TXT_Date2, wxT("Day"), wxDefaultPosition, wxDefaultSize, 0 );
    item23->SetToolTip( wxT("Select Day") );

	Choice_Day2 = new wxChoice( this, CHOICE_Day2, wxDefaultPosition, wxSize(40,-1), 0, NULL, 0 );
	wxArrayString strs42 = CreateChoiceEntries(1, 31);
	for (int i = 0; i < 31; i++)
		Choice_Day2->Append(strs42[i]);
	Choice_Day2->SetSelection(0);	
	Choice_Day2->SetToolTip( wxT("Select Day") );

	item21->Add( item23, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
    item21->Add( Choice_Day2, 0, wxALIGN_CENTER|wxALL, 5 );
	SBSEnd->Add(item21, 0, wxALIGN_CENTER|wxALL, 5 );
	
	// Box Month ----------------------------------------
    wxBoxSizer *item25 = new wxBoxSizer( wxVERTICAL );

    wxStaticText *item27 = new wxStaticText( this, TXT_Month2, wxT("Month"), wxDefaultPosition, wxDefaultSize, 0 );
    item27->SetToolTip( wxT("Select Month") );

	Choice_Month2 = new wxChoice( this, CHOICE_Month2, wxDefaultPosition, wxSize(75,-1), 0, NULL, 0 );
    Choice_Month2->SetToolTip( wxT("Select Month") );
	wxArrayString str82 = CreateChoiceEntries_Month();
	for (int i = 0; i < 12; i++)
		Choice_Month2->Append(str82[i]);
	Choice_Month2->SetSelection(0);

    item25->Add( item27, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );	
    item25->Add( Choice_Month2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
	SBSEnd->Add(item25, 0, wxALIGN_CENTER|wxALL, 5 );

	// Box Year ----------------------------------------
    wxBoxSizer *item29 = new wxBoxSizer( wxVERTICAL );

    wxStaticText *item211 = new wxStaticText( this, TXT_Year2, wxT("Year"), wxDefaultPosition, wxDefaultSize, 0 );
    item211->SetToolTip( wxT("Select Year") );

	Choice_Year2 = new wxComboBox( this, CHOICE_Year2, wxT(""), wxDefaultPosition, wxSize(55,-1), 0, NULL, wxCB_DROPDOWN );
    Choice_Year2->SetToolTip( wxT("Select Year") );

	wxArrayString strs122 = CreateChoiceEntries(1900, 2050);
	for (int i = 0; i < 151; i++)
		Choice_Year2->Append(strs122[i]);
	Choice_Year2->SetSelection(100);

    item29->Add( item211, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
    item29->Add( Choice_Year2, 0, wxALIGN_CENTER|wxALL, 5 );
	SBSEnd->Add(item29, 0, wxALIGN_CENTER|wxALL, 5 );
	
	// Add Begin StaticBox to Main BoxSizer
	item0->Add( SBSEnd, 0, wxALIGN_CENTER|wxALL, 5 );



	// Button
    wxBoxSizer *item13 = new wxBoxSizer( wxVERTICAL );
    wxButton *ButOK = new wxButton( this, wxID_OK, wxT("OK"), wxDefaultPosition, wxDefaultSize, 0 );
    item13->Add( ButOK, 0, wxALIGN_CENTER|wxALL, 5 );
    item0->Add( item13, 0, wxALIGN_CENTER|wxALL, 5 );

    this->SetSizer( item0 );
	item0->Fit(this);
    item0->SetSizeHints( this );
}
//---------------------------------------------------------------------

wxArrayString CDateDLG::CreateChoiceEntries(int start, int end)
{
	wxArrayString AStr;
	int i;

	for (i = start; i < end + 1; i++)
		AStr.Add(wxString::Format("%d",i));

	return(AStr);
}
//---------------------------------------------------------------------

wxArrayString CDateDLG::CreateChoiceEntries_Month()
{
	wxArrayString AStr;
	AStr.Add("January");
	AStr.Add("February");
	AStr.Add("March");
	AStr.Add("April");
	AStr.Add("May");
	AStr.Add("June");
	AStr.Add("July");
	AStr.Add("August");
	AStr.Add("September");
	AStr.Add("October");
	AStr.Add("November");
	AStr.Add("December");

	return(AStr);
}
//---------------------------------------------------------------------

void CDateDLG::OnChoiceSelected1(wxCommandEvent &event)
{
	_ModifyDateBoxes(1, Choice_Day1, Choice_Month1, Choice_Year1);
	event.Skip();
}
void CDateDLG::OnChoiceSelected2(wxCommandEvent &event)
{
	_ModifyDateBoxes(2, Choice_Day2, Choice_Month2, Choice_Year2);
	event.Skip();
}
//---------------------------------------------------------------------

void CDateDLG::_ModifyDateBoxes(int d, wxChoice* Choice_Day, wxChoice* Choice_Month, wxComboBox* Choice_Year)
{
	wxDateTime		date;
	wxArrayString	AStr;
	int				lastSelectedDay;
	int				month;
	long			year;
	int				leap = 0;
	int				i;

	month = Choice_Month->GetCurrentSelection() + 1;

	if (month == 1 || month == 3 || month == 5 ||
		month == 7 || month == 8 || month == 10 || month == 12)
	{
		lastSelectedDay = Choice_Day->GetSelection();
		Choice_Day->Clear();
		AStr = CreateChoiceEntries(1,31);
		for (i = 0; i < 31; i++)
			Choice_Day->Append(AStr[i]);
		Choice_Day->SetSelection(lastSelectedDay);
	}

	if (month == 4 || month == 6 || month == 9 || month == 11)
	{
		lastSelectedDay = Choice_Day->GetSelection();
		Choice_Day->Clear();
		AStr = CreateChoiceEntries(1,30);
		for (i = 0; i < 30; i++)
			Choice_Day->Append(AStr[i]);
		if (lastSelectedDay <= 29)
			Choice_Day->SetSelection(lastSelectedDay);
		else Choice_Day->SetSelection(lastSelectedDay-1);
	}

	if (month == 2)
	{
		lastSelectedDay = Choice_Day->GetSelection();
		Choice_Day->Clear();
		year = 0;
		Choice_Year->GetValue().ToLong(&year);
		if (wxDateTime::IsLeapYear(year))
			leap = 1;
		else leap = 0;

		AStr = CreateChoiceEntries(1,28 + leap);
		for (i = 0; i < 28 + leap; i++)
			Choice_Day->Append(AStr[i]);
		if (lastSelectedDay <= 27 + leap)
			Choice_Day->SetSelection(lastSelectedDay);
		else Choice_Day->SetSelection(27+leap);
	}

	if (bLimitRange1 && bLimitRange2)
	{
		long year;
		if (d == 1 && 
			(Get_Date1().IsEarlierThan(_date1) ||
			 Get_Date1().IsLaterThan(Get_Date2())) )
		{

			Choice_Day1->SetSelection(_date1.GetDay()-1);
			Choice_Month1->SetSelection(_date1.GetMonth());
				
			for (int i = 0; i < Choice_Year1->GetCount(); i++)
			{
				Choice_Year1->SetSelection(i);
					
				if (Choice_Year1->GetValue().ToLong(&year))
				{
					if (int(year) == _date1.GetYear())
					{
						Choice_Year1->SetSelection(i);
						i = Choice_Year1->GetCount()+1; // exit loop
					}
				}
			}
		} // end if (d == 1)

		if (d == 2 && 
			(Get_Date2().IsEarlierThan(Get_Date1()) ||
			 Get_Date2().IsLaterThan(_date2)) )
		{

			Choice_Day2->SetSelection(_date2.GetDay()-1);
			Choice_Month2->SetSelection(_date2.GetMonth());
				
			for (int i = 0; i < Choice_Year2->GetCount(); i++)
			{
				Choice_Year2->SetSelection(i);
					
				if (Choice_Year2->GetValue().ToLong(&year))
				{
					if (int(year) == _date2.GetYear())
					{
						Choice_Year2->SetSelection(i);
						i = Choice_Year2->GetCount()+1; // exit loop
					}
				}
			}
		} // end if (d == 2)
		
	}

}

//---------------------------------------------------------------------
//
//			GET FUNCTIONS
//
//---------------------------------------------------------------------

int CDateDLG::Get_Day1()
{
	return(Choice_Day1->GetCurrentSelection() + 1);
}

int CDateDLG::Get_Month1()
{
	return(Choice_Month1->GetCurrentSelection() + 1);
}

int CDateDLG::Get_Year1()
{
	long year;
	Choice_Year1->GetValue().ToLong(&year);
	return(int(year));
}
//---------------------------------------------------------------------

int CDateDLG::Get_Day2()
{
	return(Choice_Day2->GetCurrentSelection() + 1);
}

int CDateDLG::Get_Month2()
{
	return(Choice_Month2->GetCurrentSelection() + 1);
}

int CDateDLG::Get_Year2()
{
	long year;
	Choice_Year2->GetValue().ToLong(&year);
	return(int(year));
}
//---------------------------------------------------------------------

wxDateTime CDateDLG::Get_Date1()
{
	return(_Get_Date(Choice_Day1, Choice_Month1, Choice_Year1));
}

wxDateTime CDateDLG::Get_Date2()
{
	return(_Get_Date(Choice_Day2, Choice_Month2, Choice_Year2));
}

wxDateTime CDateDLG::_Get_Date(wxChoice* Choice_Day, wxChoice* Choice_Month, wxComboBox* Choice_Year)
{
	long year = 0;
	wxDateTime date;
	//date = wxDateTime::UNow();
	date.Set(g_pSAGA_Frame->db->Init_wxDateTime().GetJDN());

	Choice_Year->GetValue().ToLong(&year);
	date.SetYear(year);
	date.SetDay(Choice_Day->GetCurrentSelection()+1);
	_AssignMonthByInt(date, Choice_Month->GetCurrentSelection());
	

	return(date);
}
//---------------------------------------------------------------------


//---------------------------------------------------------------------
//
//			SET FUNCTIONS
//
//---------------------------------------------------------------------

bool CDateDLG::Set_Date1(wxDateTime date)
{
	if (date.IsValid() && 
		_SetDate(1, date, Choice_Day1, Choice_Month1, Choice_Year1))
	{
		_date1 = date;
		// set bLimitRange only if begin and ending date were
		// set externally
		bLimitRange1 = true;
		return(true);
	} else {
		return(false);
	}
}
//---------------------------------------------------------------------

bool CDateDLG::Set_Date2(wxDateTime date)
{
	if (date.IsValid() &&
		_SetDate(2, date, Choice_Day2, Choice_Month2, Choice_Year2))
	{
		_date2 = date;
		bLimitRange2 = true;
		return(true);
	} else {
		return(false);
	}
}
//---------------------------------------------------------------------

bool CDateDLG::_SetDate(int d,
					   wxDateTime date,
					   wxChoice* Choice_Day,
					   wxChoice* Choice_Month,
					   wxComboBox* Choice_Year)
{
	long year;

	Choice_Day->SetSelection(date.GetDay()-1);
	Choice_Month->SetSelection(date.GetMonth());

	for (int i = 0; i < Choice_Year->GetCount(); i++)
	{
		Choice_Year->SetSelection(i);
		
		if (Choice_Year->GetValue().ToLong(&year))
		{
			if (int(year) == date.GetYear())
			{
				Choice_Year->SetSelection(i);
				_ModifyDateBoxes(d,Choice_Day, Choice_Month, Choice_Year);
				return(true);
			}
		}
	}
	return(false);
}
//---------------------------------------------------------------------

bool CDateDLG::Set_Range1(wxDateTime date1, wxDateTime date2, wxChoice *ch_d, wxChoice *ch_m, wxComboBox *ch_y)
{
	return(true);
}





//---------------------------------------------------------------------
// Usually the day and year in wxDateTime should be assigned by integer values,
// but unfortunately it is not possible to assign the month like this.
void CDateDLG::_AssignMonthByInt(wxDateTime& date, int month)
{
	switch(month)
	{
	case(0):	date.SetMonth(wxDateTime::Jan); break;
	case(1):	date.SetMonth(wxDateTime::Feb); break;
	case(2):	date.SetMonth(wxDateTime::Mar); break;
	case(3):	date.SetMonth(wxDateTime::Apr); break;
	case(4):	date.SetMonth(wxDateTime::May); break;
	case(5):	date.SetMonth(wxDateTime::Jun); break;
	case(6):	date.SetMonth(wxDateTime::Jul); break;
	case(7):	date.SetMonth(wxDateTime::Aug); break;
	case(8):	date.SetMonth(wxDateTime::Sep); break;
	case(9):	date.SetMonth(wxDateTime::Oct); break;
	case(10):	date.SetMonth(wxDateTime::Nov); break;
	case(11):	date.SetMonth(wxDateTime::Dec); break;

	default:	date.SetMonth(wxDateTime::Jan); break;
	} // end switch

	//return(date);
}