/**************************************************************
 * Structured Markov Chains Solver       [  SMCSolver  ]      *
 * Dario Bini, Beatrice Meini, Sergio Steffe'                 *
 * bini@dm.unipi.it, meini@dm.unipi.it, steffe@dm.unipi.it    *
 * Dipartimento di Matematica "Leonida Tonelli"               *
 * Largo Pontecorvo 5                                         *
 * 56127 Pisa                                                 *
 * Italy                                                      *
 * Version 1.1 - Oct 2006                                     *
 **************************************************************
 *
 *  callbacks.c - mostly callback routines
 *
 */

#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h> /* atoi */
#include <ctype.h>  /* isdigit */
#include <pthread.h>
#include <libgen.h>
#include <gtk/gtk.h>
#include <math.h>
#include <time.h>

#include "structures.h"
#include "callbacks.h"

/* Main Menu: Read A */
void 
on_main_menu_reada_activate (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *reada_fs; global  */
/* int is_runnig; global        */
/* int reada_open; global       */
/* GtkWidget statusb; global    */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Wait till the end of computation, please !");
    return;
    }
if(is_savea_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Read and Write A at the same time  !");
    return;
    }

if(is_saveb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Read A and Write B at the same time  !");
    return;
    }

if (is_examples_open==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A matrices form File or from Examples !");
 return;
 }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Read A from File while editing A");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Read A from File while editing B");
    return;
    }

/* not running, not writing A, not loading examples, we can read A for the problem */
clean_statusb();
 if(is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You where just reading A ...");
    }
    else
    {
    is_reada_open=1;
    reada_fs = create_fileselection_reada ();
    gtk_widget_show (reada_fs);
    }
}
/*********************************/

/* Main Menu: Read B */
void 
on_main_menu_readb_activate (GtkMenuItem *menuitem, gpointer user_data)
{   
/* GtkWidget *readb_fs; global  */
/* int is_runnig; global        */
/* int readb_open; global       */
/* GtkWidget statusb; global    */
if(is_debug==1) printf("is_running=%d is_saveb_open=%d, committed.allocated=%d, committed.example=%d committed.type=%d\n",is_running,is_saveb_open,committed.allocated,committed.example,committed.type);
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Wait till the end of computation, please !");
    return;
    }
if(is_saveb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Read and Write B at the same time  !");
    return;
    }
if(is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Read B and  A at the same time  !");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Read B from File while editing B");
    return;
    }

if(committed.allocated==0){
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," First Read A please !");
    return;
    }
if (is_examples_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A and B matrices form File or from Examples !");
    return;
    }
if(committed.example!=0){    
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Read B from File for an Example Problem. ");
    return;
    }
/* not running, not writing B, not loading examples, not an example, we can read B for the problem */
clean_statusb();
 if(is_readb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You where just reading B ...");
    }
    else
    {
    is_readb_open=1;
    readb_fs = create_fileselection_readb ();
    gtk_widget_show (readb_fs);
    }

}
/*********************************/

/* Main Menu: Save A */
void 
on_main_menu_savea_activate (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *savea_fs; global  */
/* int is_runnig; global        */
/* int savea_open; global       */
/* GtkWidget statusb; global    */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Wait till the end of computation, please !");
    return;
    }
if (committed.allocated == 0) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No A Matrix Available to Save on File");
    return;
    }
clean_statusb();
 if(is_savea_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You where just saving A ...");
    }
    else
    {
    is_savea_open=1;
    savea_fs = create_fileselection_savea ();
    gtk_widget_show (savea_fs);
    }
}
/*********************************/

/* Main Menu: Save B */
void
on_main_menu_saveb_activate (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *saveb_fs; global  */
/* int is_runnig; global        */
/* int saveb_open; global       */
/* GtkWidget statusb; global    */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Wait till the end of computation, please !");
    return;
    }
if (committed.allocated == 0) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No B Matrix Available to Save on File");
    return;
    }
if ((committed.is_b == 0)&&(committed.is_b0==0)) { 
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No B Matrix Available to Save on File");
    return;
    }

clean_statusb();
 if(is_saveb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You where just saving B ...");
    }
    else
    {
    is_saveb_open=1;
    saveb_fs = create_fileselection_saveb ();
    if (saveb_fs != NULL) {gtk_widget_show (saveb_fs);is_saveb_open=1;} else gtk_statusbar_push(GTK_STATUSBAR(statusb),0," *** Some Error Opening the Window");
    }
}
/*********************************/

/* Main Menu: Save G */
void 
on_main_menu_saveg_activate (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *saveg_fs; global  */
/* int is_runnig; global        */
/* int saveg_open; global       */
/* GtkWidget statusb; global    */
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Wait till the end of computation, please !");
 return; 
 } 
if (completed.g == 0) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No G Matrix Available to Save on File");
 return;
 }
 clean_statusb();
 if(is_saveg_open==1) { 
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You where just saving G ...");
    }
    else
    {
    is_saveg_open=1;
    saveg_fs = create_fileselection_g ();
    gtk_widget_show (saveg_fs);
    }
}
/*********************************/

/* Main Menu: Save R */
void
on_main_menu_saver_activate (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *saver_fs; global  */
/* int is_runnig; global        */
/* int saver_open; global       */
/* GtkWidget statusb; global    */
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Wait till the end of computation, please !");
 return;
 }
if (completed.r == 0) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No R Matrix Available to Save on File");
 return;
 }
 clean_statusb();
 if(is_saver_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You where just saving R ...");
    }
    else
    {
    is_saver_open=1;
    saver_fs = create_fileselection_r ();
    gtk_widget_show (saver_fs);
    }
}
/*********************************/

/* Main Menu: Save U */
void
on_main_menu_saveu_activate (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *saveu_fs; global  */
/* int is_runnig; global        */
/* int saveu_open; global       */
/* GtkWidget statusb; global    */
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Wait till the end of computation, please !");
 return;
 }
if (completed.u == 0) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No U Matrix Available to Save on File");
 return;
 }
 clean_statusb();
 if(is_saveu_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You where just saving U ...");
    }
    else
    {
    is_saveu_open=1;
    saveu_fs = create_fileselection_u ();
    gtk_widget_show (saveu_fs);
    }
}
/*********************************/

/* Main Menu: Save G+R+U */
void 
on_main_menu_savegru_activate (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *savegru_fs; global */
/* int is_runnig; global         */
/* int savegru_open; global        */
/* GtkWidget statusb; global     */
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Wait till the end of computation, please !");
 return;
 }
if (completed.g == 0) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No G Matrix Available to Save on File");
 return;
 }

if (completed.r == 0) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No R Matrix Available to Save on File");
 return;
 }
if (completed.u == 0) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No U Matrix Available to Save on File");
 return;
 }

 clean_statusb();
 if(is_savegru_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You where just saving G+R+U ...");
    }
    else
    {
    is_savegru_open=1;
    savegru_fs = create_fileselection_gru ();
    gtk_widget_show (savegru_fs);
    }

}
/*********************************/

/* Main Menu: Save Pi */
void
on_main_menu_savepi_activate (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *savepi_fs; global */
/* int is_runnig; global         */
/* int savepi_open; global        */
/* GtkWidget statusb; global     */
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Wait till the end of computation, please !");
 return;
 }
if (completed.pi == 0) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No Pi Vectors Available to Save on File");
 return;
 }
 clean_statusb();
 if(is_savepi_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You where just saving Pi ...");
    }
    else
    {
    is_savepi_open=1;
    savepi_fs = create_fileselection_pi ();
    gtk_widget_show (savepi_fs);
    }

}
/*********************************/

/* Main Menu: Import Telpack */
void 
on_main_menu_imptel_activate (GtkMenuItem *menuitem, gpointer user_data )
{
gtk_statusbar_push(GTK_STATUSBAR(statusb),0," ****  STILL TO IMPLEMENT ***  !");
}
/*********************************/

/* Main Menu: Export Telpack */
void 
on_main_menu_exptel_activate (GtkMenuItem *menuitem, gpointer user_data )
{
gtk_statusbar_push(GTK_STATUSBAR(statusb),0," ****  STILL TO IMPLEMENT ***  !");
}
/*********************************/

/* Main Menu: SaveNotePad */
void
on_main_menu_savepad_activate (GtkMenuItem  *menuitem, gpointer  user_data)
{
/* GtkWidget *appensave; global */
/* int is_runnig; global        */
/* GtkWidget statusb; global    */
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
 }
 else
 {
 clean_statusb();
 if(is_savepad_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"You where just saving the NotePad ...");
    }
    else
    {
    is_savepad_open=1;
    appendsave = create_fileselection1 ();
    gtk_widget_show (appendsave);
    }
 }
}
/*********************************/

/* Main Menu: ClearNotePad */
void 
on_main_menu_clearpad_activate(GtkMenuItem     *menuitem, gpointer       user_data)
{
/* int is_runnig; global        */
/* GtkWidget *statusb; global    */
/* GtkWidget *textview; global   */
GtkTextBuffer *buffer;
char vuoto[80];

if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
 }
 else
 {
 clean_statusb();
 buffer = (GtkTextBuffer *) gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
 sprintf(vuoto," \n");
 gtk_text_buffer_set_text (buffer, vuoto, -1);
 }
}
/*********************************/

/* Main Menu: Quit       */
void
on_main_menu_quit_activate   (GtkMenuItem  *menuitem, gpointer  user_data)
{
if(is_debug==1) printf("%s on %s: bye\n\n",my_prog_name,my_host_name);
gtk_main_quit();
}
/*********************************/

/* Main Menu: Quit       */
void
on_main_menu_destroy_activate   (GtkWidget  *  ww, gpointer  user_data)
{
if(is_debug==1) printf("%s on %s: bye\n\n",my_prog_name,my_host_name);
gtk_main_quit();
}
/*********************************/


/* Main Menu: About Open */
void
on_main_menu_about_activate  (GtkMenuItem  *menuitem, gpointer  user_data)
{
clean_statusb();
if (is_about_open==0) {   /* do not open more than one about window */
   is_about_open = 1;
   create_window_about();
   }
}
/*********************************/

/* Main Menu: Run        */
void
on_main_menu_run_activate     (GtkMenuItem *menuitem, gpointer  user_data)
{
/* struct algorithms_str algorithms_choice,algorithms_committed;  */
/* struct goals_str goals_choice,goals_committed; */
/* struct running_problem_str committed; global  */
/* GtkWidget statusb; global    */
/*int is_edit_a_open;   0=not open  1=open global */
/* testing threads signals ... booo 
sigset_t old, new;
sigemptyset(&old);
sigemptyset(&new);
sigaddset(&new,15);

*/

if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: previous computation still running...");
 return;
 }
if (is_saveg_open==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Running not allowed while saving computed matrices !");
 return;
 }
if (is_reada_open==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Running not allowed while reading new A matrices !");
 return;
 }
if (is_examples_open==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Running not allowed while changing A e/o B matrices !");
 return;
 }
if (is_edit_a_open==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Running not allowed while changing A e/o B matrices !");
 return;
 }  
if (is_view_matrix_open==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Running not allowed while viewing G or R or U matrices !");
 return;
 }


 if ((committed.allocated==1)&&(committed.type !=0)) {
   is_running=1;
   g_idle_add((GtkFunction)fifo_inwin,NULL); /* activate the reading from fifo that Fortran will use to write */
   gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Beginning Computation .... ");
   set_options_(&is_debug,&is_verbose,&is_timings); /* push globals on ponte_f_f module */
   memcpy(&goals_committed,&goals_choice,sizeof(goals_choice));  /*freeze goals choices made up to now; */
   memcpy(&algorithms_committed,&algorithms_choice,sizeof(algorithms_choice));  /*freeze algorithms choices made up to now; */ 
   committed.maxnc = pi_choice.maxnc; /* freeze max number of vectors for Pi */
   committed.epspi = pi_choice.eps; /* freeze epspi of vectors for Pi */
   committed.fi_file_read = selected.fi_file_read ;
   committed.fi_file_dim = selected.fi_file_dim ;

/*    pthread_sigmask(SIG_BLOCK,&new,&old);   testing signals on threads ... booo */

    /* open a new tread for the Fortran computation */
if(is_debug==1) printf("on_main_menu_run_activate: starting new thread ...\n");
    my_iret = pthread_create( &my_thread_computation, NULL, (void *) start_computation , NULL);
    if (my_iret !=0) gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Sorry: there is some problem starting Fortran Routines !");
    pthread_detach(my_thread_computation);  /* this should free the resources used by computation routines  booo ?? */
    } else {
   gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Sorry: load some problem data first !"); 
   }
/*printf("Tempocputhread = %d\n\n",pthread_getcpuclockid((pthread_t) &my_thread_computation, clock_id));*/
}
/*********************************/

/*   start_computation:     starts fortran computation  in a separate thread 
 *   important note: NOTHING can be  sent to gtk window in this tread without 
 *   enclosing it with the two commands  gdk_threads_enter() ... gdk_threads_leave(); !!!! */ 
