#!/usr/bin/perl -w
# drakfont Future Overview
#         - Fonts import :
#                 pfb ( Adobe Type 1 binary )
#                 pfa ( Adobe Type 1 ASCII )
#                 ttf ( True-Type  )
#                 pcf.gz
#                 Speedo
#                 and Bitmap (PCF, BDF, and SNF)
#         - Features
#                 - Install fonts from any directory
#                 - Get windows fonts on any vfat partitions
#                 - UN-installation of any fonts (even if not installed through drakfont)
#         - Support
#               - Xfs
#               - ghostscript & printer
#               - Staroffice & printer
#               - abiword
#               - Koffice, Gnumeric, ... studying
#               - all fonts supported by printer
#                          ( aliases by RENDER in Xfree86 .... -> later )
# Visual Interface:
#         Window interface:
#           - Fontselectiondialog widget
#           - Command buttons under Fontselectiondialog (like the actual frontend).
#         Commands buttons:
#           - import from windows partition.
#                 import from all fat32 partitions and look for winnt/windows/font
#                 and import all (delete doublon) but don't import if already exist.
#           - import from directory
#                 look for if it exist before for each font and not delete the original.
#                 (replace all, no, none)
#                 expert options:
#                         ask the directory, and look for if it exist before
#                         if it exist ask: (replace all, no, none)
#           - uninstall with list per font type
#         Expert additional switch
#           - option support:   ghostscript, Staroffice, etc...
#                 check-button. (by default all check)
#           - Printer Application Fonts Support...
#                 check-button. (by default all check)

# directory to install fonts /usr/X11R6/lib/X11/fonts/
# -->> /usr/X11R6/lib/X11/fonts/drakfont


use Gtk;
use lib qw(/usr/lib/libDrakX);
use interactive;
use standalone;
use my_gtk qw(:helpers :wrappers);
use common;
use strict;
use MDK::Common::Globals "network", qw($in $prefix $connect_file $disconnect_file $connect_prog);


if ("@ARGV" =~ /--help|-h/) {
    print q(Font Importation and monitoring application
--windows_import : import from all available windows partitions.
--xls_fonts      : show all fonts that already exist from xls
--strong         : strong verification of font.
--install        : accept any font file and any directry.
--uninstall      : uninstall any font or any directory of font.
--replace        : replace all font if already exist
--application    : 0 none application.
                 : 1 all application available supported.
                 : name_of_application like  so for staroffice 
                 : and gs for ghostscript for only this one.
);
    exit(0);
}

#   global variables needed by each functions
my $xlsfonts = 0;
my $windows;
my $strong;
my $replace;
my $application;
my $install;
my $uninstall;
my $so = 1;
my $gs = 1;
my $mode = -1;
my @application;
my @install;
my @uninstall;
my $interactive;

foreach (@ARGV) {
    /--xls_fonts/ and $xlsfonts = 1, $mode=-1;
    /--windows_import|-wi/ and $windows = 1, $mode=-1;
    /--strong|-s/ and $strong = 1, $mode=-1;
    /--replace|-r/ and $replace = 1, $mode=-1;
    /--application/ and $mode = 0, next;
    $mode == 0 and push @application, $_;
    /--install/ and $mode = 1, next;
    $mode == 1 and push @install, $_;
    /--uninstall/ and $mode = 2, next;
    $mode == 2 and push @uninstall, $_;
}



foreach my $i (@application) {
    if ( $i =~ /so/i) {
	if ( $gs != 2 ) { $gs = 0;}
	$so = 2;
    }
    if ($i  =~ /gs/i){ 
	if ( $so != 2 ) { $so = 0; }
	$gs = 2;
    }
}

# only debug
# print "app : @application\n";
# print "install : @install\n";
# print "uninstall : @uninstall\n";
# print "applications supproted: so: $so  gs: $gs \n";


