/*
   OpenTrace.c : Open trace dialog window.
   Copyright (C) 1999, 2000 Karim Yaghmour.
 
   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

   History : 
      JH.D., 07/08/1999, Made Dialog box unresizeable
      K.Y., 23/06/1999, Initial typing.
*/

#include "OpenTrace.h"

/**********************************************************************************/
/***************************** File browsing functions ****************************/
/**********************************************************************************/
/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void OTIProfFileSelectDestroy(GtkWidget* pmWidget, gpointer pmData)
{
  openTraceWindow*  pOTWin;  /* The window for whom this was called */

  /* Do we have anything meaningfull */
  if((pOTWin = (openTraceWindow*) pmData) == NULL)
    {
    g_print("Internal error: Destroy File Select without Open Trace Window \n");
    exit(1);
    }

  /* Delete the file selection  */
  pOTWin->ProfFileSelect = NULL;
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void OTIProfFileSelectOK(GtkWidget* pmWidget, gpointer pmData)
{
  openTraceWindow*  pOTWin;  /* The window for whom this was called */

  /* Do we have anything meaningfull */
  if((pOTWin = (openTraceWindow*) pmData) == NULL)
    {
    g_print("Internal error: OK File Select without Open Trace Window \n");
    exit(1);
    }

  /* Display the filename in the prof file text entry */
  gtk_entry_set_text(GTK_ENTRY(pOTWin->ProfFileTextEntry),
		     gtk_file_selection_get_filename(GTK_FILE_SELECTION(pOTWin->ProfFileSelect)));
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void OTIProcFileSelectDestroy(GtkWidget* pmWidget, gpointer pmData)
{
  openTraceWindow*  pOTWin;  /* The window for whom this was called */

  /* Do we have anything meaningfull */
  if((pOTWin = (openTraceWindow*) pmData) == NULL)
    {
    g_print("Internal error: Destroy File Select without Open Trace Window \n");
    exit(1);
    }

  /* Delete the file selection  */
  pOTWin->ProcFileSelect = NULL;
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void OTIProcFileSelectOK(GtkWidget* pmWidget, gpointer pmData)
{
  openTraceWindow*  pOTWin;  /* The window for whom this was called */

  /* Do we have anything meaningfull */
  if((pOTWin = (openTraceWindow*) pmData) == NULL)
    {
    g_print("Internal error: OK File Select without Open Trace Window \n");
    exit(1);
    }

  /* Display the filename in the prof file text entry */
  gtk_entry_set_text(GTK_ENTRY(pOTWin->ProcFileTextEntry),
		     gtk_file_selection_get_filename(GTK_FILE_SELECTION(pOTWin->ProcFileSelect)));
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void OTIFileBrowse(openTraceWindow* pmOTWin, gint pmFileType, char* pmTitle)
{
  GtkWidget*   pFileSelect;    /* The file select window */

  /* Depending on the file type to get */
  switch(pmFileType)
    {
    /* Prof file */
    case OT_PROF_FILE:
      /* Don't open more than one select window per file type */
      if(pmOTWin->ProfFileSelect != NULL)
	{
	gtk_widget_hide(pmOTWin->ProfFileSelect);
	gtk_widget_show(pmOTWin->ProfFileSelect);
	return;
	}

      /* Create a new file selection dialog */
      pFileSelect = pmOTWin->ProfFileSelect = gtk_file_selection_new(pmTitle);
      gtk_signal_connect(GTK_OBJECT(pFileSelect),
			 "destroy",
			 GTK_SIGNAL_FUNC(OTIProfFileSelectDestroy),
			 pmOTWin);
      gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(pFileSelect)->ok_button),
			 "clicked",
			 GTK_SIGNAL_FUNC(OTIProfFileSelectOK),
			 pmOTWin);
      break;

    /* Proc file */
    case OT_PROC_FILE:
      /* Don't open more than one select window per file type */
      if(pmOTWin->ProcFileSelect != NULL)
	{
	gtk_widget_hide(pmOTWin->ProcFileSelect);
	gtk_widget_show(pmOTWin->ProcFileSelect);
	return;
	}

      /* Create a new file selection dialog */
      pFileSelect = pmOTWin->ProcFileSelect = gtk_file_selection_new(pmTitle);
      gtk_signal_connect(GTK_OBJECT(pFileSelect),
			 "destroy",
			 GTK_SIGNAL_FUNC(OTIProcFileSelectDestroy),
			 pmOTWin);
      gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(pFileSelect)->ok_button),
			 "clicked",
			 GTK_SIGNAL_FUNC(OTIProcFileSelectOK),
			 pmOTWin);
      break;

    /* Error, Error, Error, Error .... */
    default:
      g_print("Internal error: Unknown file type \n");
      exit(1);
      break;
    }

  /* Connect the correct signals */
  gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(pFileSelect)->ok_button),
			    "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_destroy),
			    GTK_OBJECT(pFileSelect));
  gtk_signal_connect_object(GTK_OBJECT(GTK_FILE_SELECTION(pFileSelect)->cancel_button),
			    "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_destroy),
			    GTK_OBJECT(pFileSelect));

  /* Display file selection window in middle of screen */
  gtk_window_set_position(GTK_WINDOW(pFileSelect), GTK_WIN_POS_CENTER);

  /* Keep file selection on the foreground */
  gtk_window_set_transient_for(GTK_WINDOW(pFileSelect), 
			       GTK_WINDOW(pmOTWin->Window));

  /* Show the file selection window */
  gtk_widget_show(pFileSelect);
}

/**********************************************************************************/
/**************************** Signal handling functions ***************************/
/**********************************************************************************/
/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
gint OTSHDeleteEvent(GtkWidget* pmWidget, GdkEvent* pmEvent, gpointer pmData)
{
  /* Close it */
  return(FALSE);
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void OTSHDestroy(GtkWidget* pmWidget, gpointer pmData)
{
  openTraceWindow*  pOTWin;  /* The window for whom this was called */

  /* Do we have anything meaningfull */
  if((pOTWin = (openTraceWindow*) pmData) == NULL)
    {
    g_print("Internal error: Callback without Open Trace Window \n");
    exit(1);
    }

  /* Call on the cancel callback */
  pOTWin->CBCancel(pOTWin->SysView);
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void OTSHProfFileBrowse(GtkWidget* pmWidget, gpointer pmData)
{
  OTIFileBrowse((openTraceWindow*) pmData, OT_PROF_FILE, "Select Trace File");
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void OTSHProcFileBrowse(GtkWidget* pmWidget, gpointer pmData)
{
  OTIFileBrowse(((openTraceWindow*) pmData), OT_PROC_FILE, "Select Proc File");
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void OTSHInternalOK(GtkWidget* pmWidget, gpointer pmData)
{
  openTraceWindow*  pOTWin;  /* The window for whom this was called */

  /* Do we have anything meaningfull */
  if((pOTWin = (openTraceWindow*) pmData) == NULL)
    {
    g_print("Internal error: Callback without Open Trace Window \n");
    exit(1);
    }

  /* Call the OK Callback */
  pOTWin->CBOK(pOTWin->SysView,
	       gtk_entry_get_text(GTK_ENTRY(pOTWin->ProfFileTextEntry)),
	       gtk_entry_get_text(GTK_ENTRY(pOTWin->ProcFileTextEntry)));
}

/**********************************************************************************/
/******************************* Windowing functions ******************************/
/**********************************************************************************/
/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void OTSetFocus(openTraceWindow* pmOTWin)
{
  /* This is the stupid way of doing things ... */
  gtk_widget_hide(pmOTWin->Window);
  gtk_widget_show(pmOTWin->Window);
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void OTConnectSignals(openTraceWindow* pmOTWin)
{
  /* Connect the generic signals */
  gtk_signal_connect(GTK_OBJECT(pmOTWin->Window),
		     "delete_event",
		     GTK_SIGNAL_FUNC(OTSHDeleteEvent),
		     pmOTWin);
  gtk_signal_connect(GTK_OBJECT(pmOTWin->Window),
		     "destroy",
		     GTK_SIGNAL_FUNC(OTSHDestroy),
		     pmOTWin);

  /* Connect the Browse buttons */
  gtk_signal_connect(GTK_OBJECT(pmOTWin->ProfFileBrowse),
		     "clicked",
		     GTK_SIGNAL_FUNC(OTSHProfFileBrowse),
		     pmOTWin);
  gtk_signal_connect(GTK_OBJECT(pmOTWin->ProcFileBrowse),
		     "clicked",
		     GTK_SIGNAL_FUNC(OTSHProcFileBrowse),
		     pmOTWin);

  /* Connect the Ok and Cancel buttons */
  gtk_signal_connect(GTK_OBJECT(pmOTWin->OKButton),
		     "clicked",
		     GTK_SIGNAL_FUNC(OTSHInternalOK),
		     pmOTWin);
  gtk_signal_connect_object(GTK_OBJECT(pmOTWin->OKButton),
			    "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_destroy),
			    GTK_OBJECT(pmOTWin->Window));
  gtk_signal_connect_object(GTK_OBJECT(pmOTWin->CancelButton),
			    "clicked",
			    GTK_SIGNAL_FUNC(gtk_widget_destroy),
			    GTK_OBJECT(pmOTWin->Window));
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void OTShowOpenTraceWindow(openTraceWindow* pmOTWin)
{

  /* Make OK button default choice */
  gtk_widget_grab_default(pmOTWin->OKButton);

  /* Show it all to the world */
  gtk_widget_show(pmOTWin->VBox);
  gtk_widget_show(pmOTWin->ProfHBox);
  gtk_widget_show(pmOTWin->ProcHBox);
  gtk_widget_show(pmOTWin->ButtonHBox);
  gtk_widget_show(pmOTWin->ProfLabel);
  gtk_widget_show(pmOTWin->ProcLabel);
  gtk_widget_show(pmOTWin->ProfFileTextEntry);
  gtk_widget_show(pmOTWin->ProcFileTextEntry);
  gtk_widget_show(pmOTWin->ProfFileBrowse);
  gtk_widget_show(pmOTWin->ProcFileBrowse);
  gtk_widget_show(pmOTWin->OKButton);
  gtk_widget_show(pmOTWin->CancelButton);

  /* Set title */
  gtk_window_set_title(GTK_WINDOW(pmOTWin->Window), "Open Trace");

  /* Display in the center of screen */
  gtk_window_set_position(GTK_WINDOW(pmOTWin->Window), GTK_WIN_POS_CENTER);

  /* Set the dialog window size */
  gtk_widget_set_usize(pmOTWin->Window, 350, 70);

  /* Make OpenTrace window unresizeable and always visible */
  gtk_window_set_policy(GTK_WINDOW(pmOTWin->Window),FALSE, FALSE, FALSE);
  gtk_window_set_transient_for(GTK_WINDOW(pmOTWin->Window), 
			       GTK_WINDOW(pmOTWin->ParentWin));

  /* Display it */
  gtk_widget_show(pmOTWin->Window);

}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
openTraceWindow* OTCreateOpenTraceWindow(gpointer     pmSysView,
					 GtkWidget*   pmParentWin,
			  		 _OTCBOK*     pmCBOK,
					 _OTCBCancel* pmCBCancel)
{
  openTraceWindow* pOTWin;          /* Open trace window */

  /* Create a new trace file selection window */
  pOTWin = (openTraceWindow*) g_malloc(sizeof(openTraceWindow));

  /* Initialize basic variables */
  pOTWin->ProfFileSelect = NULL;
  pOTWin->ProcFileSelect = NULL;

  /* Put the given data in the right place */
  pOTWin->SysView  = pmSysView;
  pOTWin->ParentWin= pmParentWin;
  pOTWin->CBOK     = pmCBOK;
  pOTWin->CBCancel = pmCBCancel;

  /* Build the window */
  pOTWin->Window = gtk_window_new(GTK_WINDOW_DIALOG);
  pOTWin->VBox   = gtk_vbox_new(FALSE, TRUE);
  gtk_container_add(GTK_CONTAINER(pOTWin->Window), pOTWin->VBox);

  /* Allocate HBoxes to put the rest of the widgets and pack them */
  pOTWin->ProfHBox   = gtk_hbox_new(FALSE, 0);
  pOTWin->ProcHBox   = gtk_hbox_new(FALSE, 0);
  pOTWin->ButtonHBox = gtk_hbox_new(FALSE, 0);
  gtk_box_pack_start(GTK_BOX(pOTWin->VBox), pOTWin->ProfHBox, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(pOTWin->VBox), pOTWin->ProcHBox, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(pOTWin->VBox), pOTWin->ButtonHBox, FALSE, TRUE, 0);

  /* Create the labels and pack them */
  pOTWin->ProfLabel = gtk_label_new("Trace file: ");
  pOTWin->ProcLabel = gtk_label_new("Proc file: ");
  gtk_widget_set_usize(pOTWin->ProfLabel, 80, 20);
  gtk_widget_set_usize(pOTWin->ProcLabel, 80, 20);
  gtk_box_pack_start(GTK_BOX(pOTWin->ProfHBox), pOTWin->ProfLabel, FALSE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(pOTWin->ProcHBox), pOTWin->ProcLabel, FALSE, TRUE, 0);

  /* Create text entries and pack them */
  pOTWin->ProfFileTextEntry = gtk_entry_new();
  pOTWin->ProcFileTextEntry = gtk_entry_new();
  gtk_box_pack_start(GTK_BOX(pOTWin->ProfHBox), pOTWin->ProfFileTextEntry, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(pOTWin->ProcHBox), pOTWin->ProcFileTextEntry, TRUE, TRUE, 0);

  /* Create browse buttons and pack them */
  pOTWin->ProfFileBrowse = gtk_button_new_with_label("Browse");
  pOTWin->ProcFileBrowse = gtk_button_new_with_label("Browse");
  gtk_box_pack_start(GTK_BOX(pOTWin->ProfHBox), pOTWin->ProfFileBrowse, FALSE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(pOTWin->ProcHBox), pOTWin->ProcFileBrowse, FALSE, TRUE, 0);

  /* Create OK and cancel buttons and pack them */
  pOTWin->OKButton     = gtk_button_new_with_label("OK");
  pOTWin->CancelButton = gtk_button_new_with_label("Cancel");
  GTK_WIDGET_SET_FLAGS(pOTWin->OKButton, GTK_CAN_DEFAULT);  /* Allow OK button to be default */
  gtk_box_pack_start(GTK_BOX(pOTWin->ButtonHBox), pOTWin->OKButton, TRUE, TRUE, 0);
  gtk_box_pack_start(GTK_BOX(pOTWin->ButtonHBox), pOTWin->CancelButton, TRUE, TRUE, 0);

  /* Give it to the caller */
  return pOTWin;
}

/******************************************************************
 * Function :
 * Description :
 * Parameters :
 * Return values :
 * History :
 * Note :
 ******************************************************************/
void OTDestroyOpenTraceWindow(openTraceWindow* pmOTWin)
{
  /* Were there any select window open */
  if(pmOTWin->ProfFileSelect != NULL)
    gtk_widget_destroy(pmOTWin->ProfFileSelect);
  if(pmOTWin->ProcFileSelect != NULL)
    gtk_widget_destroy(pmOTWin->ProcFileSelect);

  /* Destroy the window */
  gtk_widget_destroy(pmOTWin->Window);

  /* Free space used by structure */
  g_free(pmOTWin);
}