void * start_computation()
{
/* struct algorithms_str algorithms_choice,algorithms_committed;  */
/* struct goals_str goals_choice,goals_committed; */
/* struct running_problem_str committed; global  */
/* struct pi_parameters_str pi_choice; global*/
char line[256], buf[256];
time_t current_start, current_end;
long int elapsed; /* we suppose that time_t are long int, anyway using elapsed we are converting in int log */
int alg, goal, err, ittp, errp, interp, pi_nmax,pi_eps,pi_pinc;
double s,xdrift;
/*  cpu time for computation */
clockid_t clock_id; /* clock id for the thread of computations */
struct timespec tp; /* tp->tv_sec (seconds time_t) tp->tv_nsec (nanoseconds) */
double cpu_time;
int b_opt_flag; /* 1 if  optional B block is present B(:,:,1) for QBD, BN1 for MG1 and GIM1 */

if (committed.type==1) b_opt_flag=committed.is_b; else b_opt_flag=committed.is_bn1;
/* testing signals on threads ... booo ??
sigset_t old, new;
sigemptyset(&old);
sigemptyset(&new);
pthread_sigmask(SIG_BLOCK,&new,&old);
*/
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
/* pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);*/
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
/* print hostname, program name, time */
/* note: ctime adds a Line Feed to output */

if(is_debug) printf("on_main_menu_run_activate: thread main =    %ld\n",(unsigned long)my_thread_main);
if(is_debug) printf("on_main_menu_run_activate: thread calcoli = %ld\n",(unsigned long)my_thread_computation);
pthread_getcpuclockid((pthread_t) &my_thread_computation, &clock_id);
clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
cpu_time= (double)(tp.tv_sec) + (double)(tp.tv_nsec)* (double)1.0E-9;

sprintf(line,"\n===> Program  %s on  %s \n",my_prog_name, my_host_name);
append_fifo_(line);
if (committed.type ==1) sprintf(line,"===> QBD Problem");
if (committed.type ==2) sprintf(line,"===> M/G/1 Problem");
if (committed.type ==3) sprintf(line,"===> GI/M/1 Problem");
append_fifo_(line);
if (committed.example==0) sprintf(line,"\n===> Data Read From File "); else sprintf(line,"\n===> Data From Example %d",committed.example);
append_fifo_(line);
sprintf(line,"\n===> %d A blocks %d x %d",committed.matrix_a_num, committed.dimension_m,committed.dimension_m);
append_fifo_(line);
  /* do some checks on the A matrix, positivity and Stochasticity and write warnings ! */
    s=aamin();
    if (0.0 > s ) {
			sprintf(line,"\n===> Warning: Matrix A is not positive (minimum=%g)",s);
			append_fifo_(line);
                     }
   s=st_def();
   if (s > 1.0E-12)     {
			sprintf(line,"\n===> Warning: Matrix A has high stochastic defect (%g)",s);
			append_fifo_(line);
		    }
/* B0, B, BN1 are present ? */
if (committed.is_b0==1) {
       sprintf(line,"\n===> B0  %d x %d", committed.dimension_n,committed.dimension_n);
       append_fifo_(line);
	}
else {
       sprintf(line,"\n===> B0  not present");
       append_fifo_(line);
	}
if (committed.is_bn1==1) {
	if (committed.type ==3) sprintf(line,"\n===> BN1  %d x %d", committed.dimension_n,committed.dimension_m);
        else sprintf(line,"\n===> BN1  %d x %d", committed.dimension_m,committed.dimension_n);
       append_fifo_(line);
        }
else {
       sprintf(line,"\n===> BN1  not present");
       append_fifo_(line);
        }
if (committed.is_b==1) {
	if (committed.type ==3) sprintf(line,"\n===> %d B blocks  %d x %d", committed.matrix_b_num,committed.dimension_m,committed.dimension_n);
        else sprintf(line,"\n===> %d B blocks  %d x %d", committed.matrix_b_num, committed.dimension_n,committed.dimension_m);
       append_fifo_(line);
        }
else {
       sprintf(line,"\n===> B  not present");
       append_fifo_(line);
        }

 /* if X0 file has not been read, or is not of correct dimension, fall back to X0(0)=0 
    and after this, user X0 is not valid any more, as X0 has been reassigned   */
         if ((algorithms_committed.fi_base_u==1)&&(committed.fi_file_read==0)) {
                                sprintf(line,"\n===> Warning: Matrix X0 not present - fallback to X(0)=0");
                                append_fifo_(line);
                                algorithms_committed.fi_base_u=0;
                                algorithms_committed.fi_base0=1;
                                }
         if ((algorithms_committed.fi_shift_u==1)&&(committed.fi_file_read==0)) {
                                sprintf(line,"\n===> Warning: Matrix X0 not present - fallback to X(0)=0");
                                append_fifo_(line);
                                algorithms_committed.fi_shift_u=0;
                                algorithms_committed.fi_shift=1;
                                }
        if ((algorithms_committed.fi_base_u==1)&&(committed.fi_file_dim!=committed.dimension_m )) {
                                sprintf(line,"\n===> Warning: Matrix X0 has wrong dimension - fallback to X(0)=0");
                                append_fifo_(line);
                                algorithms_committed.fi_base_u=0;
                                algorithms_committed.fi_base0=1;
                                }
         if ((algorithms_committed.fi_shift_u==1)&&(committed.fi_file_dim!=committed.dimension_m )) {
                                sprintf(line,"\n===> Warning: Matrix X0 has wrong dimension - fallback to X(0)=0");
                                append_fifo_(line);
                                algorithms_committed.fi_shift_u=0;
                                algorithms_committed.fi_shift=1;
                                }


sprintf(line,"\n===> Algorithm: ");
/*  set alg flag */
alg=0;
switch (algorithms_committed.type) {
    case 1: /* CR  */
          strcat(line,"Cyclic Reduction "); /* alg=0 Base */
	  if (algorithms_committed.cr_shift==1) {alg=1; strcat(line,"(Shift Acceleration) ");}
	  if (algorithms_committed.cr_diag==1)  {alg=2; strcat(line,"(Diagonal Adjustment) ");}
          break;
    case 2: /* LR  */
          strcat(line,"Logarithmic Reduction "); /* alg=0 Base */
	  if (algorithms_committed.lr_shift==1) {alg=1; strcat(line,"(Shift Acceleration) ");}
	  if (algorithms_committed.lr_gth==1) {alg=2; strcat(line,"(Diagonal Adjustment) ");}
          break;
    case 3: /* FI */
          strcat(line,"Functional Iteration ");
          if ((algorithms_committed.fi_base0==1)&&(algorithms_committed.fi_natural==1)) { alg=0; strcat(line,"(Natural, Basic, x(0)=0 ) ");selected.fi_file_read=0; selected.fi_file_dim=0; committed.fi_file_read=0; committed.fi_file_dim=0; }
	  if ((algorithms_committed.fi_base1==1)&&(algorithms_committed.fi_natural==1)) { alg=1; strcat(line,"(Natural, Basic, x(0)=1 ) ");selected.fi_file_read=0; selected.fi_file_dim=0; committed.fi_file_read=0; committed.fi_file_dim=0;}
	  if ((algorithms_committed.fi_shift==1)&&(algorithms_committed.fi_natural==1)) { alg=2; strcat(line,"(Natural, Shift Acceleration) ");selected.fi_file_read=0; selected.fi_file_dim=0; committed.fi_file_read=0; committed.fi_file_dim=0;}
          if ((algorithms_committed.fi_base0==1)&&(algorithms_committed.fi_traditional==1)) { alg=3; strcat(line,"(Traditional, Basic, x(0)=0 ) ");selected.fi_file_read=0; selected.fi_file_dim=0; committed.fi_file_read=0; committed.fi_file_dim=0;}
          if ((algorithms_committed.fi_base1==1)&&(algorithms_committed.fi_traditional==1)) { alg=4; strcat(line,"(Traditional, Basic, x(0)=1 ) ");selected.fi_file_read=0; selected.fi_file_dim=0; committed.fi_file_read=0; committed.fi_file_dim=0;}
          if ((algorithms_committed.fi_shift==1)&&(algorithms_committed.fi_traditional==1)) { alg=5; strcat(line,"(Traditional, Shift Acceleration) ");selected.fi_file_read=0; selected.fi_file_dim=0; committed.fi_file_read=0; committed.fi_file_dim=0;}  
          if ((algorithms_committed.fi_base0==1)&&(algorithms_committed.fi_Ubased==1)) { alg=6; strcat(line,"(U-based, Basic, x(0)=0 ) ");selected.fi_file_read=0; selected.fi_file_dim=0; committed.fi_file_read=0; committed.fi_file_dim=0;}
          if ((algorithms_committed.fi_base1==1)&&(algorithms_committed.fi_Ubased==1)) { alg=7; strcat(line,"(U-based, Basic, x(0)=1 ) ");selected.fi_file_read=0; selected.fi_file_dim=0; committed.fi_file_read=0; committed.fi_file_dim=0;}
          if ((algorithms_committed.fi_shift==1)&&(algorithms_committed.fi_Ubased==1)) { alg=8; strcat(line,"(U-based, Shift Acceleration) ");selected.fi_file_read=0; selected.fi_file_dim=0; committed.fi_file_read=0; committed.fi_file_dim=0;} 
          if ((algorithms_committed.fi_base_u==1)&&(algorithms_committed.fi_natural==1)) { alg=9; strcat(line,"(Natural, Basic, x(0)=user ) ");}
          if ((algorithms_committed.fi_base_u==1)&&(algorithms_committed.fi_traditional==1)) { alg=10; strcat(line,"(Traditional, Basic, x(0)=user ) ");}
          if ((algorithms_committed.fi_base_u==1)&&(algorithms_committed.fi_Ubased==1)) { alg=11; strcat(line,"(U-based, Basic, x(0)=user ) ");}
          if ((algorithms_committed.fi_shift_u==1)&&(algorithms_committed.fi_natural==1)) { alg=12; strcat(line,"(Natural, Basic, x(0)=user ) ");}
          if ((algorithms_committed.fi_shift_u==1)&&(algorithms_committed.fi_traditional==1)) { alg=13; strcat(line,"(Traditional, Basic, x(0)=user ) ");}
          if ((algorithms_committed.fi_shift_u==1)&&(algorithms_committed.fi_Ubased==1)) { alg=14; strcat(line,"(U-based, Basic, x(0)=user ) ");}
	  break;
    case 4: /* IS */
          if(algorithms_committed.is_base==1){alg=0; strcat(line,"Invariant Subspace, Matrix Sign Iteration ");}         /* alg=0 Base  */
          if(algorithms_committed.is_balzer==1){alg=1;strcat(line,"Invariant Subspace, Matrix Sign Iteration with Balzer acceleration ");}/*alg=1 Balzer*/
          if(algorithms_committed.is_schur==1){alg=2;strcat(line,"Invariant Subspace, Schur decomposition");}/*alg=2 Schur */
          break;
          default:alg=0;
}
strcat(line,"\n");
append_fifo_(line);
current_start = time(NULL);
sprintf(line,"===> Computation Begins at %s",ctime(&current_start));
append_fifo_(line);
switch (committed.type) {
	case 1: /*QBD : set goal flag */
                goal= goals_committed.qbd_g +2*goals_committed.qbd_gr+3* goals_committed.qbd_gru+4* goals_committed.qbd_grupi;
		
                if (goals_committed.qbd_grupi==1) {
						/* check for B0, BN1 and stocasticity */
						if ((committed.is_b0==0)||(committed.is_bn1==0)) {
						   sprintf(line,"===> Sorry:  Pi computation impossible without loading B Matrices.\n");
						   append_fifo_(line);	
						   goals_committed.qbd_grupi=0; goals_committed.qbd_gru=1; 
						   }
						  if((goals_committed.qbd_grupi==1)&&(committed.is_b==0)&&(committed.dimension_m!=committed.dimension_n)) {
							/* B cannot be missing if the dimensions are different */
						   sprintf(line,"===> Sorry:  B is required if nonsquare blocks are given.\n");
                                                   append_fifo_(line);
                                                   goals_committed.qbd_grupi=0; goals_committed.qbd_gru=1;
						   }
						   if (goals_committed.qbd_grupi==1) { /* if not, no B0, BN1, B */
						        s=bbbmin();
                                                        if (0.0 > s ) {
                                                        sprintf(line,"===> Warning: Matrix B is not positive (minimum=%g)\n",s);
                                                        append_fifo_(line);
                                                        }
							s=st_def_b(1);
						   	if (s > 1.0E-12)     {
                        				    sprintf(line,"===> Warning: Matrix B has high stochastic defect (%g)\n",s);
                        				    append_fifo_(line);
                    					    }
							}

						} 
		switch (algorithms_committed.type) {
			case 1: /* CR  */
                                 /*parameters for CR in QBD case */
                                 ittp = choice[1].iterat;  
                                 errp = 11 - choice[1].err; /* epsilon(1.0d0) * 10 ** errp = actual error */
                                 
				 qbd_cr_solve_(&alg, &goal,&err,&errp,&ittp);
                                 
				 if(is_debug==1) printf("start_computation:  qbd_cr_solve_ returned err=%d\n",err);
                                 clean_statusb();
				 current_end = time(NULL);
				 elapsed = current_end - current_start;
		                 clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
				 cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                 if(err == 0) {
					sprintf(line,"===> Computation Ends  at  %s",ctime(&current_end));
					if (is_timings==1) {
				         	sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
					        line[strlen(line)-1]=0; /* chop the newline */
					        strcat(line,buf);
					        }
                                        append_fifo_(line);
					update_completed();
                                        /* Pi call + time call */
					getfdrift_(&xdrift);
					if(is_debug)  printf("start_computation: drift value = %g\n",xdrift);
					
					if ((goals_committed.qbd_grupi==1)&&(xdrift <0)) {
					if(is_debug==1) printf("start_computation:  beginning Pi computation\n");
					pi_nmax=committed.maxnc;
					pi_eps=11 - committed.epspi; /* similar to errp setup */
					qbd_pi_ponte_(&err,&pi_nmax,&pi_eps,&pi_pinc,&b_opt_flag);	
					current_end = time(NULL);
       		                        elapsed = current_end - current_start;
                		        clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                	cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
						if(err == 0) {
                                        		sprintf(line,"===> Pi Computation Ends  at  %s",ctime(&current_end));
                                        		if (is_timings==1) {
                                                	sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                	line[strlen(line)-1]=0; /* chop the newline */
                                                	strcat(line,buf);
                                                	}
                                        	append_fifo_(line);
						completed.pi=1;
						completed.maxnc= pi_pinc; /*  really computed components of Pi */
  						completed.epspi= committed.epspi; /* freeze epspi of vectors for Pi */
					         } else {
						sprintf(line,"===> Pi Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
	                                        append_fifo_(line);
						completed.pi=0;
						};
				             }	else {
                                                if ((goals_committed.qbd_grupi==1)&&(xdrift >=0)) {
                                                sprintf(line,"===> Pi Computation impossible with positive drift %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                } 
					     }
					} else {
					sprintf(line,"===> Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                        append_fifo_(line);
                                        invalidate_completed();
                                       }
				break;
			case 2: /* LR  */
                                /*parameters for LR in QBD case */
                                ittp = choice[2].iterat;
                                errp = 11 - choice[2].err; /* epsilon(1.0d0) * 10 ** errp = actual error */

			        qbd_lr_solve_(&alg, &goal,&err,&errp,&ittp);
				if(is_debug==1) printf("start_computation:  qbd_lr_solve_ returned err=%d\n",err);
                                clean_statusb();
                                current_end = time(NULL);
		                elapsed = current_end - current_start;
				clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                if(err == 0) {       
                                        sprintf(line,"===> Computation Ends  at   %s",ctime(&current_end));
					if (is_timings==1) {
                                                sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                line[strlen(line)-1]=0;  /* chop the newline */
                                                strcat(line,buf);
                                                }
                                        append_fifo_(line);
					if(is_timings) {};
                                        update_completed();

                                      /* Pi call + time call */
                                        getfdrift_(&xdrift);
                                        if(is_debug)  printf("start_computation: drift value = %g\n",xdrift);

                                        if ((goals_committed.qbd_grupi==1)&&(xdrift <0)) {
                                        if(is_debug==1) printf("start_computation:  beginning Pi computation\n");
                                        pi_nmax=committed.maxnc;
                                        pi_eps=11 - committed.epspi; /* similar to errp setup */
                                        qbd_pi_ponte_(&err,&pi_nmax,&pi_eps,&pi_pinc,&b_opt_flag);
                                        current_end = time(NULL);
                                        elapsed = current_end - current_start;
                                        clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                        cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                                if(err == 0) {
                                                        sprintf(line,"===> Pi Computation Ends  at  %s",ctime(&current_end));
                                                        if (is_timings==1) {
                                                        sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                        line[strlen(line)-1]=0; /* chop the newline */
                                                        strcat(line,buf);
                                                        }
                                                append_fifo_(line);
                                                completed.pi=1;
						completed.maxnc= pi_pinc; /*  really computed components of Pi */
                                                completed.epspi= committed.epspi; /* freeze epspi of vectors for Pi */
                                                } else {
                                                sprintf(line,"===> Pi Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                };
					    } else {
                                                if ((goals_committed.qbd_grupi==1)&&(xdrift >=0)) {
                                                sprintf(line,"===> Pi Computation impossible with positive drift %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                }
                                             }

                                         } else {
                                        sprintf(line,"===> Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                        append_fifo_(line);
                                        invalidate_completed();
                                       }

				break;
			case 3: /* FI */
				/*parameters for FI in QBD case */
				ittp = choice[3].iterat;
                                 errp = 11 - choice[3].err; /* epsilon(1.0d0) * 10 ** errp = actual error */
                                 qbd_fi_solve_(&alg, &goal,&err,&errp,&ittp);
                                 if(is_debug==1) printf("start_computation:  qbd_fi_solve_ returned err=%d\n",err);
                                 clean_statusb();
                                 current_end = time(NULL);
                                 elapsed = current_end - current_start;
                                 clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                 cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                 if(err == 0) {
                                        sprintf(line,"===> Computation Ends  at  %s",ctime(&current_end));
                                        if (is_timings==1) {
                                                sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                line[strlen(line)-1]=0; /* chop the newline */
                                                strcat(line,buf);
                                                };
                                        append_fifo_(line);
                                        update_completed();

                                      /* Pi call + time call */
                                        getfdrift_(&xdrift);
                                        if(is_debug)  printf("start_computation: drift value = %g\n",xdrift);

                                        if ((goals_committed.qbd_grupi==1)&&(xdrift <0)) {
                                        if(is_debug==1) printf("start_computation:  beginning Pi computation\n");
                                        pi_nmax=committed.maxnc;
                                        pi_eps=11 - committed.epspi; /* similar to errp setup */
                                        qbd_pi_ponte_(&err,&pi_nmax,&pi_eps,&pi_pinc,&b_opt_flag);
                                        current_end = time(NULL);
                                        elapsed = current_end - current_start;
                                        clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                        cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                                if(err == 0) {
                                                        sprintf(line,"===> Pi Computation Ends  at  %s",ctime(&current_end));
                                                        if (is_timings==1) {
                                                        sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                        line[strlen(line)-1]=0; /* chop the newline */
                                                        strcat(line,buf);
                                                        }
                                                append_fifo_(line);
                                                completed.pi=1;
                                                completed.maxnc= pi_pinc; /*  really computed components of Pi */
						completed.epspi= committed.epspi; /* freeze epspi of vectors for Pi */
                                                } else {
                                                sprintf(line,"===> Pi Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                };
					}  else {
                                                if ((goals_committed.qbd_grupi==1)&&(xdrift >=0)) {
                                                sprintf(line,"===> Pi Computation impossible with positive drift %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                }
                                             }

                                         } else {
                                        sprintf(line,"===> Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                        append_fifo_(line);
                                        invalidate_completed();
                                       }
				break;
			case 4: /* IS */
				/*parameters for IS in QBD case */
				ittp = choice[4].iterat;
                                 errp = 11 - choice[4].err; /* epsilon(1.0d0) * 10 ** errp = actual error */
                                 qbd_is_solve_(&alg, &goal,&err,&errp,&ittp);
                                 if(is_debug==1) printf("start_computation:  qbd_is_solve_ returned err=%d\n",err);
                                 clean_statusb();
                                 current_end = time(NULL);
                                 elapsed = current_end - current_start;
                                 clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                 cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                 if(err == 0) {
                                        sprintf(line,"===> Computation Ends  at  %s",ctime(&current_end));
                                        if (is_timings==1) {
                                                sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                line[strlen(line)-1]=0; /* chop the newline */
                                                strcat(line,buf);
                                                }
                                        append_fifo_(line);
                                        update_completed();


                                      /* Pi call + time call */
                                        getfdrift_(&xdrift);
                                        if(is_debug)  printf("start_computation: drift value = %g\n",xdrift);

                                        if ((goals_committed.qbd_grupi==1)&&(xdrift <0)) {
                                        if(is_debug==1) printf("start_computation:  beginning Pi computation\n");
                                        pi_nmax=committed.maxnc;
                                        pi_eps=11 - committed.epspi; /* similar to errp setup */
                                        qbd_pi_ponte_(&err,&pi_nmax,&pi_eps,&pi_pinc,&b_opt_flag);
                                        current_end = time(NULL);
                                        elapsed = current_end - current_start;
                                        clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                        cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                                if(err == 0) {
                                                        sprintf(line,"===> Pi Computation Ends  at  %s",ctime(&current_end));
                                                        if (is_timings==1) {
                                                        sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                        line[strlen(line)-1]=0; /* chop the newline */
                                                        strcat(line,buf);
                                                        }
                                                append_fifo_(line);
                                                completed.pi=1;
                                                completed.maxnc= pi_pinc; /*  really computed components of Pi */
						completed.epspi= committed.epspi; /* freeze epspi of vectors for Pi */
                                                } else {
                                                sprintf(line,"===> Pi Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                };
					}  else {
                                                if ((goals_committed.qbd_grupi==1)&&(xdrift >=0)) {
                                                sprintf(line,"===> Pi Computation impossible with positive drift %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                }
                                             }

                                         } else {
                                        sprintf(line,"===> Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                        append_fifo_(line);
                                        invalidate_completed();
                                       }
				break;
			default: {
				sprintf(line,"===> Sorry:  Algorithm for QBD  not yet implemented !");
			     	append_fifo_(line);
                                gdk_threads_enter();
                                gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Sorry:  Algorithm for QBD   not yet implemented !");
                                gdk_threads_leave();
				}
		}
		break;
	case 2: /*  M/G/1 set goal flag */
                goal= goals_committed.mg1_g + 2*goals_committed.mg1_gpi;
			if (goals_committed.mg1_gpi==1) {
		                                 /* check for B, B0 and stocasticity */
                                                if ((committed.is_b==0)||(committed.is_b0==0)) {
                                                   sprintf(line,"===> Sorry:  Pi computation impossible without loading B Matrices.\n");
                                                   append_fifo_(line);  
                                                  goals_committed.mg1_gpi=0; goals_committed.mg1_g=1; 
							}
						if((goals_committed.mg1_gpi==1)&&(committed.is_bn1==0)&&(committed.dimension_m!=committed.dimension_n)) {
                                                        /* BN1 cannot be missing if the dimensions are different */
                                                   sprintf(line,"===> Sorry:  BN1 is required if nonsquare blocks are given.\n");
                                                   append_fifo_(line);
                                                   goals_committed.mg1_gpi=0; goals_committed.mg1_g=1;
                                                   }
                                                   if (goals_committed.mg1_gpi==1) { /* if not, no B0, BN1, B */ 
							s=bbbmin();
                                                        if (0.0 > s ) {
                                                        sprintf(line,"===> Warning: Matrix B is not positive (minimum=%g)\n",s);
                                                        append_fifo_(line);
                                                        }
						        s=st_def_b(2);
                                                        if (s > 1.0E-12)     {
                                                             sprintf(line,"===> Warning: Matrix B has high stochastic defect (%g)\n",s);
                                                             append_fifo_(line);
                                                             }
						        } 
						   }
                switch (algorithms_committed.type) {
			case 1: /* CR  */
				 if(alg==2) { /* M/G/1 diagonal adjustment still to do */
				     sprintf(line,"===> Sorry:  Algorithm for M/G/1  not available !");
                                     append_fifo_(line);
                                     gdk_threads_enter();
                                     gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Sorry:  Algorithm for M/G/1   not available !");
                                     gdk_threads_leave();
                                     } else {
                                 /*parameters for CR in M/G/1 case  alg==0 and alg==1 i.e. basic and shift */
                                 ittp = choice[1].iterat;
				 interp = choice[1].interp;
                                 errp = 11 - choice[1].err; /* epsilon(1.0d0) * 10 ** errp = actual error */
				 need_a_transpose=1;
				 transpose_mata_(); 
                                 mg1_cr_solve_(&alg, &goal,&err,&errp,&ittp,&interp);
                                 if(is_debug==1) printf("start_computation:  mg1_cr_solve_ returned err=%d\n",err);
                                 clean_statusb();
                                 current_end = time(NULL);
                                 elapsed = current_end - current_start;
                                 clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                 cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                 if(need_a_transpose==1) {need_a_transpose=0; transpose_mata_();}
                                 if(err == 0) {
                                        sprintf(line,"===> Computation Ends  at  %s",ctime(&current_end));
                                        if (is_timings==1) {
                                                sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                line[strlen(line)-1]=0; /* chop the newline */
                                                strcat(line,buf);
                                                }
                                        append_fifo_(line);
                                        update_completed();


                                      /* Pi call + time call */
                                        getfdrift_(&xdrift);
                                        if(is_debug)  printf("start_computation: drift value = %g\n",xdrift);

                                        if ((goals_committed.mg1_gpi==1)&&(xdrift <0)) {
                                        if(is_debug==1) printf("start_computation:  beginning Pi computation\n");
                                        pi_nmax=committed.maxnc;
                                        pi_eps=11 - committed.epspi; /* similar to errp setup */
                                        mg1_pi_ponte_(&err,&pi_nmax,&pi_eps,&pi_pinc,&b_opt_flag);
                                        current_end = time(NULL);
                                        elapsed = current_end - current_start;
                                        clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                        cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                                if(err == 0) {
                                                        sprintf(line,"===> Pi Computation Ends  at  %s",ctime(&current_end));
                                                        if (is_timings==1) {
                                                        sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                        line[strlen(line)-1]=0; /* chop the newline */
                                                        strcat(line,buf);
                                                        }
                                                append_fifo_(line);
                                                completed.pi=1;
                                                completed.maxnc= pi_pinc; /*  really computed components of Pi */
                                                completed.epspi= committed.epspi; /* freeze epspi of vectors for Pi */
                                                } else {
                                                sprintf(line,"===> Pi Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                }
					}  else {
                                                if ((goals_committed.mg1_gpi==1)&&(xdrift >=0)) {
                                                sprintf(line,"===> Pi Computation impossible with positive drift %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                }
                                             }

                                         } else {
                                        sprintf(line,"===> Computation Aborted  at %s\n\n",ctime(&current_end));
                                        append_fifo_(line);
                                        invalidate_completed();
                                       }
				}
                                break;
			case 2: /* LR */ {
                                sprintf(line,"===> Sorry:  Algorithm Logarithmic Reduction does not exist for M/G/1 !");
                                append_fifo_(line);
                                gdk_threads_enter();
                                gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Sorry:  Algorithm Logarithmic Reduction does not exist for M/G/1 !");
                                gdk_threads_leave();
                                }
				break;
			case 3:/* FI */
                                /*parameters for FI in M/G/1 case  alg==0 base x(0)=0, alg==1 base x(0)=1, alg==2 shift  */
                                ittp = choice[3].iterat;
                                 errp = 11 - choice[3].err; /* epsilon(1.0d0) * 10 ** errp = actual error */
                                 mg1_fi_solve_(&alg, &goal,&err,&errp,&ittp);
                                 if(is_debug==1) printf("start_computation:  mg1_fi_solve_ returned err=%d\n",err);
                                 clean_statusb();
                                 current_end = time(NULL);
                                 elapsed = current_end - current_start;
                                 clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                 cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                 if(err == 0) {
                                        sprintf(line,"===> Computation Ends  at  %s",ctime(&current_end));
                                        if (is_timings==1) {
                                                sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                line[strlen(line)-1]=0; /* chop the newline */
                                                strcat(line,buf);
                                                }
                                        append_fifo_(line);
                                        update_completed();


                                   /* Pi call + time call */
                                        getfdrift_(&xdrift);
                                        if(is_debug)  printf("start_computation: drift value = %g\n",xdrift);

                                        if ((goals_committed.mg1_gpi==1)&&(xdrift <0)) {
                                        if(is_debug==1) printf("start_computation:  beginning Pi computation\n");
                                        pi_nmax=committed.maxnc;
                                        pi_eps=11 - committed.epspi; /* similar to errp setup */
                                        mg1_pi_ponte_(&err,&pi_nmax,&pi_eps,&pi_pinc,&b_opt_flag);
                                        current_end = time(NULL);
                                        elapsed = current_end - current_start;
                                        clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                        cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                                if(err == 0) {
                                                        sprintf(line,"===> Pi Computation Ends  at  %s",ctime(&current_end));
                                                        if (is_timings==1) {
                                                        sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                        line[strlen(line)-1]=0; /* chop the newline */
                                                        strcat(line,buf);
                                                        }
                                                append_fifo_(line);
                                                completed.pi=1;
                                                completed.maxnc= pi_pinc; /*  really computed components of Pi */
                                                completed.epspi= committed.epspi; /* freeze epspi of vectors for Pi */
                                                } else {
                                                sprintf(line,"===> Pi Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                };
					}  else {
                                                if ((goals_committed.mg1_gpi==1)&&(xdrift >=0)) {
                                                sprintf(line,"===> Pi Computation impossible with positive drift %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                }
                                             }

                                         } else {
                                        sprintf(line,"===> Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                        append_fifo_(line);
                                        invalidate_completed();
                                       }
                                break;

			case 4:/* IS */
                                /*parameters for IS in M/G/1 case alg==0 no variations */
                                ittp = choice[4].iterat;
                                 errp = 11 - choice[4].err; /* epsilon(1.0d0) * 10 ** errp = actual error */
				 if(is_debug==1) printf("start_computation:  gim1_is_solve_ starting with alg=%d\n",alg);
                                 mg1_is_solve_(&alg, &goal,&err,&errp,&ittp);
                                 if(is_debug==1) printf("start_computation:  mg1_is_solve_ returned err=%d\n",err);
                                 clean_statusb();
                                 current_end = time(NULL);
                                 elapsed = current_end - current_start;
				 clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                 cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                 if(err == 0) {
                                        sprintf(line,"===> Computation Ends  at  %s",ctime(&current_end));
                                        if (is_timings==1) {
                                                sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                line[strlen(line)-1]=0; /* chop the newline */
                                                strcat(line,buf);
                                                }
                                        append_fifo_(line);
                                        update_completed();


                                   /* Pi call + time call */
                                        getfdrift_(&xdrift);
                                        if(is_debug)  printf("start_computation: drift value = %g\n",xdrift);

                                        if ((goals_committed.mg1_gpi==1)&&(xdrift <0)) {
                                        if(is_debug==1) printf("start_computation:  beginning Pi computation\n");
                                        pi_nmax=committed.maxnc;
                                        pi_eps=11 - committed.epspi; /* similar to errp setup */
                                        mg1_pi_ponte_(&err,&pi_nmax,&pi_eps,&pi_pinc,&b_opt_flag);
                                        current_end = time(NULL);
                                        elapsed = current_end - current_start;
                                        clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                        cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                                if(err == 0) {
                                                        sprintf(line,"===> Pi Computation Ends  at  %s",ctime(&current_end));
                                                        if (is_timings==1) {
                                                        sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                        line[strlen(line)-1]=0; /* chop the newline */
                                                        strcat(line,buf);
                                                        }
                                                append_fifo_(line);
                                                completed.pi=1;
                                                completed.maxnc= pi_pinc; /*  really computed components of Pi */
                                                completed.epspi= committed.epspi; /* freeze epspi of vectors for Pi */

                                                } else {
                                                sprintf(line,"===> Pi Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                };
					}  else {
                                                if ((goals_committed.mg1_gpi==1)&&(xdrift >=0)) {
                                                sprintf(line,"===> Pi Computation impossible with positive drift %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                }
                                             }

                                         } else {
                                        sprintf(line,"===> Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                        append_fifo_(line);
                                        invalidate_completed();
                                       }
                                break;
			default: {
                                sprintf(line,"===> Sorry:  Algorithm for M/G/1  not yet implemented !");
                                append_fifo_(line);
                                gdk_threads_enter();
                                gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Sorry:  Algorithm for M/G/1   not yet implemented !");
                                gdk_threads_leave();
                                }

		}		
		break; 
	case 3: /*  GI/M/1 set goal flag */
                goal= goals_committed.gim1_r + 2*goals_committed.gim1_rpi;
                if (goals_committed.gim1_rpi==1) {
                                                /* check for B, B0 and stocasticity */
                                                if ((committed.is_b==0)||(committed.is_b0==0)) {
                                                   sprintf(line,"===> Sorry:  Pi computation impossible without loading B Matrices.\n");
                                                   append_fifo_(line);  
                                                   goals_committed.gim1_rpi=0; goals_committed.gim1_r=1; 
                                                   }
						if((goals_committed.gim1_rpi==1)&&(committed.is_bn1==0)&&(committed.dimension_m!=committed.dimension_n)) {
                                                        /* BN1 cannot be missing if the dimensions are different */
                                                   sprintf(line,"===> Sorry:  BN1 is required if nonsquare blocks are given.\n");
                                                   append_fifo_(line);
                                                   goals_committed.gim1_rpi=0; goals_committed.gim1_r=1;
						   }
						 if(goals_committed.gim1_rpi==1) {/* else no B0, B, BN1 */
                                                        s=bbbmin();
                                                        if (0.0 > s ) {
                                                        sprintf(line,"===> Warning: Matrix B is not positive (minimum=%g)\n",s);
                                                        append_fifo_(line);
                                                        }
					 	      s=st_def_b(3);
                                                      if (s > 1.0E-12)     {
                                                        sprintf(line,"===> Warning: Matrix B has high stochastic defect (%g)\n",s);
                                                        append_fifo_(line);
                                                        }
						     }
						}
                switch (algorithms_committed.type) {
                        case 1: /* CR  */
                                 if(alg==2) { /* GI/M/1 diagonal adjustment still to do */
                                     sprintf(line,"===> Sorry:  Algorithm for GI/M/1  not available !");
                                     append_fifo_(line);
                                     gdk_threads_enter();
                                     gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Sorry:  Algorithm for GI/M/1   not available !");
                                     gdk_threads_leave();
                                     } else {
                                 /*parameters for CR in GI/M/1 case  alg==0 and alg==1 i.e. basic and shift */
                                 ittp = choice[1].iterat;
                                 interp = choice[1].interp;
                                 errp = 11 - choice[1].err; /* epsilon(1.0d0) * 10 ** errp = actual error */
                                 gim1_cr_solve_(&alg, &goal,&err,&errp,&ittp,&interp);
                                 if(is_debug==1) printf("start_computation:  gim1_cr_solve_ returned err=%d\n",err);
                                 clean_statusb();
                                 current_end = time(NULL);
                                 elapsed = current_end - current_start;
                                 clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                 cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                 if(err == 0) {
                                        sprintf(line,"===> Computation Ends  at  %s",ctime(&current_end));
                                        if (is_timings==1) {
                                                sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                line[strlen(line)-1]=0; /* chop the newline */
                                                strcat(line,buf);
                                                }
                                        append_fifo_(line);
                                        update_completed();

                                 /* Pi call + time call */
                                        getfdrift_(&xdrift);
                                        if(is_debug)  printf("start_computation: drift value = %g\n",xdrift);

                                        if ((goals_committed.gim1_rpi==1)&&(xdrift <0)) {
                                        if(is_debug==1) printf("start_computation:  beginning Pi computation\n");
                                        pi_nmax=committed.maxnc;
                                        pi_eps=11 - committed.epspi; /* similar to errp setup */
                                        gim1_pi_ponte_(&err,&pi_nmax,&pi_eps,&pi_pinc,&b_opt_flag);
                                        current_end = time(NULL);
                                        elapsed = current_end - current_start;
                                        clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                        cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                                if(err == 0) {
                                                        sprintf(line,"===> Pi Computation Ends  at  %s",ctime(&current_end));
                                                        if (is_timings==1) {
                                                        sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                        line[strlen(line)-1]=0; /* chop the newline */
                                                        strcat(line,buf);
                                                        }
                                                append_fifo_(line);
                                                completed.pi=1;
                                                completed.maxnc= pi_pinc; /*  really computed components of Pi */
                                                completed.epspi= committed.epspi; /* freeze epspi of vectors for Pi */

                                                } else {
                                                sprintf(line,"===> Pi Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                };
					}  else {
                                                if ((goals_committed.gim1_rpi==1)&&(xdrift >=0)) {
                                                sprintf(line,"===> Pi Computation impossible with positive drift %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                }
                                             }

                                         } else {
                                        sprintf(line,"===> Computation Aborted  at %s\n\n",ctime(&current_end));
                                        append_fifo_(line);
                                        invalidate_completed();
                                       }
                                }
                                break;
                        case 2: /* LR */ {
                                sprintf(line,"===> Sorry:  Algorithm Logarithmic Reduction does not exist for GI/M/1 !");
                                append_fifo_(line);
                                gdk_threads_enter();
                                gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Sorry:  Algorithm Logarithmic Reduction does not exist for GI/M/1 !");
                                gdk_threads_leave();
                                }
                                break;
                       case 3:/* FI */
                                /*parameters for FI in GI/M/1 case  alg==0 base x(0)=0, alg==1 base x(0)=1, alg==2 shift  */
                                ittp = choice[3].iterat;
                                 errp = 11 - choice[3].err; /* epsilon(1.0d0) * 10 ** errp = actual error */
                                 gim1_fi_solve_(&alg, &goal,&err,&errp,&ittp);
                                 if(is_debug==1) printf("start_computation:  gim1_fi_solve_ returned err=%d\n",err);
                                 clean_statusb();
                                 current_end = time(NULL);
                                 elapsed = current_end - current_start;
                                 clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                 cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                 if(err == 0) {
                                        sprintf(line,"===> Computation Ends  at  %s",ctime(&current_end));
                                        if (is_timings==1) {
                                                sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                line[strlen(line)-1]=0; /* chop the newline */
                                                strcat(line,buf);
                                                }
                                        append_fifo_(line);
                                        update_completed();

                           /* Pi call + time call */
                                        getfdrift_(&xdrift);
                                        if(is_debug)  printf("start_computation: drift value = %g\n",xdrift);

                                        if ((goals_committed.gim1_rpi==1)&&(xdrift <0)) {
                                        if(is_debug==1) printf("start_computation:  beginning Pi computation\n");
                                        pi_nmax=committed.maxnc;
                                        pi_eps=11 - committed.epspi; /* similar to errp setup */
                                        gim1_pi_ponte_(&err,&pi_nmax,&pi_eps,&pi_pinc,&b_opt_flag);
                                        current_end = time(NULL);
                                        elapsed = current_end - current_start;
                                        clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                        cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                                if(err == 0) {
                                                        sprintf(line,"===> Pi Computation Ends  at  %s",ctime(&current_end));
                                                        if (is_timings==1) {
                                                        sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                        line[strlen(line)-1]=0; /* chop the newline */
                                                        strcat(line,buf);
                                                        }
                                                append_fifo_(line);
                                                completed.pi=1;
                                                completed.maxnc= pi_pinc; /*  really computed components of Pi */
                                                completed.epspi= committed.epspi; /* freeze epspi of vectors for Pi */

                                                } else {
                                                sprintf(line,"===> Pi Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                };
					}  else {
                                                if ((goals_committed.gim1_rpi==1)&&(xdrift >=0)) {
                                                sprintf(line,"===> Pi Computation impossible with positive drift %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                }
                                             }


                                         } else {
                                        sprintf(line,"===> Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                        append_fifo_(line);
                                        invalidate_completed();
                                       }
                                break;
                        case 4:/* IS */
                                /*parameters for IS in GI/M/1 case alg==0 no variations */
                                ittp = choice[4].iterat;
                                 errp = 11 - choice[4].err; /* epsilon(1.0d0) * 10 ** errp = actual error */
                                 gim1_is_solve_(&alg, &goal,&err,&errp,&ittp);
                                 if(is_debug==1) printf("start_computation:  gim1_is_solve_ returned err=%d\n",err);
                                 clean_statusb();
                                 current_end = time(NULL);
                                 elapsed = current_end - current_start;
                                 clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                 cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                 if(err == 0) {
                                        sprintf(line,"===> Computation Ends  at  %s",ctime(&current_end));
                                        if (is_timings==1) {
                                                sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                line[strlen(line)-1]=0; /* chop the newline */
                                                strcat(line,buf);
                                                }
                                        append_fifo_(line);
                                        update_completed();
   
                           /* Pi call + time call */
                                        getfdrift_(&xdrift);
                                        if(is_debug)  printf("start_computation: drift value = %g\n",xdrift);

                                        if ((goals_committed.gim1_rpi==1)&&(xdrift <0)) {
                                        if(is_debug==1) printf("start_computation:  beginning Pi computation\n");
                                        pi_nmax=committed.maxnc;
                                        pi_eps=11 - committed.epspi; /* similar to errp setup */
                                        gim1_pi_ponte_(&err,&pi_nmax,&pi_eps,&pi_pinc,&b_opt_flag);
                                        current_end = time(NULL);
                                        elapsed = current_end - current_start;
                                        clock_gettime(CLOCK_THREAD_CPUTIME_ID,&tp);
                                        cpu_time = (double)(tp.tv_sec) + (double)(tp.tv_nsec)*(double)1.0E-9 - cpu_time;
                                                if(err == 0) {
                                                        sprintf(line,"===> Pi Computation Ends  at  %s",ctime(&current_end));
                                                        if (is_timings==1) {
                                                        sprintf(buf," [ elapsed=%ldsec  CPU=%3.3lfsec ]\n\n",current_end-current_start,cpu_time);
                                                        line[strlen(line)-1]=0; /* chop the newline */
                                                        strcat(line,buf);
                                                        }
                                                append_fifo_(line);
                                                completed.pi=1;
                                                completed.maxnc= pi_pinc; /*  really computed components of Pi */
                                                completed.epspi= committed.epspi; /* freeze epspi of vectors for Pi */

                                                } else {
                                                sprintf(line,"===> Pi Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                };
					}  else {
                                                if ((goals_committed.gim1_rpi==1)&&(xdrift >=0)) {
                                                sprintf(line,"===> Pi Computation impossible with positive drift %s\n\n",ctime(&current_end));
                                                append_fifo_(line);
                                                completed.pi=0;
                                                }
                                             }


                                      } else {
                                        sprintf(line,"===> Computation Aborted (insufficient memory) at %s\n\n",ctime(&current_end));
                                        append_fifo_(line);
                                        invalidate_completed();
                                       }
                                break;
                        default: {
                                sprintf(line,"===> Sorry:  Algorithm for GI/M/1  not yet implemented !");
                                append_fifo_(line);
                                gdk_threads_enter();
                                gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Sorry:  Algorithm for GI/M/1   not yet implemented !");
                                gdk_threads_leave();
                                }

                }
                break;
	default:{
		sprintf(line,"===> Sorry: Algorithms for this Problem  not yet implemented !");
		append_fifo_(line);
                gdk_threads_enter(); 
		gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Sorry:  Algorithms for this Problem  not yet implemented !");
		gdk_threads_leave(); 
		}
}

is_running=0;
/* update situation bar if some change has been made during calculation */
g_idle_add((GtkFunction) selection_uptodaten,NULL);
return NULL;
}
/*********************************/

/* Main Menu: Stop        */
void
on_main_menu_stop_activate     (GtkMenuItem *menuitem, gpointer  user_data)
{
if(is_running==0) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  No computation to interrupt !");
 }
 else
 {
 if(is_debug==1) printf("on_main_menu_stop_activate: activating idle stop_computations routine\n");
 g_idle_add((GtkFunction) stop_computations,NULL);
 }
}
/*********************************/

/* Main Menu: Edit A    opens window to view and edit A   */
void 
on_main_menu_edit_a_activate    (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_edit_a_open; global   */    
/* int is_examples_open; global */
/* int is_runnig; global        */
/* int reada_open; global       */
/* GtkWidget statusb; global    */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Wait till the end of computation, please !");
    return;
    }
if(is_savea_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Inspect and Modify and Read A at the same time  !");
    return;
    }
if (is_examples_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Inspect and Modify A while Loading it from Examples  ");
    return;
    }
if (is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Inspect and Modify A while Loading it from Files ");
    return;
    }
if (committed.allocated == 0) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No A Matrix Available to Inspect");
    return;
    }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No second  window Edit Aallowed");
    return;
    }

clean_statusb();
/* not running, not writing A, not loading examples, not reading A : we can open edit A */
is_edit_a_open=1;
create_edit_a_window();
}
/*********************************/

/* Main Menu: Edit B    opens window to view and edit B   */
void
on_main_menu_edit_b_activate    (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_edit_b_open; global   */    
/* int is_examples_open; global */
/* int is_runnig; global        */
/* int readb_open; global       */
/* GtkWidget statusb; global    */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Wait till the end of computation, please !");
    return;
    }
if(is_saveb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Inspect and Modify and Read B at the same time  !");
    return;
    }
if (is_examples_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Inspect and Modify B while Loading it from Examples  ");
    return;
    }
if (is_readb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Inspect and Modify B while Loading it from Files ");
    return;
    }
if (is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Inspect and Modify B while Loading A  from Files ");
    return;
    }

if (committed.is_b0 == 0) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No B Matrix Available to Inspect");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No second  window Edit Aallowed");
    return;
    }

clean_statusb();
/* not running, not writing B, not loading examples, not reading B : we can open edit B */ 
is_edit_b_open=1;
create_edit_b_window();
}
/*********************************/

/* Main Menu: View matrix G/R/U  opens window to view a matrix, G or R or U */
void
on_main_menu_view_matrix_activate(GtkMenuItem *menuitem, gpointer user_data)
{
/* int is_runnig; global        */

if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Wait till the end of computation, please !");
    return;
    }
if (is_view_matrix_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," No second  window Edit Allowed");
    return;
    }
/* is some result available ? if not set pview.is_gru = 0 and open anyway to see from file */

if ((completed.g==0)&&(completed.u==0)&&(completed.r==0)) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Warning: No G,R or U Matrix Available to View");
 pview.is_gru =0;
 is_view_matrix_open=1;
 create_view_window(); /*create with inactive read memory ! */
 return;
 }
if (completed.r !=0) pview.is_gru =2;
if (completed.g !=0) pview.is_gru =1;
clean_statusb();
is_view_matrix_open=1;
if(is_debug==1) printf("on_main_menu_view_matrix_activate: pview.is_gru=%d\n",pview.is_gru);
create_view_window(); /*create with active read memory and default r or g preferring g if both */
}
/*********************************/

/* Main Menu: View Pi */
void
on_main_menu_view_pi_activate(GtkMenuItem *menuitem, gpointer user_data)
{
/* int is_runnig; global        */

if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Wait till the end of computation, please !");
    return;
    }
/* is some result available ? if not  open anyway to see from file ? */
if (completed.pi==0) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Warning: No Pi Available to View");
 return;
 }
clean_statusb();
/* gtk_statusbar_push(GTK_STATUSBAR(statusb),0," ****  STILL TO IMPLEMENT ***  !");
 */
create_view_pi_window();
}
/*********************************/


/* Main Menu: Pause      
void
on_main_menu_pause_activate (GtkMenuItem *menuitem, gpointer user_data )
{
 GtkWidget statusb; global    
gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Sorry:  Pause is not yet implemented !");

pthread_kill(my_thread_computation, 15);

}
*********************************/

/* Main Menu: Help Open  */
void
on_main_menu_help_activate   (GtkMenuItem  *menuitem, gpointer  user_data)
{
clean_statusb();
if (is_help_open == 0) {  /* do not open more than one help window */
   is_help_open=1;
   create_window_help();
   }
}
/*********************************/

/* About:  Close */
void
on_about_closebutton_clicked (GtkButton *button, gpointer  user_data)
{
gtk_widget_destroy(gtk_widget_get_toplevel(GTK_WIDGET(button)));
}
/*********************************/

/* About:  destroy */
void
on_about_destroy_activate (GtkWidget *ww, gpointer  user_data)
{
is_about_open = 0;
}
/*********************************/


/* Help:  Close*/
void
on_help_closebutton_clicked   (GtkButton  *button, gpointer user_data)
{
gtk_widget_destroy(gtk_widget_get_toplevel(GTK_WIDGET(button)));
}
/*********************************/

/* Help:  destroy */
void
on_help_destroy_activate   (GtkWidget *ww, gpointer user_data)
{
is_help_open = 0;
}
/*********************************/


/* clean statusbar */
void clean_statusb(void)
{
/* GtkWidget *statusb; global    */
gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"");
}
/*********************************/

/* Main Menu: File Menu: QBD */
void
on_main_menu_problem_qbd      (GtkMenuItem *menuitem , gpointer user_data)
{
/* struct running_problem_str  selected; global */
/* GtkWidget *statusb; global   */
/* int is_reada_open; global */
/* int is_running; global */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
    return;
    }
if(is_savea_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Read and Write A at the same time  !");
    return;
    }
if (is_examples_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A matrices form File or from Examples !");
    return;
    }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Read A from File while editing A");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Read A from File while editing B");
    return;
    }

/* not running, not writing A, not loading examples, we can read A for the problem */
clean_statusb();
 if(is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You where just reading A ...");
    return;
    }
selected_a_problem = 1; /* pass the info to read a window */
/* open the reada fileselection */
is_reada_open=1;
reada_fs = create_fileselection_reada ();
gtk_widget_show (reada_fs);
}
/*********************************/

/* Main Menu: File Menu: MG1 */
void
on_main_menu_problem_mg1      (GtkMenuItem *menuitem , gpointer user_data)
{
/* struct running_problem_str  selected; global */
/* GtkWidget *statusb; global   */
/* int is_reada_open; global */
/* int is_running; global */
/* if algorithms_choice.type = 2 reset it to default */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
    return;
    }
if(is_savea_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Read and Write A at the same time  !");
    return;
    }
if (is_examples_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A matrices form File or from Examples !");
    return;
    }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Read A from File while editing A");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Read A from File while editing B");
    return;
    }

/* not running, not writing A, not loading examples, we can read A for the problem */
clean_statusb();
 if(is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You where just reading A ...");
    return;
    }
selected_a_problem=2; /* pass the info to read a window */
/* open the reada fileselection */
is_reada_open=1;
reada_fs = create_fileselection_reada ();
gtk_widget_show (reada_fs);
}
/*********************************/

/* Main Menu: File Menu: GIM1 */
void
on_main_menu_problem_gm1      (GtkMenuItem *menuitem , gpointer user_data)
{
/* struct running_problem_str  selected; global */
/* GtkWidget *statusb; global   */
/* int is_reada_open; global */
/* int is_running; global */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
    return;
    }
if(is_savea_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You cannot Read and Write A at the same time  !");
    return;
    }
if (is_examples_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A matrices form File or from Examples !");
    return;
    }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Read A from File while editing A");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Read A from File while editing B");
    return;
    }

/* not running, not writing A, not loading examples, we can read A for the problem */
clean_statusb();
 if(is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You where just reading A ...");
    return;
    }
selected_a_problem=3; /* pass the info to read a window */
/* open the reada fileselection */
is_reada_open=1;
reada_fs = create_fileselection_reada ();
gtk_widget_show (reada_fs);
}
/*********************************/

/* Main Menu: Examples Menu: examples select */
void
on_main_menu_problem_examples_e    (GtkMenuItem *menuitem, gpointer user_data)
{
/* int is_examples_open; global */
/* int is_reada_open; global */
if ((is_examples_open==0)&&(is_reada_open==0)&&(is_readb_open==0))  gtk_menu_item_select (menuitem); 
}
/*********************************/

/* Main Menu: Examples Menu: examples deselect */
void
on_main_menu_problem_examples_l    (GtkMenuItem *menuitem, gpointer user_data)
{
/* int is_examples_open; global */
gtk_menu_item_deselect (menuitem);
}
/*********************************/

/* Main Menu: Examples Menu: example 1 */
void 
on_main_menu_problem_example1    (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *statusb; global    */
/* int is_examples_open; global  */
/* int is_running; global */
/* int is_reada_open; global */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
    return;
    }
if (is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A matrices form File or from Examples !");
    return;
    }
if (is_readb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load B matrices form File or from Examples !");
    return;
    }

if (is_examples_open == 1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  No more that one Examples Window allowed.");
    return;
    }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set A from Example while editing A");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set B from Example while editing B");
    return;
    }

gtk_menu_item_activate   (menuitem);
clean_statusb(); 
create_window_examples(1);
is_examples_open = 1;
selected_es=1;
}
/*********************************/

/* Main Menu: Examples Menu: example 2 */
void
on_main_menu_problem_example2    (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *statusb; global    */
/* int is_examples_open; global  */
/* int is_running; global */
/* int is_reada_open; global */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
    return;
    }
if (is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A matrices form File or from Examples !");
    return;
    }
if (is_readb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load B matrices form File or from Examples !");
    return;
    }

if (is_examples_open == 1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  No more that one Examples Window allowed.");
    return;
    }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set A from Example while editing A");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set B from Example while editing B");
    return;
    }

gtk_menu_item_activate   (menuitem);
clean_statusb();
create_window_examples(2);
is_examples_open = 1;
selected_es=2;
}
/*********************************/

/* Main Menu: Examples Menu: example 3 */
void
on_main_menu_problem_example3    (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *statusb; global    */
/* int is_examples_open; global  */
/* int is_running; global */
/* int is_reada_open; global */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
    return;
    }
if (is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A matrices form File or from Examples !");
    return;
    }
if (is_readb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load B matrices form File or from Examples !");
    return;
    }

if (is_examples_open == 1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  No more that one Examples Window allowed.");
    return;
    }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set A from Example while editing A");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set B from Example while editing B");
    return;
    }

gtk_menu_item_activate   (menuitem);
clean_statusb();
create_window_examples(3);
is_examples_open = 1;
selected_es=3;
}
/*********************************/

/* Main Menu: Examples Menu: example 4 */
void
on_main_menu_problem_example4    (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *statusb; global    */
/* int is_examples_open; global  */
/* int is_running; global */
/* int is_reada_open; global */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
    return;
    }
if (is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A matrices form File or from Examples !");
    return;
    }
if (is_readb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load B matrices form File or from Examples !");
    return;
    }

if (is_examples_open == 1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  No more that one Examples Window allowed.");
    return;
    }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set A from Example while editing A");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set B from Example while editing B");
    return;
    }

gtk_menu_item_activate   (menuitem);
clean_statusb();
create_window_examples(4);
is_examples_open = 1;
selected_es=4;
}
/*********************************/

/* Main Menu: Examples Menu: example 5 */
void
on_main_menu_problem_example5    (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *statusb; global    */
/* int is_examples_open; global  */
/* int is_running; global */
/* int is_reada_open; global */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
    return;
    }
if (is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A matrices form File or from Examples !");
    return;
    }
if (is_readb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load B matrices form File or from Examples !");
    return;
    }

if (is_examples_open == 1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  No more that one Examples Window allowed.");
    return;
    }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set A from Example while editing A");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set B from Example while editing B");
    return;
    }

gtk_menu_item_activate   (menuitem);
clean_statusb();
create_window_examples(5);
is_examples_open = 1;
selected_es=5;
}
/*********************************/

/* Main Menu: Examples Menu: example 6 */
void
on_main_menu_problem_example6    (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *statusb; global    */
/* int is_examples_open; global  */
/* int is_running; global */
/* int is_reada_open; global */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
    return;
    }
if (is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A matrices form File or from Examples !");
    return;
    }
if (is_readb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load B matrices form File or from Examples !");
    return;
    }

if (is_examples_open == 1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  No more that one Examples Window allowed.");
    return;
    }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set A from Example while editing A");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set B from Example while editing B");
    return;
    }

gtk_menu_item_activate   (menuitem);
clean_statusb();
create_window_examples(6);
is_examples_open = 1;
selected_es=6;
}
/*********************************/

/* Main Menu: Examples Menu: example 7 */
void
on_main_menu_problem_example7    (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *statusb; global    */
/* int is_examples_open; global  */
/* int is_running; global */
/* int is_reada_open; global */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
    return;
    }
if (is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A matrices form File or from Examples !");
    return;
    }
if (is_readb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load B matrices form File or from Examples !");
    return;
    }

if (is_examples_open == 1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  No more that one Examples Window allowed.");
    return;
    }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set A from Example while editing A");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set B from Example while editing B");
    return;
    }

gtk_menu_item_activate   (menuitem);
clean_statusb();
create_window_examples(7);
is_examples_open = 1;
selected_es=7;
}
/*********************************/

/* Main Menu: Examples Menu: example 8 */
void
on_main_menu_problem_example8    (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *statusb; global    */
/* int is_examples_open; global  */
/* int is_running; global */
/* int is_reada_open; global */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
    return;
    }
if (is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A matrices form File or from Examples !");
    return;
    }
if (is_readb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load B matrices form File or from Examples !");
    return;
    }

if (is_examples_open == 1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  No more that one Examples Window allowed.");
    return;
    }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set A from Example while editing A");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set B from Example while editing B");
    return;
    }