# PATH and binary full path
my $xfs_conffile = '/etc/X11/fs/config';
my $drakfont_dir = '/home/seb/new2_drakfont'; # '/usr/X11R6/lib/X11/fonts/drakfont';
my $ttf2pt1 = '/usr/sbin/ttf2pt1';
my $pfm2afm = '/usr/sbin/pfm2afm';
my $type1inst = '/usr/sbin/type1inst';
my $chkfontpath = '/usr/sbin/chkfontpath';
my $ttmkfdir = '/usr/sbin/ttmkfdir';
my $ghostscript;

# Global lists, just to manipulate it easily.
# my @font_list                    => list of fonts to install.
# my @installed_fonts;             => list of installed fonts.
# my @installed_fonts_path;        => list of path included in xfs.
# my @fontsdir_to_install;         => list of fonts to uninstall.
# my @fontsdir_to_uninstall;       => path to remove in xfs font file.
# my @installed_fonts_full_path;   => full path list of fonts to uninstall.

my @font_list;
my @installed_fonts;
my @installed_fonts_path;
my @fontsdir_to_install;
my @fontsdir_to_uninstall;
my @installed_fonts_full_path;

my $pbar;
my $pbar1;
my $pbar2;
my $pbar3;
my $font_box;
my $central_widget;

sub list_fontpath {
    foreach (grep { /\d+:\s/ } `$chkfontpath -l`) {
	chomp;
	s/\d+:\s//gi;
	s/:\w*$//gi;
	push @installed_fonts_path, $_;
    }
}

sub search_installed_fonts {
    list_fontpath();
    push @installed_fonts, all($_) foreach @installed_fonts_path;
}

sub search_installed_fonts_full_path {
    list_fontpath();
    foreach my $i (@installed_fonts_path) {
	foreach my $j (all($i)) {
	    push @installed_fonts_full_path, "$i/$j";
	}
    }
}

sub search_windows_font {
    foreach my $fstab_line (grep { /vfat/ } cat_('/etc/mtab') ) {
	my $win_dir = (split('\s', $fstab_line))[1];
	my @list_fonts_win = all("$win_dir/windows/fonts");
	my @list_fonts_winnt = all("$win_dir/winnt/fonts");
	my $nb_dir = @list_fonts_win + @list_fonts_winnt;
	if(!@list_fonts_win && !@list_fonts_winnt) {
	    print "drakfont:: could not find any font in $win_dir/win*/fonts \n";
	    $interactive and display_error(_("could not find any font in %s/win*/fonts", $win_dir));
	    return 0;
	}
	foreach $_ ([\@list_fonts_win, "windows"], [\@list_fonts_winnt, "winnt"]) {
	    foreach my $i (@{$_->[0]}) {
		if($interactive) {
		    if($nb_dir) { progress($pbar, 100/$nb_dir) } else {
			display_error(_("no fonts found"));
			return 0;
		    }
		}
		!$replace && grep(/$i/, @installed_fonts) and next;
		grep ( /$i$/, @font_list) or push @font_list, "$win_dir/$_->[1]/fonts/$i";
	    }
	}
    }
    1;
}

sub is_a_font {
    local $_ = $_[0];
    /.ttf$/i || /.pfa$/i || /.pfb$/i || /.pcf$/i || /.pcf.gz$/i || /.pfm$/i || /.gsf$/;
}

sub search_dir_font {
    my ($fn) = @_;
    my @font_list_tmp = ();
    my @font_list_tmpp = ();
    my $dir ;
    if (!(-e $fn )) { print "$_ :: no such file or directory \n" } else {
	if ( -d $fn ) {
	    $dir = $fn;
	    foreach my $i (all($fn)) {
		if (is_a_font($i)) {
		    push @font_list_tmp, "$i";
		    foreach my $i (@font_list_tmp) {
			!$replace && grep(/$i/, @installed_fonts) and next;
			grep /$i/, @font_list or push @font_list, "$fn/$i";
		    }
		}
	    }
	} else {
	    if (is_a_font($fn)) {
		!$replace && grep(/$fn/, @installed_fonts) and next;
		!grep /$fn/, (@installed_fonts) and push @font_list, "$fn";
	    }
	}
	print "Fonts in directory " . $dir . " : " . $_ . "\n" foreach (@font_list_tmp);
    }
    print ".........................................\n\n";
    print "Font to install : " . $_ . "\n" foreach (@font_list);
}

