#!/usr/bin/perl -w

#################################################################################
#                                                                              	#
#  Copyright (C) 2002-2003 Wim Vanderbauwhede. All rights reserved.             #
#  This program is free software; you can redistribute it and/or modify it      #
#  under the same terms as Perl itself.                                         #
#                                                                              	#
#################################################################################

use strict;
use Cwd;
use Gtk;
use lib '.';
use Gnome::StockIcons;
set_locale Gtk;
init Gtk;

my $false = 0;
my $true = 1;

my $xe=1;
if(@ARGV&&$ARGV[0] eq '-nox'){
 $xe=0;
}
print STDERR "Starting UI ...";

my $normal='-adobe-helvetica-medium-r-normal-*-12-*-*-*-*-*-iso8859-1';
my $bold='-adobe-helvetica-bold-r-normal-*-12-*-*-*-*-*-iso8859-1';
my $console='-misc-fixed-bold-r-normal-*-*-140-*-*-c-*-iso8859-1';

# Load a fixed font 
my $name = "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-koi8-r"; 
my $fixed_font = Gtk::Gdk::Font->load( $name );

my @matrix;
#-------------------------------------------------------------------
my $pwd=cwd();
open(CFG,"<$pwd/.synsim");
my %cfg=();
while(<CFG>){
chomp;
my ($key,$value)=split(/\s+/,$_);
 $cfg{$key}=$value;
}
close CFG;
my $xemacs=0;
my $debug=0;
my $update=0;
my $overwrite=0;
my $showtb=0;
my $showdefault=0;
my $text;
my $nlines=20;
my $nowarn=0;
my $plot=1;
my $verbose=1;
my $warn=0;
my $background=0;
my $run=0;
my $done=0;
my $inspectcode=0;
my $pid='WRONG';
my $xpid='WRONG';
my $selectedfile='NONE';
my $consoletext;
my $id;

my $charcount=1;
my $prevchar='';
my $changed=0;
my $pause=1;

&create_ui();
#&launch_xemacs($xe);

=for_named_pipe
use Fcntl;
my $path='tmp';
if(-e $path){unlink $path}
require POSIX;
POSIX::mkfifo($path,0666) or die $!;
=cut

print STDERR "\nDone \n";
=for_socket
print STDERR "\nCreating socket ... \n";
use IO::Socket;
my $new_sock;
my $buff;
my $i=0;
my $ok=1;
my $sock = new IO::Socket::INET (LocalHost => 'localhost',
				 LocalPort => 2507,
				 Proto => 'tcp',
				 Listen => 5,
				 ReuseAddr => 1,
				 );
die "Could not connect: $!" unless $sock;
print STDERR "Done \n";
=cut


#my $idle = Gtk->idle_add( \&listen );
#my $interval=1000;
#my $timer = Gtk->timeout_add( $interval, \&display );
main Gtk;

exit( 0 );


#-------------------------------------------------------------------
sub create_ui {
my $window;
my $menu;
my $menubar;
my $root_menu;
my $menu_item;
my $vbox;

 $window =  new Gtk::Window( 'toplevel' );

my $width=600;
my $heigth=500;

$window->set_usize( $width, $heigth );
$window->set_default_size( $width, $heigth );

$window->set_title(  'SynSim' );
$window->signal_connect( 'delete_event', \&clean_exit );
#$window->show();

# This VBox contains the whole GUI
# all sub-elements are put in HBoxes
my $main_vbox = new Gtk::VBox( $false, 0 );
$window->add( $main_vbox );
$main_vbox->show();
my $entry_datafile = new Gtk::Entry();
#==============================================================================
    # MENU STUFF

    # Menu bar
$menu = new Gtk::Menu();

# Create a new menu-item with a name...
$menu_item = new Gtk::MenuItem( 'Open' );
# and add it to the menu.
$menu->append( $menu_item );
# Do something interesting when the menuitem is selected
$menu_item->signal_connect( 'activate', \&file_open,$menu_item,$entry_datafile );
# Show the widget
$menu_item->show();

# Create a new menu-item with a name...
$menu_item = new Gtk::MenuItem( 'XEmacs' );
# and add it to the menu.
$menu->append( $menu_item );
# Do something interesting when the menuitem is selected
$menu_item->signal_connect( 'activate', sub {$xemacs=1;system("xemacs blank &")  } );
# Show the widget
$menu_item->show();

my $submenu_new = new Gtk::Menu();
my $menu_item_new = new Gtk::MenuItem( 'Datafile' );
$submenu_new->append( $menu_item_new );
$menu_item_new->signal_connect('activate',sub {});
$menu_item_new->show();

$menu_item_new = new Gtk::MenuItem( 'Project' );
$submenu_new->append( $menu_item_new );
$menu_item_new->signal_connect('activate',sub {});
$menu_item_new->show();

$menu_item = new Gtk::MenuItem('New');
$menu->append( $menu_item );
$menu_item->set_submenu( $submenu_new);
$menu_item->show();

$menu_item = new Gtk::MenuItem( 'Exit' );
$menu->append( $menu_item );
$menu_item->signal_connect('activate',\&clean_exit);

$menu_item->show();

# This is the root menu, and will be the label displayed on the menu bar.
# There won't be a signal handler attached, as it only pops up the rest
# of the menu when pressed.
$root_menu = new Gtk::MenuItem( "File" );
$root_menu->show();

# Now we specify that we want our newly created "menu" to be the menu
# for the "root menu"
$root_menu->set_submenu( $menu );

# Create a menu-bar to hold the menus and add it to our main window
$menubar = new Gtk::MenuBar();
$menubar->show();
# And finally we append the menu-item to the menu-bar -- this is the
# "root" menu-item I have been raving about =)
$menubar->append( $root_menu );
#------------------------------------------------------------------------------
# A hbox for menu and logo
my $hbox = new Gtk::HBox( $false, 0 ); # $true would center the button
$hbox->show();
# Create a menu-bar to hold the menus and add it to our main window
$hbox->pack_start( $menubar, $true, $true, 2 );

$main_vbox->pack_start( $hbox, $false, $false, 2 );


# always display the window as the last step so it all splashes on
# the screen at once.
$window->show();
# Logo
my $style = $window->get_style()->bg( 'normal' );



my @perl_logo_xpm = (
'88 31 17 1',
' 	c None',
'.	c #000000',
'+	c #FFFFFF',
'@	c #606997',
'#	c #33638C',
'$	c #90A1AC',
'%	c #6E7376',
'&	c #166A9B',
'*	c #006699',
'=	c #065E8A',
'-	c #418CB2',
';	c #C3CFD5',
'>	c #004261',
',	c #01567F',
"'	c #89D9FF",
')	c #022230',
'!	c #3E4547',
'>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>',
">+'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''',)",
'>,=========================================================================###=======,>)',
'>,=*************************************************************&@#******&@;++$&*****,>)',
'>,=*-;;;-**$+;--;-*;$*$;-;;;$*;;;$*-;;;--;;;-*****;;;$*;;*$;&*#@$+;@****#;+++++$*****,>)',
'>,=*-+%;+>;+$+;,+%-+;>+$%+%!!>+$;+#;+!!!$+%;;,***&+$;+#$+%+$)@;++++;&***;++++++;&****,>)',
'>,=*$+.;;!+%.$+)+%;+;%+)$+.>>-+!$+.;;.>>;;.$+)***-+!;;.#++;.>$;+++++@**@++++++++%****,>)',
'>,=*;+++%%+.>;;.;;+$+;$.;+++&$+++#.+++;*+$)$+.***$+++%)*++))*&#;++++!&$+++++++++;&***,>)',
'>,=*+;!..$+.=+$.;+$!++)>+;...;+%+!#+%..!+%)+;.***;+.;;>*;;.,**#;+++;!$+++++++++++$***,>)',
'>,=&+%)>=$+%;+))$+)>+$.&+$!-*;;!+%-+%#--+%$+!)***;;!+$)*+$)***$++++;%++++++++++++;#**,>)',
'>,=-+!>**&;+;%.,-$.,+))-+++;>+%)+%$+++$$++;#.,***+++;))-+%)***$++++%%+++++++++++++%**,>)',
'>,=*>.>***=)..>**>)**.,*>...)*.>*.>>...)>..),*****...)=*,.>***$++++;;+++++++++++++;#*,>)',
'>,=***********************************************************@++++++++++++++++++++;&,>)',
'>,=**********-----&****-------**-----&****---*****************#;++++++++++++++++++;+@,>)',
'>,=**********;+++++;&**+++++++>*;+++++;-**++;,*****************@+++++++++++++++++;!;%,>)',
'>,=**********;++;;++;=*+++;;;;.*;++;;++;,*++;)******************%++++++++++++++;+;!;%,>)',
'>,=**********;++.);++!*++;.))))*;++.)$++!*++;)*******************!;;$+++++++++$!+;!;%,>)',
'>,=**********;++.*$++!,++;)*****;++.*$++!,++;)********************..!++!%++%$+%);;%$),>)',
'>,=**********;++.&;++.>++;!---**;++!-++;.>++;)*********************)%++!%++!%+!>$+%#),>)',
'>,=**********;++++++$.=++++++;,*;+++++;!.*++;)**********************@+;);+;.$+!*#;%=,,>)',
'>,=**********;++++;%.)*+++;;;$)*;++;++;.,*++;)**********************#+%.++%.$+%*&$%=*,>)',
'>,=**********;++....>**++;.))))*;++.$++!**++;)**********************#+%)+;.)$;)*&;;&*,>)',
'>,=**********;++.******++;)*****;++.-++$,*++;)**********************#+%*@;!&;%.*&;$=*,>)',
'>,=**********;++.******++;)*****;++.*++;)*++;)**********************@+!**%;;$>)*&$!>*,>)',
'>,=**********;++.******+++++++-*;++.*;++!*+++++++-******************@$.=*=%+$)**&$!,*,>)',
'>,=**********;++.******+++++++!>;++.*-++$,+++++++!>*****************@$.**@;++%**#;!**,>)',
'>,=***********)..*******.......>*)..**>..)*.......>****************&;$>**$$%%!**@+$&*,>)',
'>,=***************************************************************@;+%>**&*)..**@;%**,>)',
'>,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,#%@)>,,,>>,,,,,#.>,,>)',
'>,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>).>>>>>>>>>>>>)>>>>)',
'>)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))');



#my ( $pixmap, $mask ) = Gtk::Gdk::Pixmap->create_from_xpm_d( $window->window,
#                                                        $style,
#                                                        @perl_logo_xpm );
#my $pixmapwid = new Gtk::Pixmap( $pixmap, $mask );
#$pixmapwid->show();
#$hbox->pack_end( $pixmapwid, $false, $false, 2 );
##==============================================================================

## A hbox for icons
#my $hbox_icons = new Gtk::HBox( $false, 0 ); # $true would center the button
#$hbox_icons->show();

## Add icons
#($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($window->window,$style,@stock_open);
#$pixmapwid = new Gtk::Pixmap( $pixmap, $mask );
#$pixmapwid->show();
#$hbox_icons->pack_start( $pixmapwid, $true, $false, 5 );

#($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($window->window,$style,@stock_new);
#$pixmapwid = new Gtk::Pixmap( $pixmap, $mask );
#$pixmapwid->show();
#$hbox_icons->pack_start( $pixmapwid, $true, $false, 5 );

#($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($window->window,$style,@stock_save);
#$pixmapwid = new Gtk::Pixmap( $pixmap, $mask );
#$pixmapwid->show();
#$hbox_icons->pack_start( $pixmapwid, $true, $false, 5 );

#($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($window->window,$style,@stock_save_as);
#$pixmapwid = new Gtk::Pixmap( $pixmap, $mask );
#$pixmapwid->show();
#$hbox_icons->pack_start( $pixmapwid, $true, $true, 5 );

#($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($window->window,$style,@stock_exit);
#$pixmapwid = new Gtk::Pixmap( $pixmap, $mask );
#$pixmapwid->show();
#$hbox_icons->pack_start( $pixmapwid, $true, $true, 2 );

#$main_vbox->pack_start( $hbox_icons, $false, $false, 2 );


#
#==============================================================================
# TABLE for entry, label, button and checkboxes

#put in a hbox
my $hbox_table = new Gtk::HBox( $false, 0 );
$hbox_table->show();
#$main_vbox->pack_start( $hbox_table, $true, $true, 2 );
$main_vbox->pack_start( $hbox_table, $false, $true, 2 );
my $main_table = new Gtk::Table( 2, 5, $false );

$main_table->set_row_spacing( 0, 2 );
$main_table->set_col_spacing( 0, 2 );

$main_table->show();
$hbox_table->pack_start($main_table, $false, $false, 2 );
#------------------------------------------------------------------------------
my $label_project = new Gtk::Label( 'Project:' );
$main_table->attach( $label_project, 0,1,0, 1,['expand'],[],4,0);
$label_project->show();

my $combo_project = new Gtk::Combo();
$combo_project->entry->set_text( $cfg{project} );
my @strings=@{&get_projects()};
$combo_project->set_popdown_strings( @strings );
 $combo_project->entry->signal_connect( "changed", sub {$cfg{project}=$combo_project->entry->get_text();});

#to append:
#$combo->list = ( $combo->list, "append1", "append2", ... );

$combo_project->set_use_arrows( 1 ); 
$main_table->attach( $combo_project, 1,2,0, 1,['expand'],[],24,0);
$combo_project->show();

my $label_datafile = new Gtk::Label( 'Datafile:' );
$main_table->attach( $label_datafile, 2,3,0, 1,['expand'],[],0,0);
$label_datafile->show();

# create a single line text entry

#$entry_datafile->signal_connect( "key_press_event", \&autocomplete_callback, $entry_datafile );
$entry_datafile->signal_connect( "changed", \&autocomplete_callback, $entry_datafile );
$entry_datafile->signal_connect( "activate", \&enter_callback, $entry_datafile );
# set the content
$entry_datafile->set_text($cfg{datafile});
$main_table->attach( $entry_datafile, 3,4,0, 1,['expand'],[],0,0);
$entry_datafile->show();

my $button_datafile= new Gtk::Button( 'Open' );
$button_datafile->signal_connect( "clicked", \&open_callback, $entry_datafile );
$main_table->attach( $button_datafile, 4,5,0, 1,['expand'],[],0,0);
$button_datafile->show();

#==============================================================================
# Create the checkboxes 
# put in an hbox
my $vbox_check = new Gtk::VBox( $false, 0 );
$vbox_check->show();
#$main_vbox->pack_start( $hbox_check, $true, $true, 2 );

my $check_plot = new Gtk::CheckButton( "Plot" ); 
#$hbox->pack_start( $check_plot, $true, $true, 0 ); 
$check_plot->set_active( $plot ); 
$check_plot->signal_connect( "toggled", sub { $plot=1-$plot; } ); 

#$main_table->attach( $check_plot, 0,1,1, 2,['expand'],[],0,0);
 $vbox_check->pack_start($check_plot, $true, $true, 0 );
$check_plot->show();

my $check_verbose = new Gtk::CheckButton( "Verbose" ); 
$check_verbose->set_active( $verbose ); 
$check_verbose->signal_connect( "toggled", sub { $verbose=1-$verbose; } ); 

#$main_table->attach( $check_verbose, 1,2,1, 2,['expand'],[],0,0);
 $vbox_check->pack_start($check_verbose, $true, $true, 0 );
$check_verbose->show();

my $check_warn = new Gtk::CheckButton( "Warnings" ); 
$check_warn->set_active( $warn ); 
$check_warn->signal_connect( "toggled", sub { $warn=1-$warn; } ); 

#$main_table->attach( $check_warn, 2,3,1, 2,['expand'],[],0,0);
 $vbox_check->pack_start($check_warn, $true, $true, 0 );
$check_warn->show();

my $check_background = new Gtk::CheckButton( "Background" ); 
$check_background->set_active( $background ); 
$check_background->signal_connect( "toggled", sub { $background=1-$background; } ); 

#$main_table->attach( $check_background, 3,4,1, 2,['expand'],[],0,0);
 $vbox_check->pack_start($check_background, $true, $true, 0 );
$check_background->show();

$main_table->attach( $vbox_check, 0,1,1, 2,['expand'],[],0,0);

my $button_run= new Gtk::Button( 'Run' );
$button_run->signal_connect( "clicked", \&run_callback, $button_run );
$button_run->show();

# put in an vbox
my $vbox_run = new Gtk::VBox( $false, 0 );
$vbox_run->show();
 $vbox_run->pack_start($button_run, $false, $true, 0 );

my $button_stop= new Gtk::Button( 'Stop' );
$button_stop->signal_connect( "clicked", \&stop_callback, $button_stop );
$button_stop->show();

# put in an vbox
#my $vbox_stop = new Gtk::VBox( $false, 0 );
#$vbox_stop->show();
 $vbox_run->pack_start($button_stop, $false, $true, 2 );

$main_table->attach( $vbox_run, 1,2,1, 2,['expand'],['fill'],0,4);

#==============================================================================
#
# Icons for SynSim-specific commands
#


# XPM */
my @tcd_ff = (
"19 15 5 1",
" 	c None",
".	c #949594",
"+	c #FFFFFF",
"\@	c #000000",
"#	c #8E8E8E",
"..        ..       ",
"+\@.       +\@.      ",
"+#\@.      +#\@.     ",
"+#\@\@.     +#\@\@.    ",
"+#\@\@\@.    +#\@\@\@.   ",
"+#\@\@\@\@.   +#\@\@\@\@.  ",
"+#\@\@\@\@\@.  +#\@\@\@\@\@. ",
"+#\@\@\@\@\@\@. +#\@\@\@\@\@\@.",
"+#\@\@\@\@\@.  +#\@\@\@\@\@. ",
"+#\@\@\@\@.   +#\@\@\@\@.  ",
"+#\@\@\@.    +#\@\@\@.   ",
"+#\@\@.     +#\@\@.    ",
"+#\@.      +#\@.     ",
"+\@.       +\@.      ",
);

# XPM */
my @tcd_pause = (
"13 15 5 1",
" 	c None",
".	c #949594",
"+	c #000000",
"\@	c #8E8E8E",
"#	c #FFFFFF",
"...... ......",
".+++\@# .+++\@#",
".+++\@# .+++\@#",
".+++\@# .+++\@#",
".+++\@# .+++\@#",
".+++\@# .+++\@#",
".+++\@# .+++\@#",
".+++\@# .+++\@#",
".+++\@# .+++\@#",
".+++\@# .+++\@#",
".+++\@# .+++\@#",
".+++\@# .+++\@#",
".+++\@# .+++\@#",
".+\@\@\@# .+\@\@\@#",
);

# XPM */
my @tcd_play = (
"13 15 5 1",
" 	c None",
".	c #949594",
"+	c #000000",
"\@	c #8E8E8E",
"#	c #FFFFFF",
"......       ",
".+++++.      ",
".++++++.     ",
".+++++++.    ",
".++++++++.   ",
".+++++++++.  ",
".++++++++++. ",
".++++++++++\@#",
".+++++++++\@# ",
".++++++++\@#  ",
".+++++++\@#   ",
".++++++\@#    ",
".+++++\@#     ",
".+\@\@\@\@#      ",
);

# XPM */
my @tcd_stop = (
"13 15 5 1",
" 	c None",
".	c #949594",
"+	c #000000",
"\@	c #8E8E8E",
"#	c #FFFFFF",
".............",
".++++++++++\@#",
".++++++++++\@#",
".++++++++++\@#",
".++++++++++\@#",
".++++++++++\@#",
".++++++++++\@#",
".++++++++++\@#",
".++++++++++\@#",
".++++++++++\@#",
".++++++++++\@#",
".++++++++++\@#",
".++++++++++\@#",
".+\@\@\@\@\@\@\@\@\@\@#",
);


## put in an vbox
#my $vbox_controls = new Gtk::VBox( $false, 0 );
#$vbox_controls->show();
#($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($window->window,$style,@tcd_play);
#$pixmapwid = new Gtk::Pixmap( $pixmap, $mask );
#$pixmapwid->show();
#$vbox_controls->pack_start($pixmapwid, $false, $true, 4 );

#($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($window->window,$style,@tcd_stop);
#$pixmapwid = new Gtk::Pixmap( $pixmap, $mask );
#$pixmapwid->show();
#$vbox_controls->pack_start($pixmapwid, $false, $true,4 );

#($pixmap,$mask)=Gtk::Gdk::Pixmap->create_from_xpm_d($window->window,$style,@tcd_pause);
#$pixmapwid = new Gtk::Pixmap( $pixmap, $mask );
#$pixmapwid->show();
#$vbox_controls->pack_start($pixmapwid, $false, $true, 4 );

#$main_table->attach( $vbox_controls, 3,4,1,2,['expand'],['fill'],0,4);
#==============================================================================
#TABLE for logview

# put in an hbox
my $hbox_log = new Gtk::HBox( $false, 0 );
$hbox_log->show();
$main_vbox->pack_start( $hbox_log, $true, $true, 2 );
my $console_table = new Gtk::Table( 2, 2, $false );
$console_table->set_row_spacing( 0, 2 );
$console_table->set_col_spacing( 0, 2 );
#$main_vbox->pack_start( $console_table, $true, $true, 0 );

$console_table->show();
$hbox_log->pack_start($console_table, $true, $true, 2 );
# Create the GtkText widget
$consoletext = new Gtk::Text( undef, undef );
$consoletext->set_editable( $false );
$console_table->attach( $consoletext, 0, 1, 0, 1,
		[ 'expand', 'shrink', 'fill' ],
		[ 'expand', 'shrink', 'fill' ],
		0, 0 );
$consoletext->show();

# Add a vertical scrollbar to the GtkText widget
my $vscrollbar = new Gtk::VScrollbar( $consoletext->vadj );
$console_table->attach( $vscrollbar, 1, 2, 0, 1, 'fill',
		[ 'expand', 'shrink', 'fill' ], 0, 0 );
$vscrollbar->show();



  } #end of create_ui
#-------------------------------------------------------------------
sub launch_xemacs {
my $xe=shift;
my $file=shift||'blank';
if($xe) {
$xpid=open(XEM,"| xemacs $file");
}
}
#-------------------------------------------------------------------
sub show_obj {
my $pattern= $matrix[2][2]->get();
system("./GUI/debug.pl -s $pattern 2>&1 | ./GUI/send_stdout.pl &");
&listen();
#system("./GUI/debug.pl -s $pattern > tmp &");
#&write_output();
}
#------------------------------------------------------------------------------
sub file_open {
# Create a new file selection widget 

my $widget=shift;
my $menu_item=shift;
my $entry_datafile=shift;
chdir "$pwd/$cfg{project}";
my $file_dialog = new Gtk::FileSelection( "File Selection" );
 $file_dialog->hide_fileop_buttons();
$file_dialog->signal_connect( "destroy", sub { $file_dialog->destroy() } ); 

# Connect the ok_button to file_ok_sel function 
$file_dialog->ok_button->signal_connect( "clicked", \&file_ok_sel, $file_dialog,$entry_datafile ); 

# Connect the cancel_button to destroy the widget 
$file_dialog->cancel_button->signal_connect( "clicked", sub { $file_dialog->destroy(); } ); 

# Lets set the filename, as if this were a save dialog, and we are giving 
# a default filename 
#$file_dialog->set_filename( $cfg{datafile} ); 
$file_dialog->show();
chdir $pwd;

}
#------------------------------------------------------------------------------
sub file_ok_sel { 
my ( $widget, $file_selection ,$entry_datafile) = @_; 
my $file = $file_selection->get_filename(); 
print( "$file\n" );
 $file_selection->destroy();
my $datafile=$file;
$datafile=~s/.*\///;
 $cfg{datafile}=$datafile;
$entry_datafile->set_text($cfg{datafile});

chdir "$pwd/$cfg{project}";

my @a=`gnuclient -q  $datafile 2>&1`;
if(@a){&launch_xemacs(1,$datafile)}

chdir $pwd;
}
#------------------------------------------------------------------------------
sub enter_callback { 
my ( $widget, $entry ) = @_; 
my $datafile = $entry->get_text(); 
#print( "Entry contents: $datafile\n" ); 
 $cfg{datafile}=$datafile;
chdir "$pwd/$cfg{project}";
my @a=`gnuclient -q  $datafile 2>&1`;
if(@a){&launch_xemacs(1,$datafile)}
#system("gnuclient -q $datafile &");
chdir $pwd;
}
#------------------------------------------------------------------------------
sub open_callback { 

my ( $widget, $entry) = @_; 
my $datafile = $entry->get_text(); 
if(not $datafile){
&file_open('','',$entry);
} else {
#print( "Entry contents: $datafile\n" ); 
 $cfg{datafile}=$datafile;
chdir "$pwd/$cfg{project}";
my @a=`gnuclient -q  $datafile 2>&1`;
if(@a){&launch_xemacs(1,$datafile)}
#system("gnuclient -q $datafile &");
chdir $pwd;
}
}
#------------------------------------------------------------------------------
sub autocomplete_callback { 
  my ( $widget, $entry ,$event) = @_; 
  $changed=1-$changed;
  if($changed){
    my $entry_text = $entry->get_text();
    my $guessed='';
    if($entry_text ne substr($prevchar,0,length($prevchar)-1)) {
      $guessed=&look_ahead($entry_text);
    }
    if(!$guessed){$guessed=$entry_text};
    $entry->set_text($guessed);
    $prevchar= $entry_text;
  }
}
#------------------------------------------------------------------------------
sub run_callback {
chdir "$pwd/$cfg{project}";

my $v=($verbose)?'-v':'';
$v=($background)?'':$v;
my $p=($plot)?'-p':'';
my $i=($background or not $plot)?'':'-i';
my $w=($warn)?'-w':'';
$done=0;

$pid=open(LOG,"./synsim $w $v $i $p -f $cfg{datafile} 2>&1 & |");
$consoletext->insert( $console, undef, undef, "\nPGRP:$$\nPID:$pid\n" );
my $source = fileno LOG;
$id = Gtk::Gdk->input_add( $source, 'read', \&display );
$run=1;
chdir $pwd;
}
#------------------------------------------------------------------------------
sub display {
#print "$run\n";
  if($run==1) {
my $line='';
my $fh=*LOG;
sysread($fh,$line,1024);
$consoletext->insert( $console, undef, undef, $line );
if ($line=~/Finished/){close $fh; Gtk::Gdk->input_remove($id);}
}
return 1;
}
#------------------------------------------------------------------------------
sub stop_callback {
#kill synsim
#my @pid=`ps -x | grep $cfg{datafile} | grep -v grep`;
#$pid=shift @pid;
#$consoletext->insert( $console, undef, undef, "\n$pid\n" );
#chomp $pid;
#$pid=~s/^\w+\s+(\d+)/$1/;
#$pid=~s/\s+.*//;
$consoletext->insert( $console, undef, undef, "\nPID:$pid\n" );
kill 'TERM',"$pid";
my $gpid=-1-$pid;
kill 'TERM',"$gpid";
#system("kill $pid");

$consoletext->insert( $console, undef, undef, "\nSynSim run halted\n" );
Gtk::Gdk->input_remove( $id );
}
#------------------------------------------------------------------------------
sub pause_callback {
#halt synsim
# this is not correct, because it does not halt child processes
# but it'll do for now
my @pid=`ps -x | grep $cfg{datafile} | grep -v grep`;
$pid=shift @pid;
$consoletext->insert( $console, undef, undef, "\n$pid\n" );
chomp $pid;
$pid=~s/^\w+\s+(\d+)/$1/;
$pid=~s/\s+.*//;
$consoletext->insert( $console, undef, undef, "\nPID:$pid\n" );
if($pause) {
system("kill 'STOP',$pid");
$pause=0;
} else {
system("kill 'CONT',$pid");
$pause=1;
}

$consoletext->insert( $console, undef, undef, "\nSynSim run halted\n" );
Gtk::Gdk->input_remove( $id );
}
#------------------------------------------------------------------------------
sub look_ahead {
my $current=shift;
if($current) {
#more portable, but not sorted by time
chdir "$pwd/$cfg{project}";
#print cwd(),"\n";
my @objs=glob("$current*.data");
#@objs=`ls -1 -t *$current*.data`;
if(@objs) {
 $current=shift @objs;
#chomp $current;
#print "Found:$current\n";
chdir $pwd;
} else {$current=''}
}
return $current;
}
#------------------------------------------------------------------------------
sub get_projects {
my @projects=($cfg{project});
opendir CWD,'.';
my @dirs= grep -d, readdir CWD;
close CWD;
foreach my $dir (@dirs) {
($dir eq $cfg{project})&&next;
  if(-d "$dir/TEMPLATES"){
push @projects, $dir;
}
}
return [@projects];
}
#------------------------------------------------------------------------------
sub clean_exit {
print "Exit\n";
#close $sock;
open(CFG,">$pwd/.synsim");
foreach my $key (sort keys %cfg){
print CFG "$key $cfg{$key}\n";
}
close CFG;
if($pid ne 'WRONG'){kill 9,$pid; close XEM;};
Gtk->exit( 0 )
#exit(0);
}