gtk_menu_item_activate   (menuitem);
clean_statusb();
create_window_examples(8);
is_examples_open = 1;
selected_es=8;
}
/*********************************/

/* Main Menu: Examples Menu: example 9 */
void
on_main_menu_problem_example9    (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *statusb; global    */
/* int is_examples_open; global  */
/* int is_running; global */
/* int is_reada_open; global */
if(is_running==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
    return;
    }
if (is_reada_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load A matrices form File or from Examples !");
    return;
    }
if (is_readb_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Sorry: Either load B matrices form File or from Examples !");
    return;
    }

if (is_examples_open == 1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  No more that one Examples Window allowed.");
    return;
    }
if (is_edit_a_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set A from Example while editing A");
    return;
    }
if (is_edit_b_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," Sorry: You cannot Set B from Example while editing B");
    return;
    }

gtk_menu_item_activate   (menuitem);
clean_statusb();
create_window_examples(9);
is_examples_open = 1;
selected_es=9;
}
/*********************************/

/* poors man tooltips for menus */
void 
on_main_menu_quit_enter       (GtkMenuItem * menuitem, gpointer user_data )
{
/* GtkWidget *statusb; global    */
gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Quit Program (no warnings!)");
gtk_menu_item_select (menuitem);
}
/*********************************/