sub search_dir_font_uninstall {
    my @font_list_tmp = ();
    my $fn = $_;
    if ( -d $fn ) { 
	foreach my $i (all($fn)) {
	    if (is_a_font($i)) { push @font_list_tmp, "$i"; }
	}
    }
    else { if (is_a_font($fn)) { push @font_list_tmp, "$fn"; }
       }
    foreach my $i (@installed_fonts_full_path) {
	foreach my $j (@font_list_tmp) {
	    if ( $i =~ /$j/) { push @font_list, "$i" ;}
	}
    }
    print "Fonts to uninstal : " . $_ . "\n" foreach (@font_list);
}

sub print_list { print "Font(s) to Install :\n\n"; print "$_\n" foreach (@font_list) }

sub dir_created {
    -e $drakfont_dir		    || mkdir_p($drakfont_dir);
    -e $drakfont_dir . "/Type1"	    || mkdir_p($drakfont_dir."/Type1"); 
    -e $drakfont_dir . "/ttf"	    || mkdir_p($drakfont_dir."/ttf");
    -e $drakfont_dir . "/tmp"	    || mkdir_p($drakfont_dir."/tmp");
    -e $drakfont_dir . "/tmp/ttf"   || mkdir_p($drakfont_dir."/tmp/ttf");
    -e $drakfont_dir . "/tmp/Type1" || mkdir_p($drakfont_dir."/tmp/Type1");
    -e $drakfont_dir . "/tmp/tmp"   || mkdir_p($drakfont_dir."/tmp/tmp");
}

sub put_font_dir {
  -e "/usr/share/ghostscript" or $gs = 0 && print "ghostscript is not installed on your system...\n"  ;
  if (@font_list) {
    dir_created();
    cp_af(@font_list, $drakfont_dir . "/tmp/tmp");

    system ("cd $drakfont_dir/tmp/tmp   && cp *.ttf ../../ttf");
    system ("cd $drakfont_dir/ttf && $ttmkfdir > fonts.dir" );
    system ("$chkfontpath -a $drakfont_dir/ttf");

    if ($so && $gs)  {
      foreach my $fontname ( glob ("$drakfont_dir/tmp/tmp/*.ttf") ) { 
	system ("cd $drakfont_dir/tmp/tmp && $ttf2pt1 -b $fontname");
      }
      system ("cd  $drakfont_dir/tmp/tmp && mv *.gsf *.pfb *.pfm *.afm ../Type1");
      system ("cd $drakfont_dir/tmp/Type1 && $type1inst" );
      system ("cd $drakfont_dir/tmp/Type1 && cat Fontmap >> `rpm -ql ghostscript | grep Fontmap.GS` " );
      system ("cd $drakfont_dir/tmp/Type1 && mv *.pfm *.gsf *.afm *.pfb ../../Type1 ");
      system ("cd $drakfont_dir/Type1 && $type1inst &&  $chkfontpath -a $drakfont_dir/Type1");
    }
    if (!$so && $gs)  {
      foreach my $fontname ( glob ("$/drakfont_dir/tmp/tmp/*.ttf") ) { 
	system ("cd $/drakfont_dir/tmp/tmp && $ttf2pt1 -b $fontname");
      }
      system ("cd $drakfont_dir/tmp/tmp && mv *.gsf *.pfb *.pfm ../Type1");
      system ("cd $drakfont_dir/tmp/Type1 && $type1inst" );
      system ("cd $drakfont_dir/tmp/Type1 && cat Fontmap >> `rpm -ql ghostscript | grep Fontmap.GS` " );
      system ("cd $drakfont_dir/tmp/Type1 && mv *.pfm *.afm *.gsf *.pfb ../../Type1 ");
      system ("cd $drakfont_dir/Type1 && $type1inst &&  $chkfontpath -a $drakfont_dir/Type1");
    }
    if ($so && !$gs)  {
      foreach my $fontname ( glob ("$drakfont_dir/tmp/tmp/*.ttf") ) { 
	system ("cd $drakfont_dir/tmp/tmp && $ttf2pt1 $fontname");
      }
      foreach my $fontname ( glob ("$drakfont_dir/tmp/tmp/*.pfm") ) { 
	system ("cd $drakfont_dir/tmp/tmp && $pfm2afm $fontname");
      }
      system ("cd $drakfont_dir/tmp/tmp && mv  *.afm ../Type1");
      system ("cd $drakfont_dir/tmp/Type1 && mv *.afm ../../Type1 ");
      system ("cd $drakfont_dir/Type1 && $type1inst &&  $chkfontpath -a $drakfont_dir/Type1");
    }
    rm_rf("$drakfont_dir/tmp/");
    print "\n\nretarting xfs......\n";
    system ("/etc/rc.d/init.d/xfs restart");
  }
}

