
///////////////////////////////////////////////////////////
//                                                       //
//                         SAGA                          //
//                                                       //
//      System for Automated Geoscientific Analyses      //
//                                                       //
//                    User Interface                     //
//                                                       //
//                    Program: SAGA                      //
//                                                       //
//-------------------------------------------------------//
//                                                       //
//                 WKSP_Database_Menu.cpp                //
//                                                       //
//          Copyright (C) 2008 by Stefan Liersch         //
//                                                       //
//-------------------------------------------------------//
//                                                       //
// This file is part of 'SAGA - System for Automated     //
// Geoscientific Analyses'. SAGA is free software; you   //
// can redistribute it and/or modify it under the terms  //
// of the GNU General Public License as published by the //
// Free Software Foundation; version 2 of the License.   //
//                                                       //
// SAGA is distributed in the hope that it will be       //
// useful, but WITHOUT ANY WARRANTY; without even the    //
// implied warranty of MERCHANTABILITY or FITNESS FOR A  //
// PARTICULAR PURPOSE. See the GNU General Public        //
// License for more details.                             //
//                                                       //
// You should have received a copy of the GNU General    //
// Public License along with this program; if not,       //
// write to the Free Software Foundation, Inc.,          //
// 59 Temple Place - Suite 330, Boston, MA 02111-1307,   //
// USA.                                                  //
//                                                       //
//-------------------------------------------------------//
//                                                       //
//    contact:    Olaf Conrad                            //
//                Institute of Geography                 //
//                University of Goettingen               //
//                Goldschmidtstr. 5                      //
//                37077 Goettingen                       //
//                Germany                                //
//                                                       //
//    e-mail:     oconrad@saga-gis.org                   //
//                                                       //
///////////////////////////////////////////////////////////

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

///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

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

#include "wksp_database_menu.h"
//#include <wx/tokenzr.h>

//#include <wx/menu.h>

// Include private header
#include "saga_gui/res_dialogs.h"		// using DLG_Parameters
#include "saga_gui/res_commands.h"		// Definitions of menu constants (event handler)
#include "saga_gui/wksp_data_manager.h" // adding items to SAGA Workspace *g_pData
#include "wksp_table_manager.h"
#include "wksp_table.h"
#include "saga_gui/helper.h"			// using function MSG_General_Add()
#define MSG_ADD(s)	MSG_General_Add(s, true, true);

#include "pgsql/pg_menu_db.h"
#include "soil_salinity/pg_menu_db_soil_salinity_assessment.h"
#include "soil_salinity/pg_menu_db_soil_salinity_risk.h"
#include "soil_salinity/dialogs/pg_menu_db_soil_salinity_congruence_map_dlg.h"

///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//BEGIN_EVENT_TABLE(CWKSP_Database_Menu, CWKSP_Database_Menu)
//	EVT_COMMAND	(ID_CMD_MENU_DB_CONN, ID_CMD_MENU_DB_CONN,		CWKSP_Database_Menu::_On_ConnectDB)
//END_EVENT_TABLE()
//---------------------------------------------------------
CWKSP_Database_Menu::CWKSP_Database_Menu(void)
{
	//m_Recent	= (CWKSP_Module **)SG_Calloc(RECENT_COUNT, sizeof(CWKSP_Module *));

	m_Menus		= NULL;
	m_nMenus	= 0;
}

//---------------------------------------------------------
CWKSP_Database_Menu::~CWKSP_Database_Menu(void)
{
	//SG_Free(m_Recent);

	Destroy();
}

///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
void CWKSP_Database_Menu::Destroy(void)
{
	if( m_Menus )
	{
		SG_Free(m_Menus);
		m_Menus		= NULL;
		m_nMenus	= 0;
	}
}

//---------------------------------------------------------
void CWKSP_Database_Menu::Add(wxMenu *pMenu)
{
	_Update(pMenu);

	m_Menus	= (wxMenu **)SG_Realloc(m_Menus, (m_nMenus + 1) * sizeof(wxMenu *));
	m_Menus[m_nMenus++]	= pMenu;
}

//---------------------------------------------------------
void CWKSP_Database_Menu::Del(wxMenu *pMenu)
{
	for(int i=0; i<m_nMenus; i++)
	{
		if( m_Menus[i] == pMenu )
		{
			m_nMenus--;

			for( ; i<m_nMenus; i++)
			{
				m_Menus[i]	= m_Menus[i + 1];
			}

			m_Menus	= (wxMenu **)SG_Realloc(m_Menus, m_nMenus * sizeof(wxMenu *));
		}
	}
}


///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
void CWKSP_Database_Menu::Update(void)
{
	for(int i=0; i<m_nMenus; i++)
	{
		_Update(m_Menus[i]);
	}
}