/* poors man tooltips for menus */
void on_main_menu_quit_leave       (GtkMenuItem *menuitem, gpointer  user_data )
{
/* GtkWidget *statusb; global    */
gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"");
gtk_menu_item_deselect (menuitem);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void 
on_main_menu_algorithms_cyclicr_basic (GtkMenuItem *menuitem, gpointer user_data)
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please ! ");
 }
 algorithms_choice.type = 1;        /* cyclic reduction */
 algorithms_choice.cr_base =1;
 algorithms_choice.cr_shift = 0;
 algorithms_choice.cr_diag = 0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void
on_main_menu_algorithms_cyclicr_shift (GtkMenuItem *menuitem, gpointer user_data)
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 algorithms_choice.type = 1;        /* cyclic reduction */
 algorithms_choice.cr_base =0;
 algorithms_choice.cr_shift = 1;
 algorithms_choice.cr_diag = 0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void
on_main_menu_algorithms_cyclicr_diag (GtkMenuItem *menuitem, gpointer user_data)
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 algorithms_choice.type = 1;        /* cyclic reduction */
 algorithms_choice.cr_base =0;
 algorithms_choice.cr_shift = 0;
 algorithms_choice.cr_diag = 1;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void
on_main_menu_algorithms_logarithmicr_basic (GtkMenuItem *menuitem, gpointer user_data)
{
/* int is_running; global */
/* not allowed if selected.type != 1 ie not QBD */
clean_statusb();
if (selected.type != 1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Available for QBD Problems only !");
    return;
    }
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
    }
 algorithms_choice.type = 2;        /* logarithmic reduction */
 algorithms_choice.lr_base =1;
 algorithms_choice.lr_shift = 0;
 algorithms_choice.lr_gth = 0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void
on_main_menu_algorithms_logarithmicr_shift (GtkMenuItem *menuitem, gpointer user_data)
{
/* int is_running; global */
/* not allowed if selected.type != 1 ie not QBD */
clean_statusb();
if (selected.type != 1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Available for QBD Problems only !");
    return;
    }
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
    }
 algorithms_choice.type = 2;        /* logarithmic reduction */
 algorithms_choice.lr_base =0;
 algorithms_choice.lr_shift = 1;
 algorithms_choice.lr_gth = 0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void
on_main_menu_algorithms_logarithmicr_gth (GtkMenuItem *menuitem, gpointer user_data)
{
/* int is_running; global */
/* not allowed if selected.type != 1 ie not QBD */
clean_statusb();
if (selected.type != 1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Available for QBD Problems only !");
    return;
    }
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
    }
 algorithms_choice.type = 2;        /* logarithmic reduction */
 algorithms_choice.lr_base =0;
 algorithms_choice.lr_shift = 0;
 algorithms_choice.lr_gth = 1;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void 
on_main_menu_algorithms_funciter_basic0 (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 algorithms_choice.type = 3;        /* functional iteration */
 algorithms_choice.fi_base0 = 1;
 algorithms_choice.fi_base1 = 0;
 algorithms_choice.fi_base_u = 0;
 algorithms_choice.fi_shift = 0;
 algorithms_choice.fi_shift_u = 0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void 
on_main_menu_algorithms_funciter_basic1 (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 algorithms_choice.type = 3;        /* functional iteration */
 algorithms_choice.fi_base0 = 0;
 algorithms_choice.fi_base1 = 1;
 algorithms_choice.fi_base_u = 0;
 algorithms_choice.fi_shift = 0;
 algorithms_choice.fi_shift_u = 0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void
on_main_menu_algorithms_funciter_basic_u (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 algorithms_choice.type = 3;        /* functional iteration */
 algorithms_choice.fi_base0 = 0;
 algorithms_choice.fi_base1 = 0;
 algorithms_choice.fi_base_u = 1;
 algorithms_choice.fi_shift = 0;
 algorithms_choice.fi_shift_u = 0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/



/*  Main Menu: Algorithms - just set algorithms_choice structure */
void 
on_main_menu_algorithms_funciter_shift (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 algorithms_choice.type = 3;        /* functional iteration */
 algorithms_choice.fi_base0 = 0;
 algorithms_choice.fi_base1 = 0;
 algorithms_choice.fi_base_u = 0;
 algorithms_choice.fi_shift = 1;
 algorithms_choice.fi_shift_u = 0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void
on_main_menu_algorithms_funciter_shift_u (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 algorithms_choice.type = 3;        /* functional iteration */
 algorithms_choice.fi_base0 = 0;
 algorithms_choice.fi_base1 = 0;
 algorithms_choice.fi_base_u = 0;
 algorithms_choice.fi_shift = 0;
 algorithms_choice.fi_shift_u = 1;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/


/*  Main Menu: Algorithms - just set algorithms_choice structure */
void 
on_main_menu_algorithms_funciter_natural (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 algorithms_choice.type = 3;        /* functional iteration */
 algorithms_choice.fi_natural=1;
 algorithms_choice.fi_traditional=0;
 algorithms_choice.fi_Ubased=0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void 
on_main_menu_algorithms_funciter_traditional (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 algorithms_choice.type = 3;        /* functional iteration */
 algorithms_choice.fi_natural=0;
 algorithms_choice.fi_traditional=1;
 algorithms_choice.fi_Ubased=0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void 
on_main_menu_algorithms_funciter_Ubased (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 algorithms_choice.type = 3;        /* functional iteration */
 algorithms_choice.fi_natural=0;
 algorithms_choice.fi_traditional=0;
 algorithms_choice.fi_Ubased=1;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - read X0 callback */
void 
on_main_menu_algorithms_funciter_readX(GtkMenuItem *menuitem, gpointer user_data)
{
if(is_debug==1) printf("on_main_menu_algorithms_funcitter_readX: begin\n");
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for reading new X0 !");
 }
if (is_readX_open==1) {
    gtk_statusbar_push(GTK_STATUSBAR(statusb),0," You where just reading X0 ...");
    return;
    }

is_readX_open=1;
readX_fs = create_fileselection_X();

if(is_debug==1) printf("on_main_menu_algorithms_funcitter_readX: end\n");
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void 
on_main_menu_algorithms_invarsubsp_basic (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 algorithms_choice.type = 4;        /* invariant subspace */
 algorithms_choice.is_base = 1;
 algorithms_choice.is_balzer = 0;
 algorithms_choice.is_schur = 0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void 
on_main_menu_algorithms_invarsubsp_balzer (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 algorithms_choice.type = 4;        /* invariant subspace */
 algorithms_choice.is_base = 0;
 algorithms_choice.is_balzer = 1;
 algorithms_choice.is_schur = 0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Algorithms - just set algorithms_choice structure */
void 
on_main_menu_algorithms_invarsubsp_schur (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 algorithms_choice.type = 4;        /* invariant subspace */
 algorithms_choice.is_base = 0;
 algorithms_choice.is_balzer = 0;
 algorithms_choice.is_schur = 1;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Goals - just set goals_choice structure */
void 
on_main_menu_goals_qbd_g (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 goals_choice.qbd_g=1;
 goals_choice.qbd_gr=0;
 goals_choice.qbd_gru=0;
 goals_choice.qbd_grupi=0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Goals - just set goals_choice structure */
void 
on_main_menu_goals_qbd_gr (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 goals_choice.qbd_g=0;
 goals_choice.qbd_gr=1;
 goals_choice.qbd_gru=0;
 goals_choice.qbd_grupi=0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Goals - just set goals_choice structure */
void 
on_main_menu_goals_qbd_gru (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 goals_choice.qbd_g=0;
 goals_choice.qbd_gr=0;
 goals_choice.qbd_gru=1;
 goals_choice.qbd_grupi=0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Goals - just set goals_choice structure */
void 
on_main_menu_goals_qbd_grupi (GtkMenuItem *menuitem, gpointer  user_data)
{
/* int is_running; global */
clean_statusb();
if(committed.matrix_b_num==0) { /* zero Block means B not present */
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Warning: Load B before computing Pi, or default values will be used !");
 }

if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }

 goals_choice.qbd_g=0;
 goals_choice.qbd_gr=0;
 goals_choice.qbd_gru=0;
 goals_choice.qbd_grupi=1;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Goals - just set goals_choice structure */
void 
on_main_menu_goals_mg1_g (GtkMenuItem *menuitem, gpointer user_data)
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 goals_choice.mg1_g=1;
 goals_choice.mg1_gpi=0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Goals - just set goals_choice structure */
void 
on_main_menu_goals_mg1_gpi  (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 goals_choice.mg1_g=0;
 goals_choice.mg1_gpi=1;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Goals - just set goals_choice structure */
void 
on_main_menu_goals_gim1_r (GtkMenuItem *menuitem, gpointer user_data)
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 goals_choice.gim1_r=1;
 goals_choice.gim1_rpi=0;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Goals - just set goals_choice structure */
void 
on_main_menu_goals_gim1_rpi (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
clean_statusb();
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for new settings to be active, please !");
 }
 goals_choice.gim1_r=0;
 goals_choice.gim1_rpi=1;
 g_idle_add((GtkFunction) selection_uptodaten,NULL);
}
/*********************************/

/*  Main Menu: Goals - set up pi parameters windows */

void 
on_main_menu_goals_pi_param (GtkMenuItem *menuitem, gpointer user_data)
{
if(is_running==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation for Changing Pi Length parameters, please !");
 return; 
 }
if(is_pi_parameters_open==1) {
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"The Window is Open.");
 return;
 }
is_pi_parameters_open=1;
 create_window_pi_parameters();
}
/*********************************/

/* Main Menu: Options toggle */
void 
on_main_menu_options_verbose (GtkMenuItem *menuitem, gpointer user_data )
{
if (is_verbose ==0) {is_verbose =1; gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Next Computation will have a Verbose Printout"); }
else {is_verbose =0; gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Next Computation will have a Terse Printout"); }
}
/*********************************/

/* Main Menu: Options toggle */
void
on_main_menu_options_debug (GtkMenuItem *menuitem, gpointer user_data )
{
if (is_debug ==0) {is_debug =1; gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Debug Output will be printed on the calling shell tty");}
else {is_debug =0; gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Debug Output Disabled");}
}
/*********************************/

/* Main Menu: Options toggle */
void 
on_main_menu_options_timings (GtkMenuItem *menuitem, gpointer user_data)
{
if (is_timings ==0) is_timings =1; else is_timings =0;
}
/*********************************/

/* Main Menu: Options toggle */
void 
on_main_menu_options_situation (GtkMenuItem *menuitem , gpointer user_data )
{
/* GtkWidget *handlebox_s; global */
if (is_situation ==1) { 
  is_situation =0; 
  gtk_widget_hide_all(handlebox_s); 
  }
else {
  is_situation =1;
  gtk_widget_show_all(handlebox_s);
  }
}
/*********************************/

/* Main Menu: menu digits write 8 digits in files */
void 
on_main_menu_options_eigth_d (GtkMenuItem *menuitem , gpointer user_data )
{
strcpy(digits_to_save," %1.7le");
}
/*********************************/

/* Main Menu: menu digits write 15 digits in files */
void 
on_main_menu_options_fifteen_d (GtkMenuItem *menuitem , gpointer user_data )
{
strcpy(digits_to_save," %1.14le"); 
}
/*********************************/

/* Main Menu: menu digits write 16 digits in files (default) */
void 
on_main_menu_options_sixteen_d (GtkMenuItem *menuitem , gpointer user_data )
{
strcpy(digits_to_save," %1.15le"); /* default 16 digits to save in files when writing numbers floating point */
}
/*********************************/

/* Main Menu: menu digits write 17 digits in files */
void 
on_main_menu_options_seventeen_d (GtkMenuItem *menuitem , gpointer user_data )
{
strcpy(digits_to_save," %1.16le"); 
}
/*********************************/


/* update completed structure in case of successfull computation */
void 
update_completed()
{
/* struct goals_str goals_committed; */
/* struct algorithms_str algorithms_committed; globals */
/* struct running_problem_str committed, completed; globals */
completed.type = committed.type;
completed.allocated= committed.allocated;
completed.g=0;
completed.r=0;
completed.u=0;
completed.pi=0;
switch (completed.type) {
	case 1: /* QBD */
                if (goals_committed.qbd_grupi==1) {completed.pi=1;completed.u=1;completed.r=1;}
                if (goals_committed.qbd_gru==1) {completed.u=1;completed.r=1;}
		if (goals_committed.qbd_gr==1) completed.r=1;
		completed.g=1; /* always */
		break;
	case 2: /* M/G/1 */
		if (goals_committed.mg1_gpi==1) completed.pi=1;
		completed.g=1; /* always */ 
		break;
	case 3: /* GI/M/1 */
		if (goals_committed.gim1_rpi==1) completed.pi=1;
		completed.r=1; /* always */
		break;
	default:  /* some error here ... */
        if (is_debug) printf("update_completed: something wrong here ... completed.type = %d\n",completed.type);
       }
completed.dimension_m= committed.dimension_m;
completed.dimension_n= committed.dimension_n;
completed.matrix_a_num= committed.matrix_a_num;
completed.matrix_b_num= committed.matrix_b_num;
completed.is_a_sparse = committed.is_a_sparse;
completed.is_b_sparse = committed.is_b_sparse;
completed.alpha = committed.alpha;
completed.beta = committed.beta;
completed.example= committed.example;
(completed.alg).type= algorithms_committed.type;
(completed.alg).cr_base= algorithms_committed.cr_base;  
(completed.alg).cr_shift= algorithms_committed.cr_shift;
(completed.alg).cr_diag= algorithms_committed.cr_diag;
(completed.alg).lr_base= algorithms_committed.lr_base;
(completed.alg).lr_shift= algorithms_committed.lr_shift;
(completed.alg).lr_gth= algorithms_committed.lr_gth;
(completed.alg).fi_base0= algorithms_committed.fi_base0;
(completed.alg).fi_base1= algorithms_committed.fi_base1;
(completed.alg).fi_base_u=algorithms_committed.fi_base_u;
(completed.alg).fi_shift= algorithms_committed.fi_shift;
(completed.alg).fi_shift_u= algorithms_committed.fi_shift_u;
(completed.alg).fi_natural= algorithms_committed.fi_natural;
(completed.alg).fi_traditional= algorithms_committed.fi_traditional;
(completed.alg).fi_Ubased= algorithms_committed.fi_Ubased;
(completed.alg).is_base= algorithms_committed.is_base;
(completed.alg).is_balzer = algorithms_committed.is_balzer;
(completed.alg).is_schur = algorithms_committed.is_schur;
}
/*********************************/

/* invalidate completed structure in case of some change */
void 
invalidate_completed(void)
{
/* struct running_problem_str  completed; globals */
completed.type =0;
completed.allocated=0;
completed.g=0;
completed.r=0;
completed.u=0;
completed.pi=0;
completed.dimension_m=0;
completed.dimension_n=0;
completed.matrix_a_num=0;
completed.matrix_b_num=0;
completed.is_a_sparse=0;
completed.is_a_sparse=0;
completed.alpha=0;
completed.beta=0;
completed.example=0;
(completed.alg).type=0;
(completed.alg).cr_base=0;  
(completed.alg).cr_shift=0;
(completed.alg).cr_diag=0;
(completed.alg).lr_base=0;
(completed.alg).lr_shift=0;
(completed.alg).lr_gth=0;
(completed.alg).fi_base0=0;
(completed.alg).fi_base1=0;
(completed.alg).fi_shift=0;
(completed.alg).fi_natural=0;
(completed.alg).fi_traditional=0;
(completed.alg).fi_Ubased=0;
(completed.alg).is_base=0;
}
/*********************************/

/* Examples Window: quit button    */
void
on_examples_quit_activate (GtkButton *button, gpointer user_data)
{
if (is_debug==1) printf("examples: quitting \n");
gtk_widget_destroy(gtk_widget_get_toplevel(GTK_WIDGET(button)));
}
/*********************************/

/* Examples Window: destroy event    */
void
on_examples_destroy_activate (GtkWidget  *ww, gpointer data)
{
if (is_debug==1) printf("examples: destroy \n");
is_examples_open =0;
}
/*********************************/


/* Examples Window: OK button      */
/* if a float entry has been modifyed but ENTER has not been typed from keyboard
 * OK button will work as ENTER, but if float value is not valid, a delayed
 * error message will appear for 2 sec, to announce the invalid float data
 * reset to previous valid value */

void
on_examples_ok_activate  (GtkButton *button , gpointer user_data)
{
int status=0; /* no error */
/* int is_examples_to_wait; global */
is_examples_to_wait=0;
if(is_debug==1) printf("on_examples_ok_activate: You did choose  Example %d: type %d, dimension_m=%d dimension_n=%d A blocks=%d, B blocks=%d\n",selected_es, es[selected_es].type, dimension_m, dimension_n, matrix_a_num, matrix_b_num);
if(is_debug==1) printf("on_examples_ok_activate: Now wait for the allocation of the matrices in Fortran Routine ...\n");
/* if present alpha */
if(es[selected_es].is_alpha==1) on_examples_alpha_activate((GtkEntry *)alpha_entry,(gpointer) -1);
/* if present beta */
if(es[selected_es].is_beta==1)  on_examples_beta_activate((GtkEntry *)beta_entry,(gpointer)-1);

set_options_(&is_debug,&is_verbose,&is_timings); /* push these globals to ponte_f_f module */
/*
to write immediately to statusb  we need a different thread for fortran allocation program 
gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"Please wait...allocating matrices...");
*/
invalidate_completed(); /* data is not ready any more for writing results */
examples_setup_(&selected_es, &dimension_m, &dimension_n, &matrix_a_num, &matrix_b_num, &status, &alpha_in, &beta_in);
if (is_debug==1) printf("on_examples_ok_activate: Fortran Allocation Status = %d is_examples_to_wait=%d\n",status,is_examples_to_wait);
if (status == 0) {
           /* gtk_widget_destroy(gtk_widget_get_toplevel(GTK_WIDGET(button)));
           is_examples_open =0; */
           /* committed and initialized example */
           committed.type = es[selected_es].type;
	   selected.type =committed.type; /* selected is used by menus */
	   /* if we did select a non QBD problem and Logarithmic reduction, we need to change Algorithm */
	   if((selected.type!=1)&&(algorithms_choice.type==2)) algorithms_choice.type=1;
           committed.allocated = 1;
           committed.example = selected_es;
           committed.dimension_m =dimension_m;
           committed.dimension_n = dimension_n;
           committed.matrix_a_num = matrix_a_num;
           committed.matrix_b_num = matrix_b_num;
           committed.is_b = es[selected_es].is_b;
           committed.is_b0 = es[selected_es].is_b0;
	   committed.is_bn1 = es[selected_es].is_bn1; 
           committed.alpha = alpha_in;
           committed.beta = beta_in;
	   /* compute if A matrix is sparse or not and write result in committed*/
           check_for_a_sparse();
	   /* remember that the edit a preference has a block number to reset ! */
           pea.block=1;
           peb.block=0;
           gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Problem data has been set up successfully from the selected example.");
           }
else {  /* allocation error in fortran routines */
           gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  *** Memory Allocation for Matrix data did fail !  not enougth memory ?? ***");
        /* invalidate partially initialized strucured */
	committed.allocated = 0;
        committed.example = 0;
	committed.dimension_m =0;
        committed.dimension_n = 0;
        committed.matrix_a_num =0;
        committed.matrix_b_num =0;
	committed.is_b0 = 0;
        committed.is_b = 0;
        committed.is_bn1 =0;
          }
g_idle_add((GtkFunction) selection_uptodaten,NULL);
if (is_debug==1) printf("on_examples_ok_activate: committed .type=%d, .allocated=%d, .example=%d\n",committed.type,committed.allocated,committed.example);
if (is_examples_to_wait==1) g_idle_add((GtkFunction)delayed_examples_close,NULL ); else  {
     is_examples_open=0;
     gtk_widget_destroy(window_examples);
     }
}
/*********************************/

/* Examples Window: reads dimension m from entry */
/* simply throw away any non digit, throw away first 0, and and check range 2-5000 */
void on_dimension_m_entry_changed  (GtkEntry *dimension_entry, gpointer user_data )
{
/* GtkWidget *statusb_examples; global    */
gchar *dimension_in = NULL;
gchar dimension_out[256];
gchar dimension_deducted[256];
gchar  this_char = '\0';
int dimension_int;
int dimension_deducted_int;
int i=0;
int j=0;
int last=0;
gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"");
dimension_in = gtk_editable_get_chars(GTK_EDITABLE(dimension_entry), 0, -1);
this_char = dimension_in[0];
if (!this_char) {
    g_free (dimension_in);
    return ;
    }
while (last==0) {
    if (isdigit(this_char)!=0) {
         dimension_out[i]=this_char;
         i++;
         }
         j++;
         this_char=dimension_in[j];
         if(this_char=='\0') {
               last=1;
               dimension_out[i]=this_char;
               }
   }

dimension_int=atoi(dimension_out);
if (dimension_int <1) {
                     dimension_int=0;
                     gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"  Dimension must be positive !");
                      }
if (dimension_int >50000) {
                    dimension_int=50000;
                    gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"  Max Dimension Allowed: 50 000 !");
                      }
if (dimension_int==0) dimension_out[0]=0;
if ((dimension_int >= 2)&&(dimension_int <= 50000)) sprintf(dimension_out,"%d",dimension_int);
g_free (dimension_in);
gtk_entry_set_text(GTK_ENTRY(dimension_entry), dimension_out);

if (es[selected_es].is_m_equal_n==0) { /* not exactly equal, but a fixed difference */
              dimension_deducted_int = dimension_int - es[selected_es].dimension_diff;
              if (dimension_deducted_int <=0) dimension_deducted_int=dimension_int;
              sprintf(dimension_deducted,"%d",dimension_deducted_int);
              gtk_entry_set_text(GTK_ENTRY(dimension_n_entry), dimension_deducted);
              }
if (es[selected_es].is_a_equal_m==0) {
              gtk_entry_set_text(GTK_ENTRY(howmany_a_entry), dimension_out);
              }

dimension_m=dimension_int;
}
/*********************************/

/* Examples Window: reads dimension n from entry */
/* simply throw away any non digit, throw away first 0, and and check range 2-5000 */
void on_dimension_n_entry_changed  (GtkEntry *dimension_entry, gpointer user_data )
{
/* GtkWidget *statusb_examples; global    */
gchar *dimension_in = NULL;
gchar dimension_out[256];
gchar  this_char = '\0';
int dimension_int;
int i=0;
int j=0;
int last=0;
gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"");
dimension_in = gtk_editable_get_chars(GTK_EDITABLE(dimension_entry), 0, -1);
this_char = dimension_in[0];
if (!this_char) {
    g_free (dimension_in);
    return ;
    }
while (last==0) {
    if (isdigit(this_char)!=0) {
         dimension_out[i]=this_char;
         i++;
         }
         j++;
         this_char=dimension_in[j];
         if(this_char=='\0') {
               last=1;
               dimension_out[i]=this_char;
               }
   }

dimension_int=atoi(dimension_out);
if (dimension_int <1) {
                      dimension_int=0;
                      gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"  Dimension must be positive !");
                      }
if (dimension_int >50000) {
                    dimension_int=50000;
                    gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"  Max Dimension Allowed: 50 000 !");
                      }
if (dimension_int==0) dimension_out[0]=0;
if ((dimension_int >= 2)&&(dimension_int <= 50000)) sprintf(dimension_out,"%d",dimension_int);
g_free (dimension_in);
gtk_entry_set_text(GTK_ENTRY(dimension_entry), dimension_out);
dimension_n=dimension_int;
}
/*********************************/

/* Examples Window: reads # of A blocks qa from entry */
/* simply throw away any non digit, throw away first 0, and and check range 2-5000 */
void on_array_n_entry_changed  (GtkEntry *dimension_entry, gpointer user_data )
{
/* GtkWidget *statusb_examples; global    */
gchar *dimension_in = NULL;
gchar dimension_out[256];
gchar  this_char = '\0';
int dimension_int;
int i=0;
int j=0;
int last=0;
gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"");
dimension_in = gtk_editable_get_chars(GTK_EDITABLE(dimension_entry), 0, -1);
this_char = dimension_in[0];
if (!this_char) {
    g_free (dimension_in);
    return ;
    }
while (last==0) {
    if (isdigit(this_char)!=0) {
         dimension_out[i]=this_char;
         i++;
         }
         j++;
         this_char=dimension_in[j];
         if(this_char=='\0') {
               last=1;
               dimension_out[i]=this_char;
               }
   }

dimension_int=atoi(dimension_out);
if (dimension_int <1) {
                      dimension_int=1;
                     gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"  Number of arrays must be positive !");
                      }
if (dimension_int >1000) {
                    dimension_int=1000;
                    gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"  Max number of arrays: 1000!");
                      }
if (dimension_int==0) dimension_out[0]=0;
if ((dimension_int >= 3)&&(dimension_int <= 1000)) sprintf(dimension_out,"%d",dimension_int);
g_free (dimension_in);
gtk_entry_set_text(GTK_ENTRY(dimension_entry), dimension_out);
matrix_a_num=dimension_int;
}
/*********************************/

/* Examples Window: read # of B blocks qb from entry */
/* simply throw away any non digit, throw away first 0, and and check range 2-5000 */
void on_blocks_n_entry_changed  (GtkEntry *dimension_entry, gpointer user_data )
{
/* GtkWidget *statusb_examples; global    */
gchar *dimension_in = NULL;
gchar dimension_out[256];
gchar  this_char = '\0';
int dimension_int;
int i=0;
int j=0;
int last=0;
gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"");
dimension_in = gtk_editable_get_chars(GTK_EDITABLE(dimension_entry), 0, -1);
this_char = dimension_in[0];
if (!this_char) {
    g_free (dimension_in);
    return ;
    }
while (last==0) {
    if (isdigit(this_char)!=0) {
         dimension_out[i]=this_char;
         i++;
         }
         j++;
         this_char=dimension_in[j];
         if(this_char=='\0') {
               last=1;
               dimension_out[i]=this_char;
               }
   }

dimension_int=atoi(dimension_out);
if (dimension_int <1) {
                      dimension_int=1;
                     gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"  Number of blocks must be positive !");
                      }
if (dimension_int >1000) {
                    dimension_int=1000;
                    gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"  Max number of blocks: 1000!");
                      }
if (dimension_int==0) dimension_out[0]=0;
if ((dimension_int >= 3)&&(dimension_int <= 1000)) sprintf(dimension_out,"%d",dimension_int);
g_free (dimension_in);
gtk_entry_set_text(GTK_ENTRY(dimension_entry), dimension_out);
matrix_b_num=dimension_int;
}
/*********************************/



/* Examples Window: read alpha entry */
/* user_data == -1 if lauched closing the window */
void
on_examples_alpha_activate(GtkEntry *entry, gpointer user_data)
{
gchar *float_in = NULL;
gchar float_out[256];
int  this_char = '\0';
double float_num;
int i=0;
int last=0;
int v; /* retrun value */
int valid;
char num_str[1024];
/* int is_examples_to_wait; global */

if( is_debug==1) printf("on_examples_alpha_activate: user_data=%d\n",(int)user_data);

valid=0; /* non valid */
float_num=-1.0;
for(i=0;i<1024;i++)num_str[i]=0; /* clean input string */
watch_for_number(0, 0,num_str);  /* initialization     */

float_in = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
last=0;
i=0;
while (last==0) {
        this_char=float_in[i];
        if(this_char!=0) {
                        v=watch_for_number(this_char,1,num_str);
                        /*if ((v==7)||(v==8)||(v==9)||(v=10)) {if(1==sscanf(num_str,"%lg",&float_num)) valid=1;}*/
                        i++;
                        } else {
                        v=watch_for_number('\n', 1,num_str);
                        /*if ((v==7)||(v==8)||(v==9)||(v=10)) {if(1==sscanf(num_str,"%lg",&float_num)) valid=1;}*/
                        last=1;
                        };
        }
if ((v==7)||(v==8)||(v==9)||(v=10)) {if(1==sscanf(num_str,"%lg",&float_num)) valid=1;}
if (is_debug==1) printf("on_examples_alpha_activate: valid=%d, float=%g\n",valid,float_num);
if (valid==0) {
                sprintf(float_out,"%.8E",1.0);
                gtk_entry_set_text(GTK_ENTRY(entry), float_out);
                gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"         Alpha Entry not accepted: not a floating number !");
                sprintf(ESBUF,"         Alpha Entry not accepted: not a floating number !");
                is_examples_to_wait=1;
		g_idle_add((GtkFunction) examples_statusb_update,NULL);
		return;
                }
if (alpha_in !=float_num) {
       alpha_in=float_num;
       sprintf(float_out,"%.8E",float_num);
       gtk_entry_set_text(GTK_ENTRY(entry), float_out);
       gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"         Alpha Entry Changed ");
       sprintf(ESBUF,"         Alpha Entry Changed ");
       is_examples_to_wait=1;
       g_idle_add((GtkFunction) examples_statusb_update,NULL);
	}
return;
}
/*********************************/

/* Examples Window: read alpha mantissa with GtkSpinButton 
void
on_examples_alpha_change(GtkEntry *alphaentry, gpointer user_data)
{
gchar *entry_strg=NULL;
entry_strg = gtk_editable_get_chars(GTK_EDITABLE(alphaentry), 0, -1);
printf("on_examples_alpha_change: %s %g\n",entry_strg, gtk_spin_button_get_value (alphaentry));

alpha_in_mant=gtk_spin_button_get_value (GTK_SPIN_BUTTON(alphaentry));
alpha_in= alpha_in_mant*pow(10.0,alpha_in_exp);
if(is_debug) printf("on_examples_alpha_change: alpha_in_mant=%g alpha_in_exp=%g alpha_in=%g \n",alpha_in_mant,alpha_in_exp,alpha_in);
}
*********************************/

/* Examples Window: read alpha exponent with GtkSpinButton 
void
on_examples_alpha_e_change(GtkEntry *alphaeentry, gpointer user_data )
{
*/
/*gchar *entry_strg=NULL;
entry_strg = gtk_editable_get_chars(GTK_EDITABLE(alphaeentry), 0, -1);
printf("on_examples_alpha_e_change: %s   %g\n",entry_strg,gtk_spin_button_get_value (alphaeentry));

alpha_in_exp=gtk_spin_button_get_value (GTK_SPIN_BUTTON(alphaeentry));
alpha_in= alpha_in_mant*pow(10.0,alpha_in_exp);
if(is_debug) printf("on_examples_alpha_e_change: alpha_in_mant=%g alpha_in_exp=%g alpha_in=%g \n",alpha_in_mant,alpha_in_exp,alpha_in);
}
*********************************/


/* Examples Window: read beta entry */
/* user_data == -1 if lauched closing the window */
void
on_examples_beta_activate(GtkEntry *entry, gpointer user_data)
{
gchar *float_in = NULL;
gchar float_out[256];
int  this_char = '\0';
double float_num;
int i=0;
int last=0;
int v; /* retrun value */
int valid;
char num_str[1024];
/* int is_examples_to_wait; global */

if( is_debug==1) printf("on_examples_beta_activate: user_data=%d\n",(int)user_data);

valid=0; /* non valid */
float_num=-1.0;
for(i=0;i<1024;i++)num_str[i]=0; /* clean input string */
watch_for_number(0, 0,num_str);  /* initialization     */

float_in = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
last=0;
i=0;
while (last==0) {
        this_char=float_in[i];
        if(this_char!=0) {
                        v=watch_for_number(this_char,1,num_str);
                        /*if ((v==7)||(v==8)||(v==9)||(v=10)) {if(1==sscanf(num_str,"%lg",&float_num)) valid=1;}*/
                        i++;
                        } else {
                        v=watch_for_number('\n', 1,num_str);
                        /*if ((v==7)||(v==8)||(v==9)||(v=10)) {if(1==sscanf(num_str,"%lg",&float_num)) valid=1;}*/
                        last=1;
                        };
        }
if ((v==7)||(v==8)||(v==9)||(v=10)) {if(1==sscanf(num_str,"%lg",&float_num)) valid=1;}
if (is_debug==1) printf("on_examples_alpha_activate: valid=%d, float=%g\n",valid,float_num);
if (valid==0) {
                sprintf(float_out,"%.8E",beta_in);
                gtk_entry_set_text(GTK_ENTRY(entry), float_out);
		gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"         Beta Entry not accepted: not a floating number !");
                sprintf(ESBUF,"         Beta Entry not accepted: not a floating number !");
                is_examples_to_wait=1;
		g_idle_add((GtkFunction) examples_statusb_update,NULL);
                return;
                }
if (beta_in != float_num) {
    beta_in=float_num;
    sprintf(float_out,"%.8E",float_num);
    gtk_entry_set_text(GTK_ENTRY(entry), float_out);
    gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,"         Beta Entry Changed ");
    sprintf(ESBUF,"         Beta Entry Changed ");
    is_examples_to_wait=1;
    g_idle_add((GtkFunction) examples_statusb_update,NULL);
    }
return;


}
/*********************************/

/* Examples Window: read beta mantissa with GtkSpinButton 
void
on_examples_beta_change(GtkEntry *betaentry, gpointer user_data)
{

beta_in_mant=gtk_spin_button_get_value (GTK_SPIN_BUTTON(betaentry));
beta_in= beta_in_mant*pow(10.0,beta_in_exp);
if(is_debug) printf("on_examples_beta_change: beta_in_mant=%g beta_in_exp=%g beta_in=%g \n",beta_in_mant,beta_in_exp,beta_in);
}
*********************************/

/* Examples Window: read beta exponent with GtkSpinButton 
void
on_examples_beta_e_change(GtkEntry *betaeentry, gpointer user_data)
{
beta_in_exp=gtk_spin_button_get_value (GTK_SPIN_BUTTON(betaeentry));
beta_in= beta_in_mant*pow(10.0,beta_in_exp);
if(is_debug) printf("on_examples_beta_e_change: beta_in_mant=%g beta_in_exp=%g beta_in=%g \n",beta_in_mant,beta_in_exp,beta_in);
}
*********************************/


/* examples statusbar update */
int
examples_statusb_update(void)
{
/* GtkWidget *statusb_examples; global */
gtk_statusbar_push(GTK_STATUSBAR(statusb_examples),0,ESBUF);
return(0);
}
/*********************************/

/* Main Menu: CR  parameters */
/* setup optional paramteres for Cyclic Reduction */
void 
on_main_menu_options_parameters (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
if(is_running==1) {
   gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
   return;
   }
/* parameter options dialog will be modal, no other changes allowed while open */
create_window_parameters(algorithms_choice.type);
}
/*********************************/

/* Main Menu: CR  parameters */
/* setup optional paramteres for Cyclic Reduction */
void
on_main_menu_options_parameters_cr (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
if(is_running==1) {
   gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
   return;
   }
/* parameter options dialog will be modal, no other changes allowed while open */
create_window_parameters(1);
}
/*********************************/

/* Main Menu: LR  parameters */
/* setup optional paramteres for Logaritmic Reduction */
void
on_main_menu_options_parameters_lr (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
if(is_running==1) {
   gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
   return;
   }
/* parameter options dialog will be modal, no other changes allowed while open */
create_window_parameters(2);
}
/*********************************/

/* Main Menu: CR  parameters */
/* setup optional paramteres for Functional Iteration */
void
on_main_menu_options_parameters_fi (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
if(is_running==1) {
   gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
   return;
   }
/* parameter options dialog will be modal, no other changes allowed while open */
create_window_parameters(3);
}
/*********************************/

/* Main Menu: CR  parameters */
/* setup optional paramteres for Invariant Subspace */
void
on_main_menu_options_parameters_is (GtkMenuItem *menuitem, gpointer user_data )
{
/* int is_running; global */
if(is_running==1) {
   gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"Wait till the end of computation, please !");
   return;
   }
/* parameter options dialog will be modal, no other changes allowed while open */
create_window_parameters(4);
}
/*********************************/