sub remove_gs_fonts {
    my @Fontmap_new;

    if (all("$drakfont_dir/remove"))  {
	system (" cd $drakfont_dir/remove && $type1inst");
	my @Fontmap_out = cat_("$drakfont_dir/remove/Fontmap");
	my $FontmapGS = `rpm -ql ghostscript | grep Fontmap.GS`;
	chomp ($FontmapGS);
	my @FontmapGS_list = cat_($FontmapGS);
	foreach my $font_gs (@FontmapGS_list) {
	    my @tmp_list = split (' ',$font_gs);
	    grep ( $_ =~ /$tmp_list[0]/ , @Fontmap_out) or  push @Fontmap_new, $font_gs;
	}
	print $_ foreach @Fontmap_new;
	output($FontmapGS, @Fontmap_new );
    }
}

sub remove_fonts {
    my @list_dir;
    my @toto;
    -e $drakfont_dir . "/remove"  || mkdir_p($drakfont_dir . "/remove");
    foreach my $i (@font_list) {
	$_ = $i;
	if ( /.pfb$/ || /.gsf$/ || /.pfm$/ || /.pfa$/ ) {
	    system ("cp $_ $drakfont_dir/remove ");
	} else {
	    rm_rf($i);
	}
	$i =~ s/\/\w*\.\w*//gi;
	grep ( $i, (@list_dir)) or push @list_dir, $i;
    }
    -e "/usr/share/ghostscript" and  remove_gs_fonts();
    foreach my $i (@list_dir) {
	if (listlength all("$i") < 3)  {
	    # remove this directory of the de fontpath
	    system("chkfontpath -r $i") or print "PERL::system command failed during chkfontpath\n";
	} else {
	    #	    # do type1inst in this path
	    system("cd $i && type1inst") or print "PERL::system command failed during cd or type1inst\n";
	}
    }
    system ("/etc/rc.d/init.d/xfs restart");
    -e "/usr/share/ghostscript" and  rm_rf("$drakfont_dir/remove");
}

sub license_msg {
    print _("Before installing any fonts, be sure that you have the right to use and install them on your system.\n\n-You can install the fonts using the normal way. In rare cases, bogus fonts may hang up your X Server.\n-You can install the fonts with strong verification. In this case, bogus fonts won't be installed, but some useable fonts won't be too.\n\nIf you have many fonts, or exotic fonts, I recommend strong verification mode.")."\n";
}

$xlsfonts || $windows || @install || @uninstall ? backend_mod() : interactive_mode();

