///////////////////////////////////////////////////////////
// File:			wksp_simplefeature.cpp
//
// Author:			Stefan Liersch
// Contact:			stefan.liersch@googlemail.com,
//					stefan.liersch@ufz.de
//
// Date:			2008-04-05
// last modified:	2008-04-05
//
//---------------------------------------------------------
// DESCRIPTION
//---------------------------------------------------------
//
//---------------------------------------------------------
// ToDo
//---------------------------------------------------------
// 
//
///////////////////////////////////////////////////////////

//---------------------------------------------------------
#include "wksp_simplefeature.h"

#include "wksp_table.h"

#include "helper.h"
#include "res_commands.h"
#include "res_dialogs.h"

#include "saga_gui/saga_frame.h"
#include "pgsql/pgdatabase.h"
#include "pgsql/pg_menu_db.h"
#include "soil_salinity/dialogs/pg_soil_salinity_load_data_dlg.h"

#define MSG_ADD(s)	MSG_General_Add(s, true, true);

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

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

CWKSP_SimpleFeature::CWKSP_SimpleFeature(CSG_SimpleFeature *pSimpleFeature)
: CWKSP_Shapes(pSimpleFeature)
{
	m_pSimpleFeature = pSimpleFeature;
	m_pTable		= new CWKSP_Table(&m_pSimpleFeature->Get_Table(), this);

	m_Edit_Shapes.Create(m_pSimpleFeature->Get_Type());
	m_Edit_pShape	= NULL;

	m_Edit_Attributes.Destroy();
	m_Edit_Attributes.Add_Field(LNG("[FLD] Name") , TABLE_FIELDTYPE_String);
	m_Edit_Attributes.Add_Field(LNG("[FLD] Value"), TABLE_FIELDTYPE_String);
}
//---------------------------------------------------------

CWKSP_SimpleFeature::~CWKSP_SimpleFeature()
{
}
//---------------------------------------------------------

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


wxString CWKSP_SimpleFeature::Get_Description(void)
{
	wxString	s;

	s.Append(wxString::Format("<b>%s</b><table border=\"0\">",
		LNG("[CAP] Simple Feature")
	));

	s.Append(wxString::Format("<tr><td>%s</td><td>%s</td></tr>",
	LNG("[CAP] FeatureName")		, m_pSimpleFeature->Get_FeatureName()
	));
	s.Append(wxString::Format("<tr><td>%s</td><td>%s</td></tr>",
	LNG("[CAP] Geometry Type")		, m_pSimpleFeature->Get_GeoTypeAsString()
	));
	s.Append(wxString::Format("<tr><td>%s</td><td>%d</td></tr>",
	LNG("[CAP] Number of Features")	, m_pSimpleFeature->Get_nFeatures()
	));
	s.Append(wxString::Format("<tr><td>%s</td><td>%d</td></tr>",
	LNG("[CAP] OID")				, m_pSimpleFeature->Get_OID()
	));
	s.Append(wxString::Format("<tr><td>%s</td><td>%d</td></tr>",
	LNG("[CAP] SRID")				, m_pSimpleFeature->Get_SRID()
	));
	s.Append(wxString::Format("<tr><td>%s</td><td>%s</td></tr>",
	LNG("[CAP] Geometry Column")	, m_pSimpleFeature->Get_geom()
	));
	s.Append(wxString::Format("<tr><td>%s</td><td>%s</td></tr>",
	LNG("[CAP] Table Catalog")		, m_pSimpleFeature->Get_TableCatalog()
	));
	s.Append(wxString::Format("<tr><td>%s</td><td>%s</td></tr>",
	LNG("[CAP] Table Schema")		, m_pSimpleFeature->Get_TableSchema()
	));
	s.Append(wxString::Format("<tr><td>%s</td><td>%s</td></tr>",
	LNG("[CAP] SF Category")		, m_pSimpleFeature->Get_SF_CategoryAsString().c_str()
	));

	s.Append("</table>");
	

	//-----------------------------------------------------
	s.Append(wxString::Format("<hr><b>%s</b>", LNG("[CAP] Table Description")));
	s.Append(Get_TableInfo_asHTML(&m_pShapes->Get_Table()));

	//-----------------------------------------------------
	s.Append(wxString::Format("<hr><b>%s</b><font size=\"-1\">", LNG("[CAP] Data History")));
	s.Append(m_pShapes->Get_History().Get_HTML());
	s.Append(wxString::Format("</font"));

	return( s );
}
//---------------------------------------------------------