/* Parameters Window: quit button    */
void 
on_parameters_quit_activate (GtkButton * button, gpointer user_data)
{
if (is_debug==1) printf("on_parameters_quit_activate: quitting \n");
gtk_widget_destroy(gtk_widget_get_toplevel(GTK_WIDGET(button)));
}
/*********************************/

/* Parameters Window: destroy event    */
void 
on_parameters_destroy_activate (GtkWidget  *ww, gpointer data)
{
/* nothing to do, it a modal window...*/
}
/*********************************/

/* Parameters defaults setup   Pi too  */
void
parameters_setup()
{
/* struct parameters_str max[4],min[4],deflt[4],choice[4]; globals */ 
int i;

sprintf(param_interp_str[0],"256" );
sprintf(param_interp_str[1],"512" );
sprintf(param_interp_str[2],"1024" );
sprintf(param_interp_str[3],"2048" );
sprintf(param_interp_str[4],"4096" );
sprintf(param_interp_str[5],"8192" );
sprintf(param_interp_str[6],"16384" );
sprintf(param_interp_str[7],"32768" );
sprintf(param_interp_str[8],"65536" );

sprintf(param_err_str[0],"1.0D-5");
sprintf(param_err_str[1],"1.0D-6");
sprintf(param_err_str[2],"1.0D-7");
sprintf(param_err_str[3],"1.0D-8");
sprintf(param_err_str[4],"1.0D-9");
sprintf(param_err_str[5],"1.0D-10");
sprintf(param_err_str[6],"1.0D-11");
sprintf(param_err_str[7],"1.0D-12");
sprintf(param_err_str[8],"1.0D-13");
sprintf(param_err_str[9],"1.0D-14");
sprintf(param_err_str[10],"1.0D-15");
sprintf(param_err_str[11],"1.0D-16");

deflt[1].iterat = 50;
deflt[2].iterat = 50;
deflt[3].iterat = 50;
deflt[4].iterat = 50;
deflt[1].interp = 1;
deflt[2].interp = 1;
deflt[3].interp = 1;
deflt[4].interp = 1;
deflt[1].err = 7;
deflt[2].err = 7;
deflt[3].err = 7;
deflt[4].err = 7;

max[1].iterat = 15000;
max[2].iterat = 15000;
max[3].iterat = 15000;
max[4].iterat = 15000;
max[1].interp = 8;
max[2].interp = 8;
max[3].interp = 8;
max[4].interp = 8;
max[1].err = 0;
max[2].err = 0;
max[3].err = 0;
max[4].err = 0;

min[1].iterat = 5;
min[2].iterat = 5;
min[3].iterat = 5;
min[4].iterat = 5;
min[1].interp = 0;
min[2].interp = 0;
min[3].interp = 0;
min[4].interp = 0;
min[1].err = 11;
min[2].err = 11;
min[3].err = 11;
min[4].err = 11;

for (i=1;i<=4;i++) {
     choice[i].iterat=deflt[i].iterat;
     choice[i].interp=deflt[i].interp;
     choice[i].err=deflt[i].err;
     }
/* Pi parameters defaults */
pi_deflt.maxnc=100;
pi_deflt.eps=7;
pi_max.maxnc=5000;
pi_max.eps=0;
pi_min.maxnc=3;
pi_min.eps=11;
pi_choice.maxnc=pi_deflt.maxnc;
pi_choice.eps=pi_deflt.eps;
}
/*********************************/

/* Main Menu:  parameters  reset */
void 
on_main_menu_options_parameters_reset (GtkMenuItem *menuitem, gpointer user_data)
{
/* GtkWidget *statusb; global    */
/* struct parameters_str max[4],min[4],deflt[4],choice[4]; globals */

gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"All Parameters for All Algorithm Reset to Default Values");
int i;
for (i=1;i<5;i++) {
	choice[i].iterat = deflt[i].iterat  ;
        choice[i].interp = deflt[i].interp  ;
        choice[i].err = deflt[i].err  ;
  }
}
/*********************************/

/* Parameters Window: ok button callback */
void 
on_parameters_ok_activate (GtkButton *button, gpointer user_data)
{
/* user_data = algoritm number */
/* check if iteration are in the bound, else change them ! */
/* struct parameters_str max[4],min[4],deflt[4],choice[4]; globals */
/* char param_interp_str[9][256], param_err_str[12][256];  actual strings used in combo */
char buf[64];
if (choice[(int)user_data].iterat <min[(int)user_data].iterat) {
                        choice[(int)user_data].iterat=min[(int)user_data].iterat;
                        sprintf(buf,"%d",choice[(int)user_data].iterat);
                        gtk_entry_set_text (GTK_ENTRY(parameters_entry_itermax),buf);
                        is_parameters=1;  /* signal to delayed close the window in padwrite.c */
			g_idle_add((GtkFunction)delayed_close,NULL );
                        return;
                        }
gtk_widget_destroy(window_parameters);
}
/*********************************/

/* Parameters Window: reset choice to default and redraw values in the window */
void 
on_parameters_reset_activate (GtkButton *button, gpointer user_data)
{
/* user_data = algoritm number */
/* struct parameters_str max[4],min[4],deflt[4],choice[4]; globals */
/* char param_interp_str[9][256], param_err_str[12][256];  actual strings used in combo */
char buf[64];
if(is_debug==1) printf("on_parameters_reset_activate: alg=%d\n",(int)user_data);
choice[(int)user_data].iterat = deflt[(int)user_data].iterat  ;
choice[(int)user_data].interp = deflt[(int)user_data].interp  ;
choice[(int)user_data].err = deflt[(int)user_data].err  ;
sprintf(buf,"%d",choice[(int)user_data].iterat);
gtk_entry_set_text (GTK_ENTRY(parameters_entry_itermax),buf);
gtk_entry_set_text (GTK_ENTRY(parameters_entry_interpmax),param_interp_str[choice[(int)user_data].interp]);
gtk_entry_set_text (GTK_ENTRY(parameters_entry_errmax),param_err_str[choice[(int)user_data].err]);
if(is_debug==1) printf("on_parameters_reset_activate: alg=%d, iterat=%d inpert=%d, err=%d\n",(int)user_data,choice[(int)user_data].iterat,choice[(int)user_data].interp,choice[(int)user_data].err);
}
/*********************************/

/* Parameters Window: itermax entry callback */
void 
on_parameters_entry_itermax_changed (GtkEntry *itermax_entry, gpointer user_data)
{
gchar entry_out_strg[64], *entry_in_strg=NULL;
char this_char;
int last,i,j;
i=0;
j=0;
last=0;
entry_in_strg = gtk_editable_get_chars(GTK_EDITABLE(itermax_entry), 0, -1);
if (entry_in_strg[0] != 0) {
      if(is_debug==1) printf("on_parameters_entry_itermax_changed: alg = %d,  Iter Max =%s\n",(int)user_data,entry_in_strg);
	this_char = entry_in_strg[0];
        if (!this_char) {
        g_free (entry_in_strg); 
        return ; 
        }
        while (last==0) {
            if (isdigit(this_char)!=0) {
             entry_out_strg[i]=this_char;
             i++;
             }
            j++;
            this_char=entry_in_strg[j];
            if(this_char=='\0') {
               last=1;
               entry_out_strg[i]=this_char;
               }
	}
        choice[(int)user_data].iterat = atoi(entry_out_strg);
        if(is_debug==1) printf("on_parameters_entry_itermax_changed: interations=%d\n",choice[(int)user_data].iterat);
/*        if (choice[(int)user_data].iterat <5) {
			choice[(int)user_data].iterat=5;
			}*/
        if (choice[(int)user_data].iterat >max[(int)user_data].iterat) {
                        choice[(int)user_data].iterat=max[(int)user_data].iterat;
                        }
        sprintf(entry_out_strg,"%d",choice[(int)user_data].iterat);
        g_free(entry_in_strg);
        gtk_entry_set_text(GTK_ENTRY(itermax_entry), entry_out_strg);
        }

}
/*********************************/

/* Parameters Window: interpmax entry callback */
void 
on_parameters_entry_interpmax_changed (GtkEntry *interpmax_entry, gpointer user_data)
{
gchar *entry_strg=NULL;
int i;
entry_strg = gtk_editable_get_chars(GTK_EDITABLE(interpmax_entry), 0, -1);
if (entry_strg[0] != 0) {
   if(is_debug==1) printf("on_parameters_entry_errmax_changed:  alg = %d,  Interp.Max =%s\n",(int)user_data,entry_strg);
   i=0;
   while (strcmp(entry_strg,param_interp_str[i])!=0) i++;
   choice[(int)user_data].interp=i;
   if(is_debug==1) printf("on_parameters_entry_interpmax_changed:  choice[%d].interp=%d\n",(int)user_data,i); 
   }
}
/*********************************/

/* Parameters Window: errmax entry callback */
void 
on_parameters_entry_errmax_changed (GtkEntry *errmax_entry, gpointer user_data)
{
gchar *entry_strg=NULL;
int i;
entry_strg = gtk_editable_get_chars(GTK_EDITABLE(errmax_entry), 0, -1);
if (entry_strg[0] != 0) {
   if(is_debug==1) printf("on_parameters_entry_errmax_changed:  alg = %d,  Err Max =%s\n",(int)user_data,entry_strg);
   i=0;
   while (strcmp(entry_strg,param_err_str[i])!=0) i++;
   choice[(int)user_data].err=i;
   if(is_debug==1) printf("on_parameters_entry_errmax_changed:  choice[%d].err=%d\n",(int)user_data,i); 
   }
}
/*********************************/

/* Pi Parameters Window: quit button    */
void
on_pi_parameters_quit_activate (GtkButton * button, gpointer user_data)
{
/* int is_pi_parameters_open; global */
/* int is_debug; global */
if (is_debug==1) printf("on_pi_parameters_quit_activate: quitting \n");
gtk_widget_destroy(gtk_widget_get_toplevel(GTK_WIDGET(button)));
}
/*********************************/

/* Pi Parameters Window: destroy event    */
void on_pi_parameters_destroy_activate (GtkWidget  *ww, gpointer data)
{
is_pi_parameters_open=0;
}
/*********************************/


/* Pi Parameters Window: ok button  */
void
on_pi_parameters_ok_activate (GtkButton *button, gpointer user_data)
{
/* check if iteration are in the bound, else change them ! */
/* struct parameters_str pi_max,pi_min,pi_deflt,pi_choice; globals */
/* char param_interp_str[9][256], param_err_str[12][256];  actual strings used in combo */
char buf[64];
if (pi_choice.maxnc <pi_min.maxnc) {
                        pi_choice.maxnc=pi_min.maxnc;
                        sprintf(buf,"%d",pi_choice.maxnc);
                        gtk_entry_set_text (GTK_ENTRY(parameters_entry_maxnc),buf);
                        is_pi_parameters=1;  /* signal to delayed close the window in padwrite.c */
                        g_idle_add((GtkFunction)pi_delayed_close,NULL );
                        return;
                        }
if (pi_choice.maxnc >pi_max.maxnc) {
                        pi_choice.maxnc=pi_max.maxnc;
                        sprintf(buf,"%d",pi_choice.maxnc);
                        gtk_entry_set_text (GTK_ENTRY(parameters_entry_maxnc),buf);
                        is_pi_parameters=1;  /* signal to delayed close the window in padwrite.c */
                        g_idle_add((GtkFunction)pi_delayed_close,NULL );
                        return;
                        }
/* ok close the window */
is_pi_parameters_open=0;
gtk_widget_destroy(window_pi_parameters);
if(is_debug==1) printf("on_pi_parameters_ok_activate: maxnc=%d eps=%d\n",pi_choice.maxnc, pi_choice.eps);
}
/*********************************/

/* Pi Parameters Window: reset choice to default and redraw values in the window */
void 
on_pi_parameters_reset_activate (GtkButton *button, gpointer user_data)
{
/* struct parameters_str pi_max,pi_min,pi_deflt,pi_choice; globals */
/* char param_interp_str[9][256], param_err_str[12][256];  actual strings used in combo */
char buf[64];
if(is_debug==1) printf("on_pi_parameters_reset_activate: \n");
pi_choice.maxnc=pi_deflt.maxnc;
pi_choice.eps=pi_deflt.eps;
sprintf(buf,"%d",pi_choice.maxnc);
gtk_entry_set_text (GTK_ENTRY(parameters_entry_maxnc),buf);
gtk_entry_set_text (GTK_ENTRY(parameters_entry_epspi),param_err_str[pi_choice.eps]);
if(is_debug==1) printf("on_pi_parameters_reset_activate: maxnc=%d eps=%d  \n",pi_choice.maxnc,pi_choice.eps);
}
/*********************************/

/* Pi Parameters Window: */
void 
on_parameters_entry_epspi_changed(GtkButton *eps_entry, gpointer user_data)
{
gchar *entry_strg=NULL;
int i;
entry_strg = gtk_editable_get_chars(GTK_EDITABLE(eps_entry), 0, -1);
if (entry_strg[0] != 0) {
   if(is_debug==1) printf("on_parameters_entry_epspi_changed:  eps =%s\n",entry_strg);
   i=0;
   while (strcmp(entry_strg,param_err_str[i])!=0) i++;
   pi_choice.eps=i;
   if(is_debug==1) printf("on_parameters_entry_epspi_changed:  pi_choice.eps=%d\n",i);
   }

}
/*********************************/

/* Pi Parameters Window: */
void 
on_parameters_entry_maxnc_changed(GtkButton *maxnc_entry, gpointer user_data)
{
gchar entry_out_strg[64], *entry_in_strg=NULL;
char this_char;
int last,i,j;
i=0;
j=0;
last=0;
entry_in_strg = gtk_editable_get_chars(GTK_EDITABLE(maxnc_entry), 0, -1);
if (entry_in_strg[0] != 0) {
      if(is_debug==1) printf("on_parameters_entry_maxnc_changed: maxnc =%s\n",entry_in_strg);
        this_char = entry_in_strg[0];
        if (!this_char) {
        g_free (entry_in_strg);
        return ;
        }
        while (last==0) {
            if (isdigit(this_char)!=0) {
             entry_out_strg[i]=this_char;
             i++;
             }
            j++;
            this_char=entry_in_strg[j];
            if(this_char=='\0') {
               last=1;
               entry_out_strg[i]=this_char;
               }
        }
        pi_choice.maxnc = atoi(entry_out_strg);
        if(is_debug==1) printf("on_parameters_entry_maxnc_changed: maxnc=%d\n",pi_choice.maxnc);
        if (pi_choice.maxnc >pi_max.maxnc) {
                        pi_choice.maxnc=pi_max.maxnc;
                        }
        sprintf(entry_out_strg,"%d",pi_choice.maxnc);
        g_free(entry_in_strg);
        gtk_entry_set_text(GTK_ENTRY(maxnc_entry), entry_out_strg);
        }

}
/*********************************/

/* check if A is sparse i.e. 70% terms or more are exactly 0 */
/* put committed.is_a_sparse= 1 if sparse 0 otherwise */
void
check_for_a_sparse()
{
int i,j,k,totzero,totnonzero;
double r,levelzero,levelnonzero;
if (committed.allocated == 1) { /* just to be sure there is a A ... */
totzero=0;
totnonzero=0;
levelzero=0.7*committed.dimension_m*committed.dimension_m*committed.matrix_a_num;
levelnonzero=0.3*committed.dimension_m*committed.dimension_m*committed.matrix_a_num;
for(i=1;i<=committed.dimension_m;i++) {
  for(j=1;j<committed.dimension_m;j++)
	for(k=1;k<=committed.matrix_a_num;k++) {
	read_mata_(&j,&i,&k,&r);
	if(r==0.0E0) totzero++;else totnonzero++;
	}
  if (totzero > levelzero) {committed.is_a_sparse=1; return;}
  if (totnonzero > levelnonzero) {committed.is_a_sparse=0; return;}
  }
if (totzero >= levelzero) {committed.is_a_sparse=1; return;}
if (totnonzero > levelnonzero) {committed.is_a_sparse=0; return;}
return;
 }
}
/*********************************/

/* we try to run the stop thread command
 * in the idle time
 * maybe race condition will not occour ?
 */
gint stop_computations(void)
{
char riga[80];
struct timespec small_wait;
small_wait.tv_sec=0;
small_wait.tv_nsec=200000000; /* 200000000 nano sec = 200msec */
if(is_debug==1) printf("stop_computations: sending thread cancellation to: %ld\n",(unsigned long)my_thread_computation);
pthread_cancel(my_thread_computation);
if(is_debug==1) printf("stop_computations: sent thread cancellation to: %ld\n",(unsigned long)my_thread_computation);
/* wait a little ... */
 nanosleep(&small_wait,NULL);
 sprintf(riga,"\n* * * * Computation Interrupted * * * *\n");
 append_fifo_(riga);
 gtk_statusbar_push(GTK_STATUSBAR(statusb),0,"  Computation Interrupted");
 is_running=0;
 if(need_a_transpose==1) {need_a_transpose=0; transpose_mata_();} /* some fortran routines did transpose of A: put it back */
 /* now results are invalid */
 invalidate_completed();
 /* update situation bar if some change has been made during calculation */
 g_idle_add((GtkFunction) selection_uptodaten,NULL);

return(0); /* one shot */
}

/*********************************/

/* generic delete_event response **** Callback *** used in debugging only  */
gboolean
on_delete_event_do   (GtkWidget  *ww, GdkEvent *event, gpointer data)
{
if(is_debug==1) printf("on_on_delete_event_do:  user data=%ld\n",(long int)data);
/* the default is FALSE; answering TRUE stops the default behaviour */
return(FALSE);
}
/*********************************/