//---------------------------------------------------------
void CWKSP_Database_Menu::_Update(wxMenu *pMenu)
{
	int		ID_Menu;

    wxMenu* subMenuTable		= new wxMenu;
	wxMenu* subMenuVector		= new wxMenu;
	wxMenu*	subMenuSQL			= new wxMenu;
	wxMenu*	subMenuTimeSeries	= new wxMenu;
	wxMenu*	subMenuHydrology	= new wxMenu;
	wxMenu* subMenuSoilSalinity	= new wxMenu;

	//-----------------------------------------------------
	while( (ID_Menu = pMenu->GetMenuItemCount()) > 0 )
	{
		pMenu->Destroy(pMenu->GetMenuItems().Item(ID_Menu - 1)->GetData());
	}

	//-----------------------------------------------------
	// Connect to Database
	pMenu->Append(ID_CMD_MENU_DB_CONN, wxT("Connect to Database"), 
			_T("Makes a connection to an existing PostgreSQL Database"),false);
	pMenu->AppendSeparator();

	// ++++++++++++++ SUBMENU TABLE ++++++++++++++++++
	subMenuTable->Append(ID_CMD_MENU_DB_IMPORT_TABLE, wxT("Import Table"),
		_T("Import Table from Database"));
	
	subMenuTable->Append(ID_CMD_MENU_DB_EXPORT_TABLE, wxT("Export Table"),
		_T("Export Table to Database"));
	
	subMenuTable->Append(ID_CMD_MENU_DB_CREATE_TABLE, wxT("Create Table"),
		_T("Create Table"));

	subMenuTable->Append(ID_CMD_MENU_DB_MODIFY_TABLE, wxT("Modify Table"),
		_T("Modify Table"));

	subMenuTable->Append(ID_CMD_MENU_DB_DELETE_TABLE, wxT("Delete Table"),
		_T("Export Table to Database"));

	pMenu->Append(MENU_DB_TABLE, wxT("Table"), subMenuTable);

	// ++++++++++++++ SUBMENU VECTOR ++++++++++++++++++++++
	subMenuVector->Append(ID_CMD_MENU_DB_IMPORTSIMPLEFEATURE, wxT("Import Simple Feature"),
		_T("Import Simple Feature from PostGIS"));

	subMenuVector->Append(ID_CMD_MENU_DB_EXPORTASSIMPLEFEATURE, wxT("Export as Simple Feature"),
		_T("Export Vector Data as OGC Simple Feature"));

	pMenu->Append(MENU_DB_VECTOR, wxT("Vector Data"), subMenuVector);
	pMenu->AppendSeparator();

	// ++++++++++++++ SUBMENU SQL ++++++++++++++++++++++++++
	subMenuSQL->Append(ID_CMD_MENU_DB_CREATE_QUERY, wxT("Create Query"), 
		_T("Executes a user-defined SQL Query"), false);

	subMenuSQL->Append(ID_CMD_MENU_DB_ExecSQLcmd, wxT("Execute SQL Command"), 
		_T("Executes a user-defined SQL Command"), false);

	subMenuSQL->Append(ID_CMD_MENU_DB_CREATE_SPATIALQUERY, wxT("Create Spatial Query"),
		_T("Executes a spatial query"), false);

	pMenu->Append(MENU_DB_SQL, wxT("SQL"), subMenuSQL);
	pMenu->AppendSeparator();

	// ++++++++++++++ SUBMENU Time Series ++++++++++++++++++
	subMenuTimeSeries->Append(ID_CMD_MENU_DB_TIMESERIES_AUTO, wxT("Time Series Analysis"),
		_T("Automatical time series analysis"));

	subMenuTimeSeries->Append(ID_CMD_MENU_DB_TIMESERIES_AVE, wxT("Average Gauge Data"),
		_T("Average the data from different gauges"));

	pMenu->Append(MENU_DB_TIMESERIES, wxT("Time Series"), subMenuTimeSeries);
	pMenu->AppendSeparator();

	// ++++++++++++++ SUBMENU Hydrology ++++++++++++++++++
	subMenuHydrology->Append(ID_CMD_MENU_DB_HYDRO_RR_PREPROC, wxT("RR Preprocessing"),
		_T("RR Preprocessing"));

	pMenu->Append(MENU_DB_HYDROLOGY, wxT("Hydrological Modeling"), subMenuHydrology);
	pMenu->AppendSeparator();

	// ++++++++ SUBMENU Soil Salinity Assessment +++++++++
	subMenuSoilSalinity->Append(ID_CMD_MENU_DB_CREATE_SOILSALINITYMAP, wxT("Create Soil Salinity Base Map"),
		_T("Create a Soil Salinity Base Map from Shapefile"));
	subMenuSoilSalinity->AppendSeparator();

	subMenuSoilSalinity->Append(ID_CMD_MENU_DB_LOAD_SOILSALINITYMAP, wxT("Load Soil Salinity Assessment Map"),
		_T("Load Soil Salinity Map"));

	subMenuSoilSalinity->Append(ID_CMD_MENU_DB_LOAD_SOILSALINITY_RISK_MAP, wxT("Load Soil Salinity Risk Map"),
		_T("Load Soil Salinity Risk Map"));
	
	subMenuSoilSalinity->AppendSeparator();

	subMenuSoilSalinity->Append(ID_CMD_MENU_DB_CREATE_CONGRUENCE_MAP, wxT("Create Congruence Map"),
		_T("Create Congruence Map"));
	
	pMenu->Append(MENU_DB_SOILSALINITY, wxT("Soil Salinity Assessment"), subMenuSoilSalinity);
	pMenu->AppendSeparator();


	// ++++++++++++++ MENU Close DB Connection ++++++++++++++++++
	// Close connection to the database
	pMenu->Append(ID_CMD_MENU_DB_DECONN, wxT("Close Database Connection"),
		_T("Exit Database"),false);

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	
	// enable / disable Menu items due to connection status
	_EnableDisableMenu(g_pSAGA_Frame->DB_CONNECTED, pMenu);
}

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

void CWKSP_Database_Menu::_EnableDisableMenu(bool bconnected, wxMenu* pMenu)
{
	if (bconnected)
	{
		pMenu->Enable(ID_CMD_MENU_DB_CONN, false);
		pMenu->Enable(ID_CMD_MENU_DB_DECONN, true);
		pMenu->Enable(MENU_DB_TABLE, true);
		pMenu->Enable(MENU_DB_VECTOR, true);
		pMenu->Enable(MENU_DB_SQL, true);
		pMenu->Enable(MENU_DB_TIMESERIES, true);
		pMenu->Enable(MENU_DB_HYDROLOGY, true);
		pMenu->Enable(MENU_DB_SOILSALINITY, true);
	} else {
		pMenu->Enable(ID_CMD_MENU_DB_CONN, true);
		pMenu->Enable(ID_CMD_MENU_DB_DECONN, false);
		pMenu->Enable(MENU_DB_TABLE, false);
		pMenu->Enable(MENU_DB_VECTOR, false);
		pMenu->Enable(MENU_DB_SQL, false);
		pMenu->Enable(MENU_DB_TIMESERIES, false);
		pMenu->Enable(MENU_DB_HYDROLOGY, false);
		pMenu->Enable(MENU_DB_SOILSALINITY, false);
	}
}

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

void CWKSP_Database_Menu::On_Command(wxCommandEvent& event)
{
	switch( event.GetId() )
	{
	case ID_CMD_MENU_DB_CONN:
		_On_ConnectDB(event);
		//wxMessageBox("Not yet implemented", wxT(""));
		break;
	}
}

// ------------------------------------------------------------------------
void CWKSP_Database_Menu::_On_ConnectDB(wxCommandEvent& event)
{
	try
	{
		// db object must be destroyed (but when and where)??????
		g_pSAGA_Frame->db = new Cpgdatabase();

		// make a connection to the database using PQconnectdb
		if (g_pSAGA_Frame->db->ConnectToDB((const char*) _GenerateConnectionString(connParms).c_str())) //connInfo.c_str()))
		{
			g_pSAGA_Frame->DB_CONNECTED = true;
			MSG_ADD(wxString::Format("%s%s%s","Database ", connParms.dbname.c_str(), " connected"));
			// enable / disable Menu items due to connection status
			_EnableDisableMenu(g_pSAGA_Frame->DB_CONNECTED);
		} else {
			g_pSAGA_Frame->DB_CONNECTED = false;
			MSG_ADD(wxString::Format("%s%s%s","Database ", connParms.dbname.c_str(), " not connected"));
			_EnableDisableMenu(g_pSAGA_Frame->DB_CONNECTED);
		}
	}
	catch(...)
	{
		MSG_ADD("Connecting Database not successfull!");
	}
}
// ------------------------------------------------------------------------


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

std::string CWKSP_Database_Menu::_GenerateConnectionString(ConnectionParameters connParms)
{
	string connInfo = "host=";
	if ( connParms.hostaddr != "" ) {
		connInfo += connParms.hostaddr;
	} else {
		connInfo += connParms.host;
	}

	connInfo += " port=";
	connInfo += connParms.port;
	if (connParms.options.length() > 0)
	{
		connInfo += " options=";
		connInfo += connParms.options;
	}
	if (connParms.tty.length() > 0)
	{
		connInfo += " tty=";
		connInfo += connParms.tty;
	}
	connInfo += " dbname=";
	connInfo += connParms.dbname;
	connInfo += " user=";
	connInfo += connParms.user;
	if (connParms.password.length() > 0)
	{
		connInfo += " password=";
		connInfo += connParms.password;
	}
	return(connInfo);
}
// ------------------------------------------------------------------------