sub backend_mod {
    if ($xlsfonts) {
	system ("xlsfonts");
    }
    if ($windows) {
	license_msg();
	print "........Windows fonts Installation........\n\n";
	search_installed_fonts();
	if(search_windows_font()) {
	    print_list();
	    put_font_dir();
	}
	print "\n...............The End...................\n";
    }

    if (@install) {
	license_msg();
	print ".......Install Specifics Fonts...........\n\n";
	search_installed_fonts();
	search_dir_font $_ foreach (@install);
	print ".................................................\n\n";
	print "Font to install : " . $_ . "\n" foreach (@font_list);
	put_font_dir();
	print "\n...............The End...................\n";
    }

    if (@uninstall) {
	license_msg();
	print "........Uninstall Specifics Fonts........\n\n";
	search_installed_fonts_full_path();
	search_dir_font_uninstall $_ foreach (@uninstall);
	remove_fonts();
	print "\n...............The End...................\n";
    }
}

#######################################  INTERACTIVE ######################################################################



my $check4;
my $check1;
my $check2;
my $check3;

sub create_fontsel {
    my $font_sel;
    gtkpack($font_box,
	    $font_sel = new Gtk::FontSelection,
	   );
    $central_widget = \$font_sel;
}

sub display_error {
    my $message = @_;
    ${$central_widget}->destroy();
    gtkpack($font_box, $message);
}

sub interactive_mode {
    my $font_sel;
    $interactive = 1;

    init Gtk;


    my $window1 = $::isEmbedded ? new Gtk::Plug ($::XID) : new Gtk::Window -toplevel;
    $window1->signal_connect (delete_event => sub { Gtk->exit(0) });
    $window1->set_position(1);
    $window1->set_title(_("Fonts Importation"));
    $window1->set_border_width(5);

    gtkadd($window1,
	   gtkpack_(new Gtk::HBox(0,2),
		    1, gtkpack_(new Gtk::VBox(0,0),
				1, new Gtk::VBox(0,0),
				1, gtkpack($font_box = new Gtk::VBox(0,5),
					   $font_sel = new Gtk::FontSelection,
					  ),
				1, new Gtk::VBox(0,0)
			       ),
		    0, gtkpack_(new Gtk::VBox(0,5),
				0, _("DrakFont"),
				0, gtkadd(gtkset_layout(new Gtk::VButtonBox, -end),
					  gtksignal_connect(new Gtk::Button(_("Windows Importation")), clicked 	=>
							    sub { gtkdestroy($central_widget); $windows = 1; license() }),
					  gtksignal_connect(new Gtk::Button(_("Advanced Importation")), clicked =>
							    sub {  }),
					  gtksignal_connect(new Gtk::Button(_("Uninstall Fonts")), clicked => sub { Gtk->main_quit() }),
					 ),
				1, new Gtk::VBox(0,0),
				0, gtkadd(gtkset_layout(new Gtk::VButtonBox, -end),
					  gtksignal_connect(new Gtk::Button(_("Help")), clicked => sub { print _("Help\n") }),
					  gtksignal_connect(new Gtk::Button(_("Close")), clicked => sub { Gtk->main_quit() }),
					 ),
			       )
		   ),
	  );
    $central_widget = $font_sel;
    $window1->show_all;
    $window1->realize;
    $window1->show_all();
    #}
    # import_status();
    #main_gi;
    Gtk->main;
    Gtk->exit(0);
}


my $text;
my $vscrollbar;


#	    $vscrollbar = new Gtk::VScrollbar( $text->vadj ),

sub license {
    my $text = new Gtk::Text(undef, undef);
    my $license_box;
    gtkpack($font_box,
	    $license_box = gtkpack_(new Gtk::VBox(0,0),
	       1, gtkpack_(new Gtk::HBox(0,0),
			   1, gtktext_insert(gtkset_editable($text, 1), "Before installing any fonts, be sure that you have the right to use and install them on your system.\n\n-You can install the fonts using the normal way. In rare cases, bogus fonts may hang up your X Server.\n-You can install the fonts with strong verification. In this case, bogus fonts won't be installed, but some useable fonts won't be too.\n\nIf you have many fonts, or exotic fonts, I recommend strong verification mode."),
			   0, new Gtk::VScrollbar($text->vadj),
			  ),
	       0, gtkadd(gtkset_layout(new Gtk::HButtonBox, -end),
			 gtksignal_connect(new Gtk::Button(_("OK")), clicked => sub { ${$central_widget}->destroy(); import_status() }),
			 gtksignal_connect(new Gtk::Button(_("Cancel")), clicked => sub { ${$central_widget}->destroy(); create_fontsel() }),
			),
				      )
	   );
    $central_widget = \$license_box;
    $font_box->show_all();
}
	    