wxMenu * CWKSP_SimpleFeature::Get_Menu(void)
{
	wxMenu	*pMenu;
//	CSG_Data_Object* pObject = m_pSimpleFeature;
	pMenu	= new wxMenu("SimpleFeature");

	CMD_Menu_Add_Item(pMenu, false, ID_CMD_WKSP_ITEM_CLOSE);
	CMD_Menu_Add_Item(pMenu, false, ID_CMD_SHAPES_SAVE);
	CMD_Menu_Add_Item(pMenu, false, ID_CMD_SHAPES_SAVEAS);
	CMD_Menu_Add_Item(pMenu, false, ID_CMD_SHAPES_SHOW);
	CMD_Menu_Add_Item(pMenu, false, ID_CMD_SHAPES_SET_LUT);

	pMenu->AppendSeparator();
	pMenu->Append(ID_CMD_WKSP_FIRST, LNG("[MNU] Edit"), Edit_Get_Menu());

	return( pMenu );
}
//---------------------------------------------------------

bool CWKSP_SimpleFeature::On_Command(int Cmd_ID)
{
	switch( Cmd_ID )
	{
	default:
		return( CWKSP_Layer::On_Command(Cmd_ID) );

	case ID_CMD_SHAPES_SET_LUT:
		_LUT_Create();
		break;

	case ID_CMD_SHAPES_EDIT_SHAPE:
		_Edit_Shape();
		break;

	case ID_CMD_SHAPES_EDIT_ADD_SHAPE:
		_Edit_Shape_Add();
		break;

	case ID_CMD_SHAPES_EDIT_DEL_SHAPE:
		_Edit_Shape_Del();
		break;

	case ID_CMD_SHAPES_EDIT_ADD_PART:
		_Edit_Part_Add();
		break;

	case ID_CMD_SHAPES_EDIT_DEL_PART:
		_Edit_Part_Del();
		break;

	case ID_CMD_SHAPES_EDIT_DEL_POINT:
		_Edit_Point_Del();
		break;

//----------stliersch----------
	case ID_CMD_SIMPLEFEATURE_GET_STATION:
		Get_Station_Data();
		break;

	case ID_CMD_SIMPLEFEATURE_OPEN_SOILSALINITY_DLG:
		Open_SoilSalinity_Dlg(m_pSimpleFeature);
		break;

	case ID_CMD_SIMPLEFEATURE_LOAD_SOILSALINITY_DATA:
		Load_SoilSalinityData(m_pSimpleFeature);
		break;

	//case ID_CMD_SIMPLEFEATURE_OPEN_SOILSALINITY_RISK_DLG:
	//	Open_SoilSalinityRisk_Dlg(m_pSimpleFeature);
	//	break;

	//case ID_CMD_SIMPLEFEATURE_LOAD_SOILSALINITY_RISK_DATA:
	//	Load_SoilSalinityRiskData(m_pSimpleFeature);
	//	break;
				
//----------stliersch----------
	}

	return( true );
}

