#!/usr/bin/perl -w

use strict;
use File::Temp qw/ tempfile /;

my $DictRegEx = '^[a-z][a-z]_[A-Z][A-Z]\.dic$';
my $AffRegEx  = '^[a-z][a-z]_[A-Z][A-Z]\.aff$';
my $HyphRegEx = '^hyph_[a-z][a-z].*\.dic$';
my $ThesRegEx = '^th_[a-z][a-z]_[A-Z][A-Z]\.dat$';

my $Debug = $ENV{'OOO_DEBUG'};
my $OOO_DIR = '/usr/lib/ooo-1.1';

if ($Debug && $OOO_DIR =~ /^\@/) {
    $OOO_DIR = '/usr/lib/ooo-1.1.0';
}

my $option = shift (@ARGV);
my $FILENAME = shift (@ARGV);

my $SHARED_DICT_DIR = "/usr/share/myspell/";
my $DICT_DIR = $OOO_DIR . "/share/dict/ooo/";
my $DICT_FILENAME = $DICT_DIR . "dictionary.lst";

sub get_dict_files($)
{
    my $path = shift;
    my $dirhandle;
    my $fname;
    my @files = ();

    opendir ($dirhandle, $path) || die "can't opendir $path: $!";
    while ($fname = readdir ($dirhandle)) {
	if ($fname =~ m/$DictRegEx/ ||
	    $fname =~ m/$AffRegEx/  ||
	    $fname =~ m/$HyphRegEx/ ||
	    $fname =~ m/$ThesRegEx/) {
	    push @files, $fname;
	}
    }
    closedir ($dirhandle);

    return @files;
}

sub remove_unused_symlinks {
    my $path = shift;
    my $dirhandle;
    my $fname;

    opendir ($dirhandle, $path) || die "can't opendir $path: $!";
    while ($fname = readdir ($dirhandle)) {
	unless (-r "$path/$fname") {
	    unlink "$path/$fname" || die "can't unlink $path/$fname: $!";
	}
    }
    closedir ($dirhandle);
}

sub link_shared_dict_files {
  my ($shared_dict_dir, $dict_dir) = @_;
  return unless -d $shared_dict_dir;
  my @shared_files=get_dict_files ("$shared_dict_dir");
  
  foreach my $file (@shared_files) {
    unless (-r "$dict_dir/$file") {
      symlink ("$shared_dict_dir/$file", "$dict_dir/$file") || die "can't crate symlink $dict_dir/$file -> $shared_dict_dir/$file: $!";
    }
  }
}

remove_unused_symlinks ($DICT_DIR);
link_shared_dict_files ($SHARED_DICT_DIR, $DICT_DIR);

my $file;
my @files = get_dict_files ($DICT_DIR);
my $CONFIG_FILE;

open ($CONFIG_FILE, ">$DICT_FILENAME") || die "Can't open $DICT_FILENAME: $!\n";

for $file (@files) {
    install ($file);
}

close ($CONFIG_FILE);

sub filetype {
    my ($filename) = @_;

    if ($filename =~ m/$DictRegEx/) {
	return "DICT";
    } elsif ($filename =~ m/$AffRegEx/) {
	return "AFF";
    } elsif ($filename =~ m/$HyphRegEx/) {
	return "HYPH";
    } elsif ($filename =~ m/$ThesRegEx/) {
	return "THES";
    } else {
	print "\"$filename\" does not look like a dictionary, hyphenation table, or thesaurus file\n"
	    . "Dictionaries are of the form xx_YY.dic\n"
	    . "Hyphenation tables are of the form hyph_xx_YY.dic\n"
	    . "Thesauruses are of the form th_xx_YY.dat\n";
	exit (1);
    }
}

sub change_extension {
    my ($filename, $ext, $newext) = @_;

    $filename =~ s/^(.*)\.($ext)$/$1\.$newext/g;
    return $filename;
}

sub get_dict_list_entry {
    my ($filename) = @_;

    $filename =~ m/^([a-z][a-z])_([A-Z][A-Z])/;

    my $language = $1;
    my $country = $2;
    my $file_prefix = $1 . "_" . $2;

    return ($language, $country, $file_prefix);
}

sub lookup_default_country {
    my $lang = shift;
    
    if ($lang eq 'en') {
	return 'US';
    } elsif ($lang eq 'da') {
	return 'DK';
    } else {
	return uc ($lang);
    }
}

sub get_hyph_list_entry {
    my ($filename) = @_;

    $filename =~ s/^hyph_([a-z][a-z])//;

    my $language = $1;
    my $country;
    my $suffix = '';

    if ($filename =~ m/_([A-Z][A-Z])/) {
	$country = $1;
	$suffix = "_" . $country;
    } else {
	$country = lookup_default_country ($language);
    }

    my $file_prefix = "hyph_" . $language . $suffix;

    return ($language, $country, $file_prefix);
}

sub get_thes_list_entry {
    my ($filename) = @_;

    $filename =~ m/^th_([a-z][a-z])_([A-Z][A-Z])/;

    my $language = $1;
    my $country = $2;
    my $file_prefix = "th_" . $1 . "_" . $2;

    return ($language, $country, $file_prefix);
}

sub install {
    my $type;
    my $language;
    my $country;
    my $file_prefix;
    my $filename = shift;

    $type = filetype ($filename);

    if ($type eq "DICT") {
	my $dict_file = $DICT_DIR . $filename;
	my $affix_file = $DICT_DIR . change_extension ($filename, "dic", "aff");

	if (!-f $dict_file || !-f $affix_file) {
	    print "Error: These files must be present:\n"
		. $dict_file . "\n"
		. $affix_file . "\n";
	    exit (1);
	}

	($language, $country, $file_prefix) = get_dict_list_entry ($filename);
    } elsif ($type eq "AFF") {
	# nothing to do
	return;
    } elsif ($type eq "HYPH") {
	my $hyph_file = $DICT_DIR . $filename;

	if (!-f $hyph_file) {
	    print ("Error: $hyph_file is not present\n");
	    exit (1);
	}

	($language, $country, $file_prefix) = get_hyph_list_entry ($filename);
    } elsif ($type eq "THES") {
	my $thes_file = $DICT_DIR . $filename;
	my $idx_file = $DICT_DIR . change_extension ($filename, "dat", "idx");

	if (!-f $thes_file || !-f $idx_file) {
	    print "Error: These files must be present:\n"
		. $thes_file . "\n"
		. $idx_file . "\n";
	    exit (1);
	}

	($language, $country, $file_prefix) = get_thes_list_entry ($filename);
    }

    print $CONFIG_FILE "$type $language $country $file_prefix\n";
}
