#!/usr/bin/perl -w
#
# Simple Tk script to create a button that prints "Hello, world".  Click on 
# the button to terminate the program.
# 
# The first line below imports the Tk objects into the application, the second
# line creates the main window, the third through sixth lines create the button
# and defines the code to execute when the button is pressed, the seventh line
# asks the packer to shrink-wrap the application's main window around the
# button, and the eight line starts the event loop.

use Tk;
use Tk::FileDialog;
use DTM::Catalog;
use DTM::Snippet;
use DTM::Type1Utils;
use DTM::Utils;
use strict;


my $main;
my $lists;
my ($list,$list_scroll,$list_box,$list_label);
my ($flist,$flist_scroll,$flist_box,$flist_label,$flist_sel);
my ($buttons,$quitb, $delb, $addb);

my %snip_names;
my $catalog;
my $path = $ENV{HOME};
my $catalog_path;

sub change_path {
    my $ask = shift;
    
    if ($ask) {
	my $dialog = $main->FileDialog(-Title => 'Select a path',
				       -Create => 0,
				       -SelDir => 1,
				       -Path => $path);
	my $tmppath = $dialog->Show;
	$path = ($tmppath eq "" ? $path : $tmppath);
    }

    chdir $path;
    my @files = glob("*.pf?");
    $flist_box->delete(0, $flist_box->size-1);
    $flist_box->insert(0, sort @files);
}


my $OK;
sub add_font {

    # first i get the names from the listbox
    my @indices = $flist_box->curselection();
    my @labels = ('Name',
		  'Foundry',
		  'Typeface',
		  'Weight',
		  'Width',
		  'Slantness',
		  'Variant',
		  'PS Name',
		  'X11 Name');
    my $top = $main->Toplevel();
    my (@txt, @lab, $ok);

    # builds widgets
    for my $i (0..8) {
	$lab[$i] = $top->Label(-text => "$labels[$i]:");
	$txt[$i] = $top->Entry(-width => 80);
	$lab[$i]->grid(-row => $i, -column => 0);
	$txt[$i]->grid(-column => 1, -row => $i);
     }
    $ok = $top->Button(-text => 'Install the font',
		       -command => sub {$OK = 1});
    $ok->grid(-row => 9, -column => 1);

    foreach my $idx (@indices) {
	# builds type1 snippet
	my $file = $flist_box->get($idx);
	my $snip = build_type1snippet($path, $file);
	
	foreach my $i (0..6) {
	    $txt[$i]->delete(0,'end');
	    $txt[$i]->insert(0, $snip->get_attr($labels[$i]));
	}
	$txt[7]->delete(0,'end');
	$txt[8]->delete(0,'end');
	$txt[7]->insert(0, $snip->get_attr('Name', 'psspecific'));
	$txt[8]->insert(0, $snip->get_attr('Name', 'x11specific'));

	$OK = 0;
	$top->waitVariable(\$OK);

	# updates and install snippet
	foreach my $i (0..6) {
	    $snip->set_attr($labels[$i], $txt[$i]->get());
	}
	$snip->set_attr('Name', $txt[7]->get(), 'psspecific');
	$snip->set_attr('Name', $txt[8]->get(), 'x11specific');
	$snip->set_attrs(undef,
			 FontFile => $file,
			 FontPath => $catalog_path);

	$OK = 0;
	my $thetext;
	my $msg = $main->Toplevel(-width => 600);
	my $out = $msg->Message(-textvariable => \$thetext,
				-width => 600);
	my $oki = $msg->Button(-text => 'OK',
			      -command => sub {$OK = 1});
	$out->pack(-side => 'top');
	$oki->pack(-side => 'top');

	# copy the font
	safe_system("cp $path/$file $catalog_path/$file");
	safe_system("chmod 644 $catalog_path/$file");
	if ($catalog->add($snip) == 0) {
	    $thetext = $catalog->error();
	} 
	else {
	    $thetext = "Font installed";
	}
	update_catalog();
	$msg->waitVariable(\$OK);
	$msg->destroy();
    }

    $top->destroy();
    $catalog->save();
}


sub del_font {

    # first i get the names from the listbox
    my @indices = $list_box->curselection();
    
    # then I simply get the right snippets and I
    # remove the fonts 
    my $thetext;
    my $top = $main->Toplevel(-width => 600);
    my $out = $top->Message(-textvariable => \$thetext,
			    -width => 600);
    my $ok = $top->Button(-text => 'OK',
			  -command => [$top => 'destroy']);
    my @removed;
    $out->pack(-side => 'top');
    $ok->pack(-side => 'top');
    foreach my $i (@indices) {
	my $name = $list_box->get($i);
	my $snip = $catalog->find($snip_names{$name});
	$thetext .= "Removing font `$name' ... ";
	$out->update;
	$catalog->remove($snip);
	my $err = $catalog->error();
	safe_system("rm -f $path/" . $snip->get_attr('FontFile'))
	    unless $snip->get_attr('Alias');; 
	if ($err eq "") {
	    $thetext .= "done\n";
	    @removed = (@removed, $i);
	}
	else {
	    $thetext .= "error!\n    $err\n";
	}
    }
    # updates the listbox, etc...
    foreach my $i (@removed) {
	$list_box->delete($i);
    }
    $out->update();
    $catalog->save();
}


sub quit {
    exit;
}


sub update_catalog {
    foreach my $snip ($catalog->filter()) {
	$snip_names{$snip->get_attr('Name')} = $snip->get_attr('ID');
    }
    $list_box->delete(0, 'end');
    $list_box->insert(0, sort keys %snip_names);
}


$main = MainWindow->new;
#$lists = $main->Frame(-relief => 'flat');

# font list
$list = $main->Frame(-relief => 'flat');
$list_box = $list->Listbox(-width => 30,
			   -selectmode => 'extended');
$list_scroll = $list->Scrollbar(-command, ['yview', $list_box]);
$list_label = $list->Label(-text => 'Installed fonts');
$list_box->configure(-yscrollcommand => ['set', $list_scroll]);
#packs
$list_label->pack(-side => 'top');
$list_box->pack(-side => 'left', -fill => 'both');
$list_scroll->pack(-side => 'right', -fill => 'y');

# file list
$flist = $main->Frame(-relief => 'flat');
$flist_box = $flist->Listbox(-width => 30,
			     -selectmode => 'extended');
$flist_scroll = $flist->Scrollbar(-command, ['yview', $flist_box]);
$flist_label = $flist->Label(-text => 'Available font files');
$flist_box->configure(-yscrollcommand => ['set', $flist_scroll]);
$flist_sel = $flist->Button(-text => 'Select path...',
			    -command => [\&change_path => 1]);
#packs
$flist_sel->pack(-side => 'bottom', -fill => 'x');
$flist_label->pack(-side => 'top');
$flist_box->pack(-side => 'left', -fill => 'both');
$flist_scroll->pack(-side => 'right', -fill => 'y');


# action buttons
$buttons = $main->Frame(-relief => 'flat');

$addb = $buttons->Button(-command => \&add_font,
			 -width => 12,
			 -text => 'Add file(s)...');

$delb = $buttons->Button(-command => \&del_font,
			 -width => 12,
			 -text => 'Remove font(s)');

$quitb = $buttons->Button(-command => \&quit,
			  -width => 12,
			  -text => 'Quit');

$addb->pack(-side => 'left');
$delb->pack(-side => 'left');
$quitb->pack(-side => 'left');

# places the widgets
#$lists->pack(-side => 'top', -fill => 'both');
$buttons->pack(-side => 'bottom', -anchor => 'e');
$list->pack(-side => 'left', -fill => 'both');
$flist->pack(-side => 'left', -fill => 'both');


# options pretty bad done at now
if ($> == 0) {
    $catalog_path = '/usr/share/fonts/type1/outlines';
    $catalog = DTM::Catalog::sys_catalog('type1');
}
else {
    $catalog_path = "$ENV{HOME}/fonts/type1/outlines";
    if ($ARGV[0] and $ARGV[0] eq '-l') {
	$catalog = DTM::Catalog::user_catalog('type1', 
					      "$ENV{HOME}/fonts/methods");
	shift @ARGV;
    }
    else {
	$catalog = DTM::Catalog::user_catalog('type1');
    }

    # creates some std dirs
    safe_system("install -d $ENV{HOME}/fonts/catalogs") 
	if !(-d "$ENV{HOME}/fonts/catalogs");
    safe_system("install -d $ENV{HOME}/fonts/methods") 
	if !(-d "$ENV{HOME}/fonts/methods");
    safe_system("install -d $ENV{HOME}/fonts/type1/outlines")
	if !(-d "$ENV{HOME}/fonts/type1/outlines");
}


$path = $ARGV[0] if $ARGV[0];
change_path();
update_catalog();

MainLoop;