//---------------------------------------------------------
bool CWKSP_SimpleFeature::On_Command_UI(wxUpdateUIEvent &event)
{
	switch( event.GetId() )
	{
	default:
		return( CWKSP_Layer::On_Command_UI(event) );

	case ID_CMD_SHAPES_EDIT_SHAPE:
		event.Enable(m_pSimpleFeature->Get_Selection_Count() > 0 || m_Edit_pShape != NULL);
		event.Check(m_Edit_pShape != NULL);
		break;

	case ID_CMD_SHAPES_EDIT_ADD_SHAPE:
		event.Enable(m_Edit_pShape == NULL);
		break;

	case ID_CMD_SHAPES_EDIT_DEL_SHAPE:
		event.Enable(m_pSimpleFeature->Get_Selection_Count() > 0 && m_Edit_pShape == NULL);
		break;

	case ID_CMD_SHAPES_EDIT_ADD_PART:
		event.Enable(m_Edit_pShape != NULL);
		break;

	case ID_CMD_SHAPES_EDIT_DEL_PART:
		event.Enable(m_Edit_pShape != NULL && m_Edit_iPart >= 0);
		break;

	case ID_CMD_SHAPES_EDIT_DEL_POINT:
		event.Enable(m_Edit_pShape != NULL && m_Edit_iPart >= 0 && m_Edit_iPoint >= 0);
		break;

//----------stliersch----------
	case ID_CMD_SIMPLEFEATURE_GET_STATION:
		event.Enable( (m_pSimpleFeature->Get_Type() == SHAPE_TYPE_Points ||
					   m_pSimpleFeature->Get_Type() == SHAPE_TYPE_Point) &&
					   m_pSimpleFeature->Get_Selection_Count() > 0 );
		break;

	case ID_CMD_SIMPLEFEATURE_OPEN_SOILSALINITY_DLG:
		event.Enable( (
			m_pSimpleFeature->Get_Type() == SHAPE_TYPE_Polygon &&
			m_pSimpleFeature->Get_Selection_Count() > 0 &&
			m_pSimpleFeature->asSimpleFeature()->Get_SF_Category() == SF_CATEGORY_SoilSalinityMap )
			);
		break;

	case ID_CMD_SIMPLEFEATURE_LOAD_SOILSALINITY_DATA:
		event.Enable( (
			m_pSimpleFeature->Get_Type() == SHAPE_TYPE_Polygon &&
			//m_pSimpleFeature->Get_Selection_Count() > 0 &&
			m_pSimpleFeature->asSimpleFeature()->Get_SF_Category() == SF_CATEGORY_SoilSalinityMap )
			);
		break;
	
	//case ID_CMD_SIMPLEFEATURE_OPEN_SOILSALINITY_RISK_DLG:
	//	event.Enable( (
	//		m_pSimpleFeature->Get_Type() == SHAPE_TYPE_Polygon &&
	//		m_pSimpleFeature->Get_Selection_Count() > 0 &&
	//		m_pSimpleFeature->asSimpleFeature()->Get_SF_Category() == SF_CATEGORY_SoilSalinityRiskMap )
	//		);
	//	break;
	//	

	//case ID_CMD_SIMPLEFEATURE_LOAD_SOILSALINITY_RISK_DATA:
	//	event.Enable( (
	//		m_pSimpleFeature->Get_Type() == SHAPE_TYPE_Polygon &&
	//		//m_pSimpleFeature->Get_Selection_Count() > 0 &&
	//		m_pSimpleFeature->asSimpleFeature()->Get_SF_Category() == SF_CATEGORY_SoilSalinityRiskMap )
	//		);
	//	break;
//----------stliersch----------
	}

	return( true );
}


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

