/*
testvdk Application
Main unit implementation file:testvdk.cc
*/ 
#include <testvdk.h>
#include "vdksignal.h"
#include "canvas.h"
#include "customtree.h"
#include "databox.h"
#include "combo.h"
#include "grid.h"
#include "notebook.h"
#include <vdk/FileDialog.h>
#include <vdk/FileTreeDialog.h>
#include <gdk/gdkkeysyms.h>
#include <vdk/vdkcolorbrowser.h>
#include "entries.h"
#include "paned.h"
#include "progress.h"
#include "radiobutton.h"
#include "scrolled.h"
TestvdkApp* TheApplication;
static char buff[256];

/*
main program 
*/
int main (int argc, char *argv[])
{
        TestvdkApp app(&argc, argv);
    	TheApplication = &app;
    	app.SetGarbageCollection(2000);
    	app.Run();
    	return 0;
}

// Testvdk MAIN FORM  CLASS


void  MakeFileBrowser(int ndx);
void  MakeFileTreeBrowser(int ndx);
void  MakeGtkFileSel(int ndx);
void  MakeColorBrowser(int ndx);
void  MakeMessageBox(int ndx);

struct
{ 
  char *name;
  void (*foo)(int);  
  VDKForm* form;   
} dialogs[MAXDIALOG] =  
{    
/*
  dialog name           foo() function   form 
*/
  {"File dialog" ,      MakeFileBrowser, NULL},
  {"File tree dialog" , MakeFileTreeBrowser, NULL},
  {"File sel ala gtk+", MakeGtkFileSel,  NULL},
  {"Color browser" ,    MakeColorBrowser,NULL},
  {"MessageBox" ,       MakeMessageBox,  NULL}
};

/*
this struct array contains
mapping instruction to:
- load test list with <test name> and availability
- form static constructor to invoke for each test
- source file name to be displayed
- a <form> address to raise form if alredy constructed
(if NULL form isn't yet constructed or destroyed)
*/
struct
{ 
  char *items[LISTCOL];
  VDKForm* (*Create)(VDKForm*);
  char* source; 
  VDKForm* form;   
} test[MAXTEST] =  
{    
/*
  test name               avail    function               source          form 
*/
  {{"About sigs & evs" ,  "yes" }, VdksignalForm::Create,    "signal",       NULL},
  {{"Canvas",             "yes" }, CanvasForm::Create,    "canvas",       NULL},
  {{"Combo box",          "yes" }, ComboForm::Create,     "combo",        NULL},
  {{"Custom tree",        "yes" }, CustomtreeForm::Create,"customtree",   NULL},
  {{"Databox",            "yes" }, DataboxForm::Create,   "databox",      NULL},
  {{"Entries",            "yes" }, EntriesForm::Create,   "entries",      NULL},
  {{"Grid",               "yes" }, GridForm::Create,      "grid",         NULL},
  {{"Note book",          "yes" }, NotebookForm::Create,  "notebook",     NULL},
  {{"Packer",             "no"  }, NULL,NULL,NULL},
  {{"Paned widget",       "yes" }, PanedForm::Create,      "paned",       NULL},
  {{"Progress bar",       "yes" }, ProgressForm::Create,   "progress",    NULL},
  {{"Radio buttons" ,     "no"  }, RadiobuttonForm::Create,"radiobutton", NULL},
  {{"Range and spins",    "no"  }, NULL,NULL,NULL},
  {{"Scrolled ",          "yes" }, ScrolledForm::Create,   "scrolled",    NULL}, 
  {{"Signal benchmark" ,  "no"  }, NULL,NULL,NULL},
  {{"Sorted list",        "no"  }, NULL,NULL,NULL},
  {{"Text",               "no"  }, NULL,NULL,NULL},
  {{"Toolbar",            "no"  }, NULL,NULL,NULL},
  {{"VDK chart",          "no"  }, NULL,NULL,NULL},
};


void MakeFileBrowser(int ndx)
{
  FileStringArray selections;
  VDKFileDialog  *child = new VDKFileDialog(
  				TheApplication->MainForm,
  	               &selections,
                      "File Open dialog");
  test[ndx].form = child;   
  child->ShowModal();
  for( int t = 0; t < selections.size(); t++)
    {
      printf("\nselection:%s",(char*) selections[t]);
      fflush(stdout);
    } 
}

void MakeFileTreeBrowser(int ndx)
{
  FileStringArray selections;
  VDKFileTreeDialog  *child = new VDKFileTreeDialog(
  					  TheApplication->MainForm,
  					  &selections,
  					  "File Open dialog");
  test[ndx].form = child;   
  child->ShowModal();
  for( int t = 0; t < selections.size(); t++)
    {
      printf("\nselection:%s",(char*) selections[t]);
      fflush(stdout);
    } 
}

/*
*/
void  MakeNotebookForm(int ndx)
{
  NotebookForm* child = 
  	new NotebookForm(TheApplication->MainForm, NULL);
  test[ndx].form = child; 
  child->Setup();
  child->Show();
}

/*
*/
void MakeColorBrowser(int ndx)
{
  VDKColorBrowserParms parms;
  VDKColorBrowser* child = new VDKColorBrowser(TheApplication->MainForm,
  				                          &parms);
  test[ndx].form = child; 
  child->Setup();
  child->ShowModal();
  if(parms.rgb.red >= 0)
    {
      printf("\nselected color: VDKRgb(%d,%d,%d), name:%s",
      	   parms.rgb.red,parms.rgb.green,parms.rgb.blue,parms.colorname);
      fflush(stdout);
    }
} 
/*
*/
void MakeGtkFileSel(int ndx)
{
  char selection[512];
  strcpy(selection,"*.h");
  VDKFileSel* child = new VDKFileSel(TheApplication->MainForm,
    				   selection,
    				   "File selection (ala Gtk+)");
  test[ndx].form = child; 
  child->Setup();
  child->Show(); 
  if(*selection) 
    {
      printf("\nselection:%s",selection);
      fflush(stdout);
    }
}
/*
*/
void MakeMessageBox(int )
{
  TheApplication->MessageBox("VDK MessageBox",
  	"This is a modal message box\n\
      (will disappear in 5 seconds)",
  	MB_ICONINFORMATION|MB_OK, 
  	NULL,
  	NULL,
  	5000);
}

/*
main form constructor
*/
TestvdkForm::TestvdkForm(VDKApplication* app, char* title):
	VDKForm(app,title)
{
}

/*
main form destructor
*/
TestvdkForm::~TestvdkForm()
{
}

/*
main form setup
*/
void
TestvdkForm::Setup(void) 
{

  GUISetup(); // vdkb gui setup
  // set form size as background pixmap
  //VDKRawPixmap *bgpix = BackgroundPixmap;
  //if(bgpix)
    // 	SetSize(bgpix->Width(),bgpix->Height());
  // sets vdk version on status bar
  sprintf(buff,"VDK %d.%d.%d",VDK_VERSION_MAJOR,
		VDK_VERSION_MINOR,
		VDK_REVISION);
  main_status_bar->Push(buff);
  // hides main notebook
  main_notebook->Visible = false;
  // sets list colors 
  if(VDKRgb("cornsilk").IsValid())
    list->NormalBackground = VDKRgb("cornsilk");
  if(VDKRgb("red3").IsValid())
    list->SelectedBackground = new VDKColor(this,VDKRgb("red3"));
  list->SelectedForeground = new VDKColor(this,clWhite);  
  // load tests list
  LoadTestList();
  // fills combo menu with items
  combomenu = new VDKMenu(this);
  for (int z = 0;  z < MAXTEST; z++)
  {
    menuitems[z] = new VDKMenuItem(combomenu,test[z].items[0]);
    menuitems[z]->Enabled = test[z].Create != NULL;
    SignalConnect(menuitems[z],"activate",&TestvdkForm::OnActivateComboMenu);
  }
  combobutton->SetComboMenu(combomenu);
  // fills dialog combo menu with items
  dialogcombomenu = new VDKMenu(this);
  for (int z = 0;  z < MAXDIALOG; z++)
    {
      dialogmenuitems[z] = new VDKMenuItem(dialogcombomenu,dialogs[z].name);
      dialogmenuitems[z]->Enabled = dialogs[z].foo != NULL;
      SignalConnect(dialogmenuitems[z],
      		"activate",
      		&TestvdkForm::OnActivateDialogComboMenu);
    }
  dialogcombobutton->SetComboMenu(dialogcombomenu);
}

/*
*/
void
TestvdkForm::LoadTestList(void)
{
// add list rows
for (int i = 0; i < MAXTEST; i++) 
       list->AddRow(test[i].items, NULL,1);  
}

/*  
can close query   
*/
bool 
TestvdkForm::CanClose() 
{
  sprintf(buff,"VDK %d.%d.%d",VDK_VERSION_MAJOR,
		VDK_VERSION_MINOR,
		VDK_REVISION);
  if(Application()->MessageBox(buff,
			       "Sure to quit ?",
			       MB_ICONQUESTION|MB_YESNO,
			       "Leave test application",
			       "Cancel",5000) == IDYES)
    return true;
  else   
    return false;  
}    

// Testvdk APPLICATION  CLASS
/*
application constructor
*/
TestvdkApp::TestvdkApp(int* argc, char** argv):
	VDKApplication(argc,argv)
{
}

/*
application destructor
*/
TestvdkApp::~TestvdkApp()
{
}

/*
application setup
*/

void
TestvdkApp::Setup(void)
{
	MainForm = new TestvdkForm(this,NULL);
	MainForm->Setup();
	MainForm->Visible = true;
}

// signal response method 
bool
TestvdkForm::OnshowNoteBookButtonClick(VDKObject* sender)
{
bool visible = main_notebook->Visible;
VDKLabel* label = showNoteBookButton->Label;
main_notebook->Visible = visible ? false : true;
label->Caption =  ! visible ? (char*) "Hide tests" : 
	(char*) "Show tests";
return true;
}

// signal response method 
bool
TestvdkForm::OnquitButtonClick(VDKObject* sender)
{
Close();
return true;
}

// signal response method 
bool
TestvdkForm::OnsourceTextRealize(VDKObject* sender)
{
int ndx = list->Selected.Row();
if(ndx < 0)
	return true;
// load source and header
if(test[ndx].source)
	{
	sprintf(buff,"%s.cc",test[ndx].source);
	sourceText->LoadFromFile(buff);
	}
else
	sourceText->Clear();
return true;
}

// signal response method 
bool
TestvdkForm::OnheaderTextRealize(VDKObject* sender)
{
int ndx = list->Selected.Row();
if(ndx < 0)
	return true;
// load source and header
if(test[ndx].source)
	{
	sprintf(buff,"%s.h",test[ndx].source);
	headerText->LoadFromFile(buff);
	}
else
	headerText->Clear();

return true;
}

// signal response method 
bool
TestvdkForm::OnlistSelectRow(VDKObject* sender)
{
int ndx = list->Selected.Row();
if(ndx < 0)
	return true;
testButton->Enabled = test[ndx].Create != NULL;
// load source and header
if(test[ndx].source)
	{
	sprintf(buff,"%s.cc",test[ndx].source);
	sourceText->LoadFromFile(buff);
	sprintf(buff,"%s.h",test[ndx].source);
	headerText->LoadFromFile(buff);
	}
else
	{
	sourceText->Clear();
	headerText->Clear();
	}
return true;
}

// signal response method 
bool
TestvdkForm::OntestButtonClick(VDKObject* sender)
{
int ndx = list->Selected.Row();
if(ndx < 0) 
  return true;
// exec or raises an already mapped child
if(test[ndx].form)
	test[ndx].form->Raise();
else
	{
	VDKForm* child =  test[ndx].Create(this);
	test[ndx].form = child; 
	child->Setup();
	child->Show();
	}
return true;
}

// form event response method 
void
TestvdkForm::OnChildClosing(VDKForm* child)
{
int t;
for(t=0; t < MAXTEST;t++)
    if(test[t].form == child)
	test[t].form = NULL;
return ;
}

// signal response method 
bool
TestvdkForm::Onmain_notebookSwitchPage(VDKObject* sender)
{
int ndx;
if(main_notebook->ActivePage <= 0)
	return true;
else if ((ndx = list->Selected.Row()) < 0)
	return true;
sourceText->Clear();
headerText->Clear();
gui_sourceText->Clear();
gui_headerText->Clear();
// load source and header
if(test[ndx].source)
	{
	sprintf(buff,"%s.cc",test[ndx].source);
	sourceText->LoadFromFile(buff);
	sprintf(buff,"%s.h",test[ndx].source);
	headerText->LoadFromFile(buff);
	sprintf(buff,"%s_gui.cc",test[ndx].source);
	gui_sourceText->LoadFromFile(buff);
	sprintf(buff,"%s_gui.h",test[ndx].source);
	gui_headerText->LoadFromFile(buff);
	}
return true; 
}

// signal response method 
bool
TestvdkForm::Ongui_HeaderTextRealize(VDKObject* sender)
{
int ndx = list->Selected.Row();
if(ndx < 0)
	return true;
// load source and header
if(test[ndx].source)
	{
	sprintf(buff,"%s_gui.h",test[ndx].source);
	gui_headerText->LoadFromFile(buff);
	}
else
	gui_headerText->Clear();

return true;
}

// signal response method 
bool
TestvdkForm::Ongui_sourceTextRealize(VDKObject* sender)
{
int ndx = list->Selected.Row();
if(ndx < 0)
	return true;
// load source and header
if(test[ndx].source)
	{
	sprintf(buff,"%s_gui.cc",test[ndx].source);
	gui_sourceText->LoadFromFile(buff);
	}
else
	gui_sourceText->Clear();

return true;
}
/*
 */
bool 
TestvdkForm::OnActivateComboMenu(VDKObject* item) 
{
  // look up on menuitems array to match the right index
  int ndx = -1;
  for(int t = 0; t < MAXTEST; t++)
    if(menuitems[t] == item)
      {
       ndx = t;
       break;
      }
  // match found
  // raises or launch test window
  if(ndx >= 0)
    {
      if(test[ndx].form)
	test[ndx].form->Raise();
      else
	{
	VDKForm* child =  test[ndx].Create(this);
	test[ndx].form = child; 
	child->Setup();
	child->Show();
	}
    }
  return true;
}

/*
 */
bool 
TestvdkForm::OnActivateDialogComboMenu(VDKObject* item) 
{
  // look up on menuitems array to match the right index
  int ndx = -1;
  for(int t = 0; t < MAXDIALOG; t++)
    if(dialogmenuitems[t] == item)
      {
       ndx = t;
       break;
      }
  // match found
  // raises or launch test window
  if(ndx >= 0)
    {
      if(dialogs[ndx].form)
	dialogs[ndx].form->Raise();
      else
	dialogs[ndx].foo(ndx);
    }
  return true;
}