#ifndef MAKE_ID
#define MAKE_ID(a,b,c,d) ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))
#endif

#ifdef __cplusplus
extern "C"
{
#endif

/* Libraries */
#include <libraries/mui.h>
#include <libraries/gadtools.h> /* for Barlabel in MenuItem */
#include <exec/memory.h>

/* Prototypes */
#include <proto/muimaster.h>
#include <proto/exec.h>
#include <clib/alib_protos.h>

#include <MUI/NListview_mcc.h>
#include <MUI/NFloattext_mcc.h>

#ifdef __cplusplus
}
#endif


#include <SearchGUI.h>

struct Hook ads_RecordFillHook;
struct Hook ads_RecordConstructHook;
struct Hook ads_RecordDestructHook;
struct Hook ads_RecordCompareHook;

char *GetMBString(APTR ref)
{
	char *aux;

	aux = Get_SearcherString(ref);
	if (aux[1] == '\0') return(&aux[2]);
	else                return(aux);
}

STRPTR *cy_FieldNames = NULL;

SearchGUI::SearchGUI(char* host,char* database,char* table)
{
	APTR	MN_Project = NULL, GROUP_ROOT_SEARCH = NULL, GR_Field_Request = NULL;
	APTR	Space_1 = NULL , GR_Add_Critera = NULL, Space_3 = NULL, GR_Query = NULL, Space_2 = NULL, GR_Action_Buttons = NULL;
	APTR	Space_0 = NULL , REC_label_1 = NULL , GR_DataBase_Info = NULL, obj_aux0 = NULL, obj_aux1 = NULL, LA_DataBase = NULL;
	APTR	LA_Table = NULL, GR_Results = NULL, GR_Status = NULL;

	db_ID = "SearchGUI";

	cy_FieldNames = NULL;
	sg_Host = host;
	sg_Database = database;
	sg_Table = table;

	APL_Search 		= NULL;
	MN_Menu 			= NULL;
	MN_Quit 			= NULL;
	WI_Search 		= NULL;
	GR_Search_Regs = NULL;
	GR_Criteria 	= NULL;
	BT_Add 			= NULL;
	BT_Remove 		= NULL;
	STR_Query 		= NULL;
	BT_Search 		= NULL;
	BT_Quit 			= NULL;
	STR_DB_Server 	= NULL;
	PO_DataBase 	= NULL;
	STR_PO_DataBase= NULL;
	LV_DataBase 	= NULL;
	PO_Table 		= NULL;
	STR_PO_Table 	= NULL;
	LV_Table 		= NULL;
	LV_Results 		= NULL;
	STR_Status 		= NULL;

	InstallHook(&ads_RecordFillHook,&ads_RecordFillFunc,NULL);
	InstallHook(&ads_RecordConstructHook,&ads_RecordConstructFunc,NULL);
	InstallHook(&ads_RecordDestructHook,&ads_RecordDestructFunc,NULL);
	InstallHook(&ads_RecordCompareHook,&ads_RecordCompareFunc,NULL);

	ads_RecordFillHook.h_Data = db_ID;

	STR_GR_Search_Regs[0] = GetMBString(MSG_GR_Search_Regs0);
	STR_GR_Search_Regs[1] = GetMBString(MSG_GR_Search_Regs1);
	STR_GR_Search_Regs[2] = NULL;

	// This is a dynamic group !

	GR_Criteria = GroupObject,
		MUIA_HelpNode, "GR_Criteria",
	End;

	AR_Criteria.InsertAt(0,new Criteria((Object*)GR_Criteria));

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

	Space_1 = HVSpace;

	Space_3 = HVSpace;

	BT_Add = TextObject,
		ButtonFrame,
		MUIA_Weight, 10,
		MUIA_Background, MUII_ButtonBack,
		MUIA_ControlChar, Get_SearcherString(MSG_BT_Add)[0],
		MUIA_Text_Contents, GetMBString(MSG_BT_Add),
		MUIA_Text_PreParse, "\033c",
		MUIA_Text_HiChar, Get_SearcherString(MSG_BT_Add)[0],
		MUIA_HelpNode, "BT_Add",
		MUIA_InputMode, MUIV_InputMode_RelVerify,
	End;

	BT_Remove = TextObject,
		ButtonFrame,
		MUIA_Weight, 10,
		MUIA_Background, MUII_ButtonBack,
		MUIA_ControlChar, Get_SearcherString(MSG_BT_Remove)[0],
		MUIA_Text_Contents, GetMBString(MSG_BT_Remove),
		MUIA_Text_PreParse, "\033c",
		MUIA_Text_HiChar, Get_SearcherString(MSG_BT_Remove)[0],
		MUIA_HelpNode, "BT_Remove",
		MUIA_InputMode, MUIV_InputMode_RelVerify,
	End;

	GR_Add_Critera = GroupObject,
		MUIA_HelpNode, "GR_Add_Critera",
		MUIA_Group_Horiz, TRUE,
		MUIA_Group_SameSize, TRUE,
		Child, Space_3,
		Child, BT_Add,
		Child, BT_Remove,
	End;

	GR_Field_Request = GroupObject,
		MUIA_HelpNode, "GR_Field_Request",
		Child, GR_Criteria,
		Child, Space_1,
		Child, GR_Add_Critera,
	End;

	STR_Query = StringObject,
		MUIA_Frame, MUIV_Frame_String,
		MUIA_HelpNode, "STR_Query",
		MUIA_String_Contents, "",
		MUIA_String_MaxLen, 256,
	End;

	Space_2 = HVSpace;

	GR_Query = GroupObject,
		MUIA_HelpNode, "GR_Query",
		Child, GroupObject,
			MUIA_Group_Horiz, TRUE,
				Child, Label("SELECT "),
				Child, STR_Query,
			End,
		Child, Space_2,
	End;

	GR_Search_Regs = RegisterObject,
		MUIA_Register_Titles, STR_GR_Search_Regs,
		MUIA_HelpNode, "GR_Search_Regs",
		MUIA_Weight, 25,
		Child, GR_Field_Request,
		Child, GR_Query,
	End;

	BT_Search = TextObject,
		ButtonFrame,
		MUIA_Weight, 15,
		MUIA_Background, MUII_ButtonBack,
		MUIA_ControlChar, Get_SearcherString(MSG_BT_Search)[0],
		MUIA_Text_Contents, GetMBString(MSG_BT_Search),
		MUIA_Text_PreParse, "\033c",
		MUIA_Text_HiChar, Get_SearcherString(MSG_BT_Search)[0],
		MUIA_HelpNode, "BT_Search",
		MUIA_InputMode, MUIV_InputMode_RelVerify,
	End;

	Space_0 = HVSpace;

	BT_Quit = TextObject,
		ButtonFrame,
		MUIA_Weight, 15,
		MUIA_Background, MUII_ButtonBack,
		MUIA_ControlChar, Get_SearcherString(MSG_BT_Quit)[0],
		MUIA_Text_Contents, GetMBString(MSG_BT_Quit),
		MUIA_Text_PreParse, "\033c",
		MUIA_Text_HiChar, Get_SearcherString(MSG_BT_Quit)[0],
		MUIA_HelpNode, "BT_Quit",
		MUIA_InputMode, MUIV_InputMode_RelVerify,
	End;

	GR_Action_Buttons = GroupObject,
		MUIA_HelpNode, "GR_Action_Buttons",
		MUIA_Weight, 0,
		MUIA_Group_Horiz, TRUE,
		MUIA_Group_SameSize, TRUE,
		Child, BT_Search,
		Child, Space_0,
		Child, BT_Quit,
	End;

	REC_label_1 = RectangleObject,
		MUIA_Rectangle_HBar, TRUE,
		MUIA_FixHeight, 8,
	End;

	STR_DB_Server = StringObject,
		MUIA_Frame, MUIV_Frame_String,
		MUIA_ControlChar, Get_SearcherString(MSG_STR_DB_Server)[0],
		MUIA_HelpNode, "STR_DB_Server",
//		MUIA_String_Contents, "localhost",
	End;

	obj_aux1 = KeyLabel2(GetMBString(MSG_STR_DB_Server), Get_SearcherString(MSG_STR_DB_Server)[0]);

	obj_aux0 = GroupObject,
		MUIA_Group_Columns, 2,
		Child, obj_aux1,
		Child, STR_DB_Server,
	End;

	LA_DataBase = Label(GetMBString(MSG_LA_DataBase));

	LV_DataBase = ListObject,
		MUIA_Frame, MUIV_Frame_InputList,
	End;

	LV_DataBase = ListviewObject,
		MUIA_HelpNode, "LV_DataBase",
		MUIA_Listview_DoubleClick, TRUE,
		MUIA_Listview_List, LV_DataBase,
	End;

	STR_PO_DataBase = String("", 80);

	PO_DataBase = PopobjectObject,
		MUIA_HelpNode, "PO_DataBase",
		MUIA_Popstring_String, STR_PO_DataBase,
		MUIA_Popstring_Button, PopButton(MUII_PopUp),
		MUIA_Popobject_Object, LV_DataBase,
	End;

	LA_Table = Label(GetMBString(MSG_LA_Table));

	LV_Table = ListObject,
		MUIA_Frame, MUIV_Frame_InputList,
	End;

	LV_Table = ListviewObject,
		MUIA_HelpNode, "LV_Table",
		MUIA_Listview_DoubleClick, TRUE,
		MUIA_Listview_List, LV_Table,
	End;

	STR_PO_Table = String("", 80);

	PO_Table = PopobjectObject,
		MUIA_HelpNode, "PO_Table",
		MUIA_Popstring_String, STR_PO_Table,
		MUIA_Popstring_Button, PopButton(MUII_PopUp),
		MUIA_Popobject_Object, LV_Table,
	End;

	GR_DataBase_Info = GroupObject,
		MUIA_HelpNode, "GR_DataBase_Info",
		MUIA_Group_Horiz, TRUE,
		Child, obj_aux0,
		Child, LA_DataBase,
		Child, PO_DataBase,
		Child, LA_Table,
		Child, PO_Table,
	End;

	LV_Results = NListObject,
		MUIA_Frame, MUIV_Frame_ReadList,
		MUIA_NList_Input, TRUE,
		MUIA_NList_MultiSelect, MUIV_Listview_MultiSelect_Default,
    	MUIA_NList_ConstructHook,&ads_RecordConstructHook,
    	MUIA_NList_DestructHook,&ads_RecordDestructHook,
    	MUIA_NList_DisplayHook,&ads_RecordFillHook,
    	MUIA_NList_CompareHook,&ads_RecordCompareHook,
      MUIA_NList_Format, "BAR W=-1",
      MUIA_NList_AutoVisible, TRUE,
      MUIA_NList_TitleSeparator, TRUE,
      MUIA_NList_Title, TRUE,
      MUIA_NList_EntryValueDependent, TRUE,
	End;

	LV_Results = NListviewObject,
		MUIA_HelpNode, "LV_Results",
		MUIA_NListview_NList, LV_Results,
		MUIA_Listview_Input, TRUE,
	End;

	GR_Results = GroupObject,
		MUIA_HelpNode, "GR_Results",
		MUIA_Frame, MUIV_Frame_Group,
		MUIA_FrameTitle, GetMBString(MSG_GR_ResultsTitle),
		Child, LV_Results,
	End;

	STR_Status = StringObject,
		MUIA_Frame, MUIV_Frame_String,
		MUIA_HelpNode, "STR_Status",
		MUIA_String_Contents, "idle...",
		MUIA_String_MaxLen, 256,
	End;

	GR_Status = GroupObject,
		MUIA_HelpNode, "GR_Status",
		MUIA_Group_Horiz, TRUE,
		Child, Label("Status:"),
		Child, STR_Status,
	End;

	GROUP_ROOT_SEARCH = GroupObject,
		Child, GR_Search_Regs,
		Child, GR_Action_Buttons,
		Child, REC_label_1,
		Child, GR_DataBase_Info,
		Child, GR_Results,
		Child, GR_Status,
	End;

	WI_Search = WindowObject,
		MUIA_Window_Title, GetMBString(MSG_WI_Searcher),
		MUIA_Window_ID, MAKE_ID('S', 'E', 'A', 'R'),
		WindowContents, GROUP_ROOT_SEARCH,
	End;

	MN_Quit = MenuitemObject,
		MUIA_Menuitem_Title, GetMBString(MSG_MN_Quit),
		MUIA_Menuitem_Shortcut, GetMBString(MSG_MN_QuitChar),
	End;

	MN_Project = MenuitemObject,
		MUIA_Menuitem_Title, GetMBString(MSG_MN_Project),
		MUIA_Family_Child, MN_Quit,
	End;

	MN_Menu = MenustripObject,
		MUIA_Family_Child, MN_Project,
	End;

	APL_Search = ApplicationObject,
		MUIA_Application_Author, "Jürgen Schober",
		MUIA_Application_Menustrip, MN_Menu,
		MUIA_Application_Base, "ADAC",
		MUIA_Application_Title, "ADAC Search",
		MUIA_Application_Version, "$VER: ADAC Search 0.02 (09.06.99)",
		MUIA_Application_Copyright, GetMBString(MSG_AppCopyright),
		MUIA_Application_Description, GetMBString(MSG_AppDescription),
		SubWindow, WI_Search,
	End;

	if (!APL_Search)
		throw("Constructor failed: Could not initialize the GUI!");

	InitGUI();
}

SearchGUI::~SearchGUI()
{
	MUI_DisposeObject(APL_Search);
}

void SearchGUI::InitGUI()
{
	if (!APL_Search)
		throw("InitGUI(): GUI not initialized");

	DoMethod(MN_Quit,
		MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
		WI_Search,
		3,
		MUIM_Set, MUIA_Window_Open, FALSE
		);

	DoMethod(MN_Quit,
		MUIM_Notify, MUIA_Menuitem_Trigger, MUIV_EveryTime,
		APL_Search,
		2,
		MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit
		);

	DoMethod(WI_Search,
		MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
		WI_Search,
		3,
		MUIM_Set, MUIA_Window_Open, FALSE
		);

	DoMethod(WI_Search,
		MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
		APL_Search,
		2,
		MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit
		);

	DoMethod(BT_Quit,
		MUIM_Notify, MUIA_Pressed, FALSE,
		APL_Search,
		2,
		MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit
		);

	DoMethod(BT_Quit,
		MUIM_Notify, MUIA_Pressed, FALSE,
		WI_Search,
		3,
		MUIM_Set, MUIA_Window_Open, FALSE
		);

	// --- Setup base methods ---

	DoMethod(STR_DB_Server,
		MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_FILL_DATABASE_LIST
		);

	DoMethod(LV_DataBase,
		MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_POP_SELECT_DATABASE
	);

	DoMethod(LV_DataBase,
		MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
		PO_DataBase,
		2,
		MUIM_Popstring_Close, TRUE
	);

	DoMethod(STR_PO_DataBase,
		MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_FILL_TABLE_LIST
		);

	DoMethod(LV_Table,
		MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_POP_SELECT_TABLE
	);

	DoMethod(LV_Table,
		MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
		PO_Table,
		2,
		MUIM_Popstring_Close, TRUE
	);

	// --- binding of dynamic object !

	Criteria *cr = AR_Criteria[0];

	DoMethod(cr->STR_Value(),
		MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_CREATE_QUERY_STRING
		);

	DoMethod(cr->STR_Value(),
		MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
		WI_Search,
		3,
		MUIM_Set, MUIA_Window_ActiveObject, BT_Search
		);

	DoMethod(cr->CY_Field(),
		MUIM_Notify, MUIA_Selected, FALSE,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_CREATE_QUERY_STRING
		);

	DoMethod(cr->STR_Value(),
		MUIM_Notify, MUIA_Selected, FALSE,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_CREATE_QUERY_STRING
		);

	DoMethod(cr->CY_Operator(),
		MUIM_Notify, MUIA_Selected, FALSE,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_CREATE_QUERY_STRING
		);

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

	DoMethod(BT_Search,
		MUIM_Notify, MUIA_Pressed, FALSE,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_EXECUTE_QUERY
		);

	DoMethod(BT_Add,
		MUIM_Notify, MUIA_Pressed, FALSE,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_ADD_CRITERIA
		);

	DoMethod(BT_Remove,
		MUIM_Notify, MUIA_Pressed, FALSE,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_REM_CRITERIA
		);

	// --- Setup cycle chain ---
	// Note: We have dynamic objects. 
	// s. Critera::Criteria() for more information

	set(BT_Add,MUIA_CycleChain,1);
	set(BT_Remove,MUIA_CycleChain,1);
	set(STR_Query,MUIA_CycleChain,1);
	set(BT_Search,MUIA_CycleChain,1);
	set(BT_Quit,MUIA_CycleChain,1);
	set(STR_DB_Server,MUIA_CycleChain,1);
	set(PO_DataBase,MUIA_CycleChain,1);
	set(PO_Table,MUIA_CycleChain,1);
	set(LV_Results,MUIA_CycleChain,1);

	// --- Attach Strings to popup lists

	set(STR_PO_DataBase,MUIA_String_AttachedList,LV_DataBase);
	set(STR_PO_Table,   MUIA_String_AttachedList,   LV_Table);
	set(BT_Search,   MUIA_Disabled, TRUE);
	set(BT_Remove,   MUIA_Disabled, TRUE);
	set(PO_DataBase, MUIA_Disabled, TRUE);
	set(PO_Table,    MUIA_Disabled, TRUE);

	// --- Fill.the DataBase List ---

   set(STR_DB_Server,MUIA_String_Contents,sg_Host);

	FillDataBaseList();
}


BOOL SearchGUI::Open()
{
	set(WI_Search, MUIA_Window_Open, TRUE );

	return TRUE;
}

void SearchGUI::Close()
{
	set(WI_Search, MUIA_Window_Open, FALSE );
}

BOOL SearchGUI::CreateQuery()
{
	char *field,*table,*line;

	// This must change into a loop!
	get(STR_PO_Table,MUIA_String_Contents,&table);

	char query[1024];
	sprintf(query," * FROM %s WHERE",table);

	int nc = AR_Criteria.GetSize() - 1;
	for (int i = nc; i >= 0; i--)
	{
		int n = 0;

		Criteria *cr = AR_Criteria[i];
		if (cr)
		{
			field = cr->FieldName();
			line = cr->FieldValue();

			if (field && line)
			{
				if ((strlen(query) + strlen(field) + strlen(line) + 20) > 1024) break;

				while (line && line[n] != '\0')
				{
					if (line[n] == '*') line[n] = '%';
					n++;
				}
				if (line)
					sprintf(query,"%s %s LIKE '%s'",query,field,line);
				if (i > 0)
					sprintf(query,"%s %s",query,cr->OperatorValue());
			}
		}			
	}

	set(STR_Query,MUIA_String_Contents,query);

	return TRUE;
}

BOOL SearchGUI::ExecuteQuery()
{
	try
	{
		char query[256];
		sprintf(query,"SELECT ");

		char *q;
		get(STR_Query,MUIA_String_Contents,&q);

		if (q)
		{
			char *server,*db_name;
			clock_t t1,t2;

			strncat(query,q,256);

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

			t1 = clock();
			set(STR_Status,MUIA_String_Contents,"Searching Database...Please Wait...");

	      get(STR_PO_DataBase,MUIA_String_Contents,&db_name);
    		get(STR_DB_Server,MUIA_String_Contents,&server);
			DoMethod(LV_Results,MUIM_List_Clear);

			DataBase db(&sql);

			db.Open(db_name,server);
			DataTable tbl = db.Query(query);

			int recount = tbl.GetRecordCount();
			char buffer[256];
			t2 = clock();
			double delta_t = difftime(t2,t1)/CLOCKS_PER_SEC;
			if (recount == 0)
			{
				sprintf(buffer,"No Record found!");
//				set(STR_Value, MUIA_String_Contents, "");
				set(WI_Search,MUIA_Window_ActiveObject, AR_Criteria[0]->STR_Value());
			}
			else if (recount == 1)
			{
				sprintf(buffer,"Found one Record. (%g secs)",recount,delta_t);
				set(WI_Search,MUIA_Window_ActiveObject, LV_Results);
			}
			else
			{
				sprintf(buffer,"Found %d Records. (%g secs)",recount,delta_t);
				set(WI_Search,MUIA_Window_ActiveObject, LV_Results);
			}
			set(STR_Status,MUIA_String_Contents,buffer);

			if (recount)
			{
				set(LV_Results,MUIA_NList_Quiet,TRUE);
				tbl.MoveFirst();
				int i = 0;
				do
				{
					DoMethod(LV_Results,MUIM_NList_InsertSingle,
								&tbl,MUIV_NList_Insert_Sorted);

				} while (tbl.MoveNext());

				set(LV_Results,MUIA_NList_Quiet,FALSE);
			}
// --------------

			return TRUE;
		}
	}
	catch(AdacException e)
	{
		set(STR_Status,MUIA_String_Contents,"failed !");

		e.Warn("Continue");
	}

	set(STR_Status,MUIA_String_Contents,"idle...");
	return FALSE;
}


void SearchGUI::FillFieldList()
{
	m_result *r = NULL;

	set(STR_Status,MUIA_String_Contents,"Fill fieldlist & columns...");

	try
	{

		if (cy_FieldNames)
		{
			set(STR_Status,MUIA_String_Contents,"Clear old fields...");

			int i = 0;
			while (cy_FieldNames[i])
			{
				delete cy_FieldNames[i++];
			}
			delete cy_FieldNames;
			cy_FieldNames = NULL;
		}
	
		char query[256];

		set(STR_Status,MUIA_String_Contents,"Query for field columns...");

		get(STR_PO_Table,MUIA_String_Contents,&sg_Table);
		sprintf(query,"SELECT * FROM %s WHERE _rowid = 0",sg_Table);
		sql.Query((char*)query);
		r = sql.StoreResult();

		long num_fields = sql.NumFields(r);

		cy_FieldNames = (char**)new char*[num_fields+1];
		cy_FieldNames[num_fields] = NULL;

		int n = 0;
		char column_format[1024];
		strcpy(column_format,"BAR");
		while (--num_fields >= 0)
		{
			m_field *mf = sql.FetchField(r);

			cy_FieldNames[n] = new char[strlen(mf->name)+1];
			strcpy(cy_FieldNames[n],mf->name);			
			strncat(column_format,",BAR",64);
			n++;
		}	

		sql.FreeResult(r);

		set(STR_Status,MUIA_String_Contents,"OK.");

		int nc = AR_Criteria.GetSize();
		for (int i = 0; i < nc; i++)
		{
			Criteria *cr = AR_Criteria[i];
			if (cr)
			{
				cr->FieldNames(cy_FieldNames);
			}
		}

		set(BT_Search, MUIA_Disabled, FALSE);
		set(LV_Results,MUIA_NList_Format, column_format);

	}
	catch(AdacException e)
	{
		set(STR_Status,MUIA_String_Contents,"failed !");

		int nc = AR_Criteria.GetSize();
		for (int i = 0; i < nc; i++)
		{
			Criteria *cr = AR_Criteria[i];
			if (cr)
			{
				set(cr->CY_Field, MUIA_Disabled, TRUE);
			}
		}
		set(BT_Search, MUIA_Disabled, TRUE);

		if (r) e.Warn("Continue");
	}

    set(STR_Status,MUIA_String_Contents,"idle...");
}

void SearchGUI::FillTableList()
{
	set(STR_Status,MUIA_String_Contents,"Fill table Popup...");

	try
	{
		m_result* mre;

	   set(STR_Status,MUIA_String_Contents,"Open Database...");

		get(STR_PO_DataBase,MUIA_String_Contents,&sg_Database);
		sql.SelectDB(sg_Database);
		mre = sql.ListTables();	
		int rows = sql.NumRows(mre);
		if (rows)
		{
			set(STR_Status,MUIA_String_Contents,"Insert tables...");

			DoMethod(LV_Table,MUIM_List_Clear);
			while (rows-- >= 0)
			{
				m_row mro = sql.FetchRow(mre);
				DoMethod(LV_Table,MUIM_List_InsertSingle,
					sql.GetField(mro, 0),
					MUIV_List_Insert_Sorted);
			}

			set(LV_Table, MUIA_List_Active, MUIV_List_Active_Top);
			DoMethod(LV_Table,
						MUIM_List_GetEntry,MUIV_List_GetEntry_Active,
						&sg_Table);

			set(STR_PO_Table,MUIA_String_Contents,sg_Table);
			set(PO_Table, MUIA_Disabled, FALSE);

			set(STR_Status,MUIA_String_Contents,"OK.");

			FillFieldList();
		}
		else
			set(PO_Table, MUIA_Disabled, TRUE);
	}
	catch(AdacException e)
	{
		set(STR_Status,MUIA_String_Contents,"failed !");

		set(PO_Table, MUIA_Disabled, TRUE);
		e.Warn("Continue");
	}

	set(STR_Status,MUIA_String_Contents,"idle...");
}

void SearchGUI::FillDataBaseList()
{
	set(STR_Status,MUIA_String_Contents,"Fill database Popup...");

	try
	{
		set(STR_Status,MUIA_String_Contents,"Connecting server...");

		get(STR_DB_Server,MUIA_String_Contents,&sg_Host);
		if (sg_Host && strlen(sg_Host))
		{
			sql.Connect(sg_Host);
		}
		else
		{
			sql.Connect();	
		}

//    set(STR_DB_Server,MUIA_String_Contents,server);

		set(STR_Status,MUIA_String_Contents,"finding available databases...");

		m_result* mre = sql.ListDBs();
		int rows = sql.NumRows(mre);

		DoMethod(LV_DataBase,MUIM_List_Clear);
		while (rows--)
		{
			m_row mro = sql.FetchRow(mre);
			DoMethod(LV_DataBase,MUIM_List_InsertSingle,
						sql.GetField(mro, 0),
						MUIV_List_Insert_Sorted);
		}

		set(STR_Status,MUIA_String_Contents,"OK.");

		set(LV_DataBase, MUIA_List_Active, MUIV_List_Active_Top);
		DoMethod(LV_DataBase,
					MUIM_List_GetEntry,MUIV_List_GetEntry_Active,
					&sg_Table);

		set(STR_PO_DataBase,MUIA_String_Contents,sg_Table);

		DoMethod(LV_Table,MUIM_List_Clear);
		set(STR_PO_Table,MUIA_String_Contents,"");
		set(PO_DataBase, MUIA_Disabled, FALSE);

		FillTableList();
	}
	catch(AdacException e)
	{
		set(STR_Status,MUIA_String_Contents,"failed!");

		set(PO_DataBase, MUIA_Disabled, TRUE);
		e.Warn("Continue");
	}

    set(STR_Status,MUIA_String_Contents,"idle...");
}

void SearchGUI::AddCriteria()
{
	// dynamiv objects only work on closed windows

	set(WI_Search,MUIA_Window_Open,FALSE);

	// Add a new Criteria-Group

	Criteria *cr = new Criteria(GR_Criteria);
	AR_Criteria.InsertAt(0,cr);

	set(BT_Remove, MUIA_Disabled, FALSE);
	cr->FieldNames(cy_FieldNames);

	DoMethod(cr->STR_Value(),
		MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_CREATE_QUERY_STRING
		);

	DoMethod(cr->STR_Value(),
		MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
		WI_Search,
		3,
		MUIM_Set, MUIA_Window_ActiveObject, BT_Search
		);

	DoMethod(cr->CY_Field(),
		MUIM_Notify, MUIA_Selected, FALSE,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_CREATE_QUERY_STRING
		);

	DoMethod(cr->STR_Value(),
		MUIM_Notify, MUIA_Selected, FALSE,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_CREATE_QUERY_STRING
		);

	// Modify previous Gadgets

	DoMethod(AR_Criteria[1]->STR_Value(),
		MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
		WI_Search,
		3,
		MUIM_Set, MUIA_Window_ActiveObject, cr->STR_Value()
		);

	set(AR_Criteria[1]->CY_Operator(),MUIA_Disabled,FALSE);

	DoMethod(AR_Criteria[1]->CY_Operator(),
		MUIM_Notify, MUIA_Selected, FALSE,
		APL_Search,
		2,
		MUIM_Application_ReturnID, ID_CREATE_QUERY_STRING
		);

	// reopen the window

	set(WI_Search,MUIA_Window_Open,TRUE);
}

void SearchGUI::RemCriteria()
{
	if (AR_Criteria.GetSize() > 1)
	{
		Criteria *cr = AR_Criteria[0];

		set(WI_Search,MUIA_Window_Open,FALSE);
		if (cr)
		{
			delete cr;
		}
		AR_Criteria.RemoveAt(0);
		set(AR_Criteria[0]->CY_Operator(),MUIA_Disabled,TRUE);
		set(WI_Search,MUIA_Window_Open,TRUE);
	}

	if (AR_Criteria.GetSize() <= 1)
		set(BT_Remove, MUIA_Disabled, TRUE);

	CreateQuery();
}

void SearchGUI::DoEventLoop()
{
	BOOL	running = TRUE;
	ULONG	signal;

	while (running)
	{
		switch (DoMethod(APL_Search,MUIM_Application_Input,&signal))
		{
			case MUIV_Application_ReturnID_Quit:
				running = FALSE;
				break;

			/* Insert your code between the "case" statement and comment "end of case ..." */

			case ID_FILL_DATABASE_LIST:
				FillDataBaseList();
				break;

			case ID_FILL_TABLE_LIST:
				FillTableList();
				break;

			case ID_POP_SELECT_DATABASE:
				DoMethod(LV_DataBase,
							MUIM_List_GetEntry,MUIV_List_GetEntry_Active,
							&sg_Database);

				set(STR_PO_DataBase,MUIA_String_Contents,sg_Database);
				FillTableList();
				break;

			case ID_POP_SELECT_TABLE:
				DoMethod(LV_Table,
							MUIM_List_GetEntry,MUIV_List_GetEntry_Active,
							&sg_Table);

				set(STR_PO_Table,MUIA_String_Contents,sg_Table);
				FillFieldList();
				break;

			case ID_CREATE_QUERY_STRING:
				CreateQuery();
				break;

			case ID_EXECUTE_QUERY:
				ExecuteQuery();
				break;

			case ID_ADD_CRITERIA:
				AddCriteria();
				break;

			case ID_REM_CRITERIA:
				RemCriteria();
				break;

			/* End computing of IDCMP */

			default:
				break;
		}
		if (running && signal) Wait(signal);
	}

}