//---------------------------------------------------------
void CWKSP_SimpleFeature::On_Create_Parameters(void)
{
	//-----------------------------------------------------
	// General...

	_AttributeList_Add(
		m_Parameters("NODE_COLORS")		, "COLORS_ATTRIB"			, LNG("[CAP] Attribute"),
		""
	);


	//-----------------------------------------------------
	// Display...

	m_Parameters.Add_Parameters(
		m_Parameters("NODE_DISPLAY")	, "DISPLAY_CHART"			, LNG("[CAP] Chart"),
		""
	);


	//-----------------------------------------------------
	// HTML Extra info

	m_Parameters.Add_Node(
		NULL							, "NODE_EXTRAINFO"			, LNG("[CAP] Html Extra Info"),
		""
	);

	_AttributeList_Add(
		m_Parameters("NODE_EXTRAINFO")	, "EXTRAINFO_ATTRIB"		, LNG("[CAP] Attribute"),
		""
	);

	//-----------------------------------------------------
	// Label...

	m_Parameters.Add_Node(
		NULL							, "NODE_LABEL"				, LNG("[CAP] Display: Label"),
		""
	);

	_AttributeList_Add(
		m_Parameters("NODE_LABEL")		, "LABEL_ATTRIB"			, LNG("[CAP] Attribute"),
		""
	);

	m_Parameters.Add_Font(
		m_Parameters("NODE_LABEL")		, "LABEL_ATTRIB_FONT"		, LNG("[CAP] Font"),
		""
	);

	m_Parameters.Add_Choice(
		m_Parameters("NODE_LABEL")		, "LABEL_ATTRIB_SIZE_TYPE"	, LNG("[CAP] Size relates to..."),
		"",
		wxString::Format("%s|%s|",
			LNG("[VAL] Screen"),
			LNG("[VAL] Map Units")
		), 0
	);

	m_Parameters.Add_Value(
		m_Parameters("NODE_LABEL")		, "LABEL_ATTRIB_SIZE"		, LNG("[CAP] Default Size"),
		LNG(""),
		PARAMETER_TYPE_Double, 100.0, 0.0, true
	);


	//-----------------------------------------------------
	// Edit...

	m_Parameters.Add_Node(
		NULL							, "NODE_EDIT"				, LNG("[CAP] Edit"),
		""
	);

	m_Parameters.Add_Value(
		m_Parameters("NODE_EDIT")		, "EDIT_SNAP_DIST"			, LNG("[CAP] Snap Distance"),
		"",
		PARAMETER_TYPE_Int, 10, 0, true
	);

	m_Parameters.Add_SimpleFeature_List(
		m_Parameters("NODE_EDIT")		, "EDIT_SNAP_LIST"			, LNG("[CAP] Snap to..."),
		"",
		PARAMETER_INPUT
	);
}
///////////////////////////////////////////////////////////
//														 //
//														 //
//														 //
///////////////////////////////////////////////////////////


//---------------------------------------------------------
wxMenu * CWKSP_SimpleFeature::On_Edit_Get_Menu(void)
{
	wxMenu	*pMenu;

	pMenu	= new wxMenu;

	CMD_Menu_Add_Item(pMenu, true , ID_CMD_SHAPES_EDIT_SHAPE);
	CMD_Menu_Add_Item(pMenu, false, ID_CMD_SHAPES_EDIT_ADD_SHAPE);
	CMD_Menu_Add_Item(pMenu, false, ID_CMD_SHAPES_EDIT_DEL_SHAPE);
	CMD_Menu_Add_Item(pMenu, false, ID_CMD_SHAPES_EDIT_ADD_PART);
	CMD_Menu_Add_Item(pMenu, false, ID_CMD_SHAPES_EDIT_DEL_PART);
	CMD_Menu_Add_Item(pMenu, false, ID_CMD_SHAPES_EDIT_DEL_POINT);
		
	// Soil Salinity Functions
	if ( m_pSimpleFeature->Get_Type() == SHAPE_TYPE_Polygon ) {

		// Soil Salinity Assessment
		if ( m_pSimpleFeature->asSimpleFeature()->Get_SF_Category() == SF_CATEGORY_SoilSalinityMap ) {
			
			pMenu->AppendSeparator();

			CMD_Menu_Add_Item(pMenu, false, ID_CMD_SIMPLEFEATURE_LOAD_SOILSALINITY_DATA);
			
			if ( m_pSimpleFeature->Get_Selection_Count() > 0 ) {
				CMD_Menu_Add_Item(pMenu, false, ID_CMD_SIMPLEFEATURE_OPEN_SOILSALINITY_DLG);
			}
		}
		
		// Soil Salinity Risk
		if ( m_pSimpleFeature->asSimpleFeature()->Get_SF_Category() == SF_CATEGORY_SoilSalinityRiskMap ) {
			
			pMenu->AppendSeparator();
			
			CMD_Menu_Add_Item(pMenu, false, ID_CMD_SIMPLEFEATURE_LOAD_SOILSALINITY_RISK_DATA);
			
			if ( m_pSimpleFeature->Get_Selection_Count() > 0 ) {
				CMD_Menu_Add_Item(pMenu, false, ID_CMD_SIMPLEFEATURE_OPEN_SOILSALINITY_RISK_DLG);
			}
		}
	}
	return( pMenu );
}





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



bool CWKSP_SimpleFeature::Get_Station_Data()
{
	wxString		PK_ColumnName;	// Column name of the SimpleFeature's primary key column
	int				PK_ColumnNumber;// Column number of the SimpleFeature's primary key
	wxArrayString	aPK_Value_str;	// Primary key value as wxString
	wxArrayString	aStationName;	// Name(s) of the corresponding gauging station(s)

	// Get LookUp table name as well as SimpleFeature's primary key column number and name
	wxString LUT_Name = _Select_LU_Table(PK_ColumnNumber, PK_ColumnName);
		
	if (LUT_Name != "")
	{
		for (int i = 0; i < m_pSimpleFeature->Get_Selection_Count(); i++)
		{
			// Get selected primary key value (representing station id) as wxString
			aPK_Value_str.Add(m_pSimpleFeature->Get_Selection(i)->Get_Record()->asString(PK_ColumnNumber));
			// Get station name(s) corresponding to selected station(s)
			aStationName =_Get_Station_TableName(aPK_Value_str[i], LUT_Name, PK_ColumnName);
			// Import Table(s) StationName from database
			for (unsigned int j = 0; j < aStationName.size(); j++)
				_ImportTable(aStationName[j]);
		}
	}

	return(true);
}
//---------------------------------------------------------

wxString CWKSP_SimpleFeature::_Select_LU_Table(int &PK_ColumnNumber, wxString &PK_ColumnName)
{
	// returns the name of the corresponding LookUp table
	// as well as the name and column number of the SimpleFeature's primary key column
	//-----------------------------------------------------
	// DIALOG
	//-----------------------------------------------------
	CSG_Parameters	P;

	P.Set_Name(LNG("Select LookUp Table"));

	P.Add_Choice(
		NULL	, "TABLE"	, LNG("Select LookUp Table"),
		"",
		_Get_LU_Tables_Only().c_str()
	);

	P.Add_Choice(
		NULL	, "PK_Col"	, LNG("Select Primary Key Column"),
		"",
		_Get_Column_Names().c_str()
	);

	if( DLG_Parameters(&P) )
	{
		PK_ColumnName	= P("PK_Col")->asString();
		PK_ColumnNumber = P("PK_Col")->asInt();
		return(P("TABLE")->asString());
	} else {
		return("");
	}
}
//---------------------------------------------------------

wxString CWKSP_SimpleFeature::_Get_LU_Tables_Only()
{
	// returns a wxString containing
	// only LookUp table names (names starting with 'lu_')
	wxArrayString All_Tables = g_pSAGA_Frame->db->GetDBTablesArray();
	wxString LU_Tables;

	for (unsigned int i = 0; i < All_Tables.size(); i++)
	{
		if (   All_Tables[i].compare(0,2,"lu_",0,2) == 0
			|| All_Tables[i].compare(0,2,"LU_",0,2) == 0)
		{
			LU_Tables.Append(All_Tables[i]);
			LU_Tables.Append("|");
		}
	}
	return(LU_Tables);
}
//---------------------------------------------------------

wxString CWKSP_SimpleFeature::_Get_Column_Names()
{
	// returns the column names of the current SimpleFeature
	wxString ColNames;
	//for (int i = 0; i < m_pShapes->Get_Table().Get_Field_Count(); i++)
	for (int i = 0; i < m_pSimpleFeature->Get_Table().Get_Field_Count(); i++)
	{
		//ColNames.Append(m_pShapes->Get_Table().Get_Field_Name(i));
		ColNames.Append(m_pSimpleFeature->Get_Table().Get_Field_Name(i));
		ColNames.Append("|");
	}
	return(ColNames);
}
//---------------------------------------------------------

wxArrayString CWKSP_SimpleFeature::_Get_Station_TableName(wxString PK_Value_str, wxString LU_TableName, wxString PK_ColumnName)
{
	Csqltable		*sqltable = new Csqltable();
	wxArrayString	aStationName;
	wxString		sql = "SELECT * FROM ";

	// Create query
	sql.Append(LU_TableName);
	sql.Append(" WHERE ");
	sql.Append(PK_ColumnName);
	sql.Append(" = ");
	sql.Append(PK_Value_str);

	// send query
	if (g_pSAGA_Frame->db->GetSelection(sqltable, sql))
	{
		if (sqltable->Get_nrows() > 0)
		{
			for (int i = 0; i < sqltable->Get_nrows(); i++)
				// Assuming that the station name is stored in the second column !!!
				aStationName.Add(sqltable->GetValue(1,i).c_str());
		}
	}
	delete sqltable;

	return(aStationName);
}
//---------------------------------------------------------

void CWKSP_SimpleFeature::_ImportTable(wxString tablename)
{
	Cmenu_db		menu;
	CSG_Table		*pTable;
	Csqltable		*psqltable;
	psqltable = new Csqltable(tablename.c_str(),
							  g_pSAGA_Frame->db->GetNumberCols(tablename.c_str()),
							  g_pSAGA_Frame->db->GetNumberRows(tablename.c_str()));

	if (g_pSAGA_Frame->db->ReadTable(psqltable))
	{
		MSG_ADD(wxString::Format("%s%s%s", "Read Table '", tablename.c_str(), "' successfull"));
		//-----------------------------------------------------
		// create SAGA Table from database table
		pTable = SG_Create_Table();
		menu.CreateSAGATable(psqltable, pTable);
				
		// add table to SAGA Workspace
		pTable->Set_Name(tablename.c_str());
		g_pData->Add(pTable);

		delete psqltable;

	} else {
		MSG_ADD("Read Table not successfull");
	}
}


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

void CWKSP_SimpleFeature::Open_SoilSalinity_Dlg(CSG_SimpleFeature* pSimpleFeature)
{
	CSoilSalinityMap*	pSSMap;
	pSSMap = new CSoilSalinityMap(pSimpleFeature);

	CSoilSalinityAssessmentDlg* pSoilSalinityDlg = new CSoilSalinityAssessmentDlg(pSSMap, g_pSAGA_Frame, -1, "Soil Salinity Assessment");
	pSoilSalinityDlg->ShowModal();
	
	delete pSoilSalinityDlg;
	delete pSSMap;
}
//---------------------------------------------------------

void CWKSP_SimpleFeature::Load_SoilSalinityData(CSG_SimpleFeature* pSimpleFeature)
{
	CSoilSalinityMap* pSSMap;
	pSSMap = new CSoilSalinityMap(pSimpleFeature);

	CSoilSalinityLoadDataDlg* pSoilSalinityLoadDataDlg = new CSoilSalinityLoadDataDlg(pSSMap, g_pSAGA_Frame, -1, "Load Soil Salinity Assessment Data");
	pSoilSalinityLoadDataDlg->ShowModal();

	delete pSoilSalinityLoadDataDlg;
	delete pSSMap;
}
//---------------------------------------------------------
//
//void CWKSP_SimpleFeature::Open_SoilSalinityRisk_Dlg(CSG_SimpleFeature* pSimpleFeature)
//{
//	CSoilSalinityRiskDlg* pSoilSalinityRiskDlg = new CSoilSalinityRiskDlg(pSimpleFeature, g_pSAGA_Frame, -1, "Soil Salinity Risk");
//	pSoilSalinityRiskDlg->ShowModal();
//	delete pSoilSalinityRiskDlg;
//}
////---------------------------------------------------------
//
//void CWKSP_SimpleFeature::Load_SoilSalinityRiskData(CSG_SimpleFeature* pSimpleFeature)
//{
//	CSoilSalinityLoadRiskDataDlg* pSoilSalinityLoadRiskDataDlg = new CSoilSalinityLoadRiskDataDlg(pSimpleFeature, g_pSAGA_Frame, -1, "Load Soil Salinity Risk Data");
//	pSoilSalinityLoadRiskDataDlg->Show();
//}