/**
	@license GNU GPLv2
	PROJECT "trovacap"
	Copyright © 2006 Danilo Cicerone

	This program 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; either version 2 of the License, or
	(at your option) any later version.

	This program 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/

/**
	@file trovacap.cxx
	@author Danilo Cicerone info@digitazero.org
	@date 2006-12-05
	@version 0.2.2
*/

#include "trovacap.h"

/*----------------------------------------------------------------------------*/

TCWin::TCWin()
{
	win_main = new Fl_Window((Fl::w() - winW)/2, (Fl::h() - winH)/2, winW, winH,
		"trovacap 0.2.2");
	win_main->callback((Fl_Callback*)cb_win_main, (void*)(this));
	win_main->when(FL_WHEN_RELEASE_ALWAYS);
	win_main->begin();
	{
		txt_loca = new Fl_Input(5, 20, 200, 25, "Localitą\\Comune\\Frazione");
		txt_loca->align(FL_ALIGN_TOP_LEFT);
		txt_loca->callback((Fl_Callback*)cb_txt_loca, (void*)(this));
		txt_loca->when(FL_WHEN_CHANGED);

		cbo_prov = new Fl_Choice(235, 20, 200, 25, "Provincia");
		cbo_prov->menu(mnu_prov);
		cbo_prov->align(FL_ALIGN_TOP_LEFT);
		cbo_prov->when(FL_WHEN_CHANGED);
		cbo_prov->callback((Fl_Callback*)cb_cbo_prov, (void*)(this));

		txt_topo = new Fl_Input(5, 65, 200, 25, "Toponimo");
		txt_topo->align(FL_ALIGN_TOP_LEFT);
		txt_topo->callback((Fl_Callback*)cb_txt_topo, (void*)(this));
		txt_topo->when(FL_WHEN_CHANGED);

		txt_fcap = new Fl_Input(235, 65, 200, 25, "CAP");
		txt_fcap->align(FL_ALIGN_TOP_LEFT);
		txt_fcap->callback((Fl_Callback*)cb_txt_fcap, (void*)(this));
		txt_fcap->when(FL_WHEN_CHANGED);

		btn_find = new Fl_Return_Button(450, 5, 100, 85, "&Trova");
		btn_find->callback((Fl_Callback*)cb_btn_find, (void*)(this));
		btn_find->image(image_search);

		btn_help = new Fl_Button(570, 5, 100, 25, "&Help");
		btn_help->callback((Fl_Callback*)cb_btn_help, (void*)(this));

		btn_info = new Fl_Button(570, 35, 100, 25, "&Info");
		btn_info->callback((Fl_Callback*)cb_btn_info, (void*)(this));

		btn_esci = new Fl_Button(690, 5, 100, 25, "&Esci");
		btn_esci->callback((Fl_Callback*)cb_btn_esci, (void*)(this));

		lbl_data = new Fl_Output(25, 25, 25, 25, "");
		lbl_data->hide();

		tb_loca = new DB_Table(5, 95, winW - 10, winH - 95, "");
		tb_loca->selection_color(FL_SELECTION_COLOR);
		tb_loca->when(FL_WHEN_RELEASE);
		tb_loca->xTable.resize(0 * cLoc, "");
		tb_loca->xTable_Header.resize(cLoc, "-");
		tb_loca->xTable_Header[0] = "D.U.G.";
		tb_loca->xTable_Header[1] = "Toponimo";
		tb_loca->xTable_Header[2] = "Civici";
		tb_loca->xTable_Header[3] = "CAP";
		tb_loca->xTable_Header[4] = "Localitą\\Comune";
		tb_loca->xTable_Header[5] = "Frazione";
		tb_loca->xTable_Header[6] = "Prov.";
		tb_loca->rows(0);
		tb_loca->cols(cLoc);
		tb_loca->col_header(1);
		tb_loca->col_resize(4);
		tb_loca->row_header(0);
		tb_loca->col_width(0, 60);
		tb_loca->col_width(1, 160);
		tb_loca->col_width(2, 80);
		tb_loca->col_width(3, 50);
		tb_loca->col_width(4, 160);
		tb_loca->col_width(5, 160);
		tb_loca->col_width(6, 40);
		tb_loca->callback((Fl_Callback*)cb_tb_loca, (void*)(this));
		tb_loca->end();
	}
	win_main->resizable(tb_loca);
	win_main->end();

#if defined(WIN32)
	// Nothing to do here (Dev-C++ solve this problem)
#elif defined(__APPLE__)
	// Nothing to do here
#else
	fl_open_display();
	Pixmap mask, p;
	XpmCreatePixmapFromData(fl_display, DefaultRootWindow(fl_display),
	trovacap_xpm, &p, &mask, NULL);

	win_main->icon((char *)p);
#endif

	int rc;
	rc = sqlite3_open("./trovacap.db", &db);
	if (rc)
	{
		fl_message("Database Error: %s", sqlite3_errmsg(db));
		sqlite3_close(db);
		exit(0);
	}
	load_prov();
}

/*----------------------------------------------------------------------------*/

Fl_Menu_Item TCWin::mnu_prov[] =
{
	{"", 0, 0, 0},
	{0}
};

/*----------------------------------------------------------------------------*/

TCWin::~TCWin()
{
	delete win_main;
}

/*----------------------------------------------------------------------------*/

void
TCWin::show()
{
	win_main->show();
}

/*----------------------------------------------------------------------------*/

void
TCWin::hide()
{
	win_main->hide();
}

/*----------------------------------------------------------------------------*/

int
TCWin::visible()
{
	return win_main->visible();
}

/*----------------------------------------------------------------------------*/

inline void
TCWin::cb_win_main_i()
{
	sqlite3_close(db);
	exit(0);
}

/*----------------------------------------------------------------------------*/

void
TCWin::cb_win_main(Fl_Window* o, void* v)
{
	((TCWin*)(o->user_data()))->cb_win_main_i();
}

/*----------------------------------------------------------------------------*/

inline void
TCWin::cb_txt_loca_i()
{
	btn_find->color((Fl_Color)94);
	btn_find->redraw();
}

/*----------------------------------------------------------------------------*/

void
TCWin::cb_txt_loca(Fl_Input* o, void* v)
{
	((TCWin*)(o->parent()->user_data()))->cb_txt_loca_i();
}

/*----------------------------------------------------------------------------*/

inline void
TCWin::cb_txt_fcap_i()
{
	btn_find->color((Fl_Color)94);
	btn_find->redraw();
}

/*----------------------------------------------------------------------------*/

void
TCWin::cb_txt_fcap(Fl_Input* o, void* v)
{
	((TCWin*)(o->parent()->user_data()))->cb_txt_loca_i();
}

/*----------------------------------------------------------------------------*/

inline void
TCWin::cb_txt_topo_i()
{
	btn_find->color((Fl_Color)94);
	btn_find->redraw();
}

/*----------------------------------------------------------------------------*/

void
TCWin::cb_txt_topo(Fl_Input* o, void* v)
{
	((TCWin*)(o->parent()->user_data()))->cb_txt_topo_i();
}

/*----------------------------------------------------------------------------*/

void
TCWin::cb_btn_find(Fl_Button* o, void* v)
{
	static_cast<TCWin *>(v)->build_query();
}

/*----------------------------------------------------------------------------*/

inline void
TCWin::cb_cbo_prov_i()
{
	btn_find->color((Fl_Color)94);
	btn_find->redraw();
}

/*----------------------------------------------------------------------------*/

void
TCWin::cb_cbo_prov(Fl_Choice* o, void* v)
{
	static_cast<TCWin *>(v)->cb_cbo_prov_i();
}

/*----------------------------------------------------------------------------*/

inline void
TCWin::load_prov()
{
	int rc;
	string sql;
	sqlite3_stmt *pStmt;

	sql = "SELECT prov_cap FROM tab_cap GROUP BY prov_cap ORDER BY prov_cap;";
	do
	{
		rc = sqlite3_prepare(db, sql.c_str() , -1, &pStmt, 0);
		if (rc != SQLITE_OK)
		{
			fl_alert("Error in sqlite3_prepare: %s\n", sqlite3_errmsg(db));
			exit(0);
			break;
		}

		while (SQLITE_ROW == sqlite3_step(pStmt))
		{
			cbo_prov->add((char*)sqlite3_column_text(pStmt, 0), 0, 0, 0);
		}
		rc = sqlite3_finalize(pStmt);

	} while(rc == SQLITE_SCHEMA);
}

/*----------------------------------------------------------------------------*/

inline void
TCWin::build_query()
{
	int rc;
	int tot_rows = 0;
	string sql;
	string app;
	sqlite3_stmt *pStmt;

//	fl_message("OK build_query");

	sql.clear();

	app.clear();
	app = txt_loca->value();
	if (app.length() > 0)
	{
		sql += sqlite3_mprintf("(comu_cap LIKE '%%%q%%' OR com2_cap LIKE '%%%q%%' OR fraz_cap LIKE '%%%q%%' OR fra2_cap LIKE '%%%q%%')"
			,txt_loca->value(),txt_loca->value(),txt_loca->value(),txt_loca->value());
		sql += " AND ";
	}

	app.clear();
	app = cbo_prov->text(cbo_prov->value());
	if (app.length() > 0)
	{
		sql += sqlite3_mprintf("prov_cap='%q'"
			,cbo_prov->text(cbo_prov->value()));
		sql += " AND ";
	}

	app.clear();
	app = txt_topo->value();
	if (app.length() > 0)
	{
		sql += sqlite3_mprintf("(topo_cap LIKE '%%%q%%' OR top2_cap LIKE '%%%q%%')"
			,txt_topo->value(), txt_topo->value());
		sql += " AND ";
	}

	app.clear();
	app = txt_fcap->value();
	if (app.length() > 0)
	{
		sql += sqlite3_mprintf("(capi_cap LIKE '%%%q%%')"
			,txt_fcap->value());
		sql += " AND ";
	}

//	fl_message("[%s]", sql.c_str());

	if (sql.length() == 0) return;
	else
		{
			sql = sql.substr(0, sql.length() - 5);
			sql += " ORDER BY prov_cap, comu_cap;";
		}

	sql += ";";

	app.clear();
	app = "SELECT count(capi_cap) FROM tab_cap WHERE " + sql;
	do
	{
		rc = sqlite3_prepare(db, app.c_str(), -1, &pStmt, 0);
		if (rc != SQLITE_OK)
		{
			fl_alert("Error in sqlite3_prepare: %s\n", sqlite3_errmsg(db));
			break;
		}

		while (SQLITE_ROW == sqlite3_step(pStmt))
		{
			tot_rows = sqlite3_column_int(pStmt, 0);
		}
		rc = sqlite3_finalize(pStmt);

	} while(rc == SQLITE_SCHEMA);

	sql = "SELECT * FROM tab_cap WHERE " + sql;
//	fl_message("[%s]", sql.c_str());

	tb_loca->xTable.clear();
	do
	{
		rc = sqlite3_prepare(db, sql.c_str(), -1, &pStmt, 0);
		if (rc != SQLITE_OK)
		{
			fl_alert("Error in sqlite3_prepare: %s\n", sqlite3_errmsg(db));
			break;
		}

		while (SQLITE_ROW == sqlite3_step(pStmt))
		{
			// dugt_cap
			tb_loca->xTable.push_back((char*)sqlite3_column_text(pStmt, 8));
			// topo_cap
			tb_loca->xTable.push_back((char*)sqlite3_column_text(pStmt, 6));
			// nciv_cap
			tb_loca->xTable.push_back((char*)sqlite3_column_text(pStmt, 9));
			// capi_cap
			tb_loca->xTable.push_back((char*)sqlite3_column_text(pStmt, 10));
			// comu_cap
			tb_loca->xTable.push_back((char*)sqlite3_column_text(pStmt, 2));
			// fraz_cap
			tb_loca->xTable.push_back((char*)sqlite3_column_text(pStmt, 4));
			// prov_cap
			tb_loca->xTable.push_back((char*)sqlite3_column_text(pStmt, 1));
		}
		rc = sqlite3_finalize(pStmt);

	} while(rc == SQLITE_SCHEMA);

	tb_loca->rows(tot_rows);
	tb_loca->cols(cLoc);

	btn_find->color(FL_BACKGROUND_COLOR);
	btn_find->redraw();
}

/*----------------------------------------------------------------------------*/

inline void
TCWin::cb_tb_loca_i()
{
	int idx = 0;
	int ids = 0;
	int i;

	if ((int)tb_loca->callback_context() == 0x08) return;
	
	idx = ((int)tb_loca->callback_row() * cLoc) + cLoc - 1;
	ids = ((int)tb_loca->callback_row() * cLoc);

	if (idx >= 0)
	{
		sigp.clear();
		for (i = 0; ids <= idx; ids++, i++)
		{
			if (tb_loca->xTable[ids].empty()) continue;
			switch (i)
			{
				case 0:
				case 3:
				case 4:
				case 5:
					sigp += tb_loca->xTable[ids].c_str();
					sigp += " ";
					break;
				case 1:
					sigp += tb_loca->xTable[ids].c_str();
					sigp += " \n";
					break;
				case 6:
					sigp += tb_loca->xTable[ids].c_str();
					break;
			}
		}
/*
		fprintf(stderr, "index=%d\n", idx);
		fprintf(stderr, "value 1=%s\n", tb_loca->xTable[idx].c_str());
		fprintf(stderr, "index=%d\n", ids);
		fprintf(stderr, "value 2=%s\n", tb_loca->xTable[ids].c_str());
*/
		lbl_data->value(sigp.c_str());
		lbl_data->position(0, sigp.size());
		lbl_data->copy(1);
	}
}

/*----------------------------------------------------------------------------*/

void
TCWin::cb_tb_loca(Fl_Widget* o, void* v)
{
	static_cast<TCWin *>(v)->cb_tb_loca_i();
}
/*----------------------------------------------------------------------------*/

inline void
TCWin::cb_btn_help_i()
{
	WinHelp *win = new WinHelp();

	if (win->standby())
	{
		//fl_message("OK");
	}

	delete win;
}

/*----------------------------------------------------------------------------*/

void
TCWin::cb_btn_help(Fl_Button* o, void* v)
{
	static_cast<TCWin *>(v)->cb_btn_help_i();
}

/*----------------------------------------------------------------------------*/

inline void
TCWin::cb_btn_info_i()
{
	WinInfo *win = new WinInfo();

	if (win->standby())
	{
		//fl_message("OK");
	}

	delete win;
}

/*----------------------------------------------------------------------------*/

void
TCWin::cb_btn_info(Fl_Button* o, void* v)
{
	static_cast<TCWin *>(v)->cb_btn_info_i();
}

/*----------------------------------------------------------------------------*/

inline void
TCWin::cb_btn_esci_i()
{
	cb_win_main_i();
}

/*----------------------------------------------------------------------------*/

void
TCWin::cb_btn_esci(Fl_Button* o, void* v)
{
	static_cast<TCWin *>(v)->cb_btn_esci_i();
}