#	    my $text = new Gtk::Text;


#	    $text->set_editable( 0 ),
#	    my $vscrollbar = new Gtk::VScrollbar( $text->$vadj );
#	    my $hbox->pack_start( $vscrollbar, 0, 0, 0 );
#	    $vscrollbar->show();

#    $wtext->can_focus($has_scroll);
#    chomp(my $text = join("\n", @_));
#    my $scroll = createScrolledWindow(gtktext_insert($wtext, $text));
#    $scroll->set_usize(400, $height);
#    gtkpack__($o->{box}, $scroll);


#	_("Before installing any fonts, be sure that you have the right to use and install them on your system.\n\n-You can install the fonts using the normal way. In rare cases, bogus fonts may hang up your X Server.\n-You can install the fonts with strong verification. In this case, bogus fonts won't be installed, but some useable fonts won't be too.\n\nIf you have many fonts, or exotic fonts, I recommend strong verification mode."),
	    


sub import_status {
    my $adj = new Gtk::Adjustment( 0, 1, 100, 0, 0, 0 );
    my $adj1 = new Gtk::Adjustment( 0, 1, 100, 0, 0, 0 );
    my $adj2 = new Gtk::Adjustment( 0, 1, 100, 0, 0, 0 );
    my $adj3 = new Gtk::Adjustment( 0, 1, 100, 0, 0, 0 );
    my $table;
    gtkpack($font_box,
	    $table = create_packtable({ col_spacings => 30, row_spacings => 20},
   if_($windows, [_("Search Fonts on your System"), $pbar = new_with_adjustment Gtk::ProgressBar($adj), gtkset_sensitive($check1 = new Gtk::CheckButton(), 0)]),
   ["Supress Doublons ", $pbar1 = new_with_adjustment Gtk::ProgressBar($adj1), gtkset_sensitive($check2 = new Gtk::CheckButton(), 0)],
   ["Install Fonts ", $pbar2 = new_with_adjustment Gtk::ProgressBar($adj2), gtkset_sensitive($check3 = new Gtk::CheckButton(), 0)],
   ["Post Install Fonts ", $pbar3 = new_with_adjustment Gtk::ProgressBar($adj3), gtkset_sensitive($check4 = new Gtk::CheckButton(), 0)],
			    ),
	   );
    $central_widget = \$table;
#    $font_box->show_all();
#    my $timer  = Gtk->timeout_add(  5, \&progress_timeout );
#    my $timer1 = Gtk->timeout_add( 10, \&progress_timeout1 );
#    my $timer2 = Gtk->timeout_add( 15, \&progress_timeout2 );
#    my $timer3 = Gtk->timeout_add( 20, \&progress_timeout3 );
    backend_mod();
}

sub progress {
    my ($bar, $incr) = @_;
    my $new_val;
    my $adjt;
    $new_val = $pbar->get_value() + $incr;
    $adjt = $bar->adjustment;
    $bar->set_value( $new_val );
    $new_val < 100 || gtkset_active($check1 , 1);
    $new_val < 100 ;
}


#1, gtksignal_connect(my $button_connect = gtkset_sensitive(new Gtk::Button(), 0), clicked => \&connection),



# interface graphique a faire
# option strong: verifier strong  ttmkfdir -c ???
# gestion abiword, netscape, gimp....
# xlsfonts | less pour verifier l'installation des polices.