#!/usr/bin/env perl

require 5.8.0;
use strict;

my $esc = ' &"\'';

our $modules;
BEGIN
{ 
	select STDIN;
	$| = 1;
	select STDOUT;
	$| = 1;
 $modules = __FILE__;
	$modules = '.' if ($modules !~ /\//);
 $modules =~ s/\/[^\/]*$//gos;
 eval "use lib qw($modules/.);";
}
use lib qw(.);
use localization::localization;
use Foundation;

print "\n";
if (scalar(@ARGV) != 1 && scalar(@ARGV) != 2 && scalar(@ARGV) != 3)
{
	my $verPath = $0;
	$verPath =~ s/\/[^\/]*$//gos;
	$verPath .= '/version';
	$verPath =~ s/([$esc])/\\$1/gos;
	my $ver = `cat $verPath`;
	$ver =~ s/\s+$//gos;
	print _L("(c) MiF, MDict dictionary packer version %#\n\n",$ver);
	print _L("Usage: %# <dictionaryFolder> [<outputDirectory>]\n",$0);
	print _L("\n<dictionaryFolder> - dictionary path\n");
	print _L("<outputDirectory> - optional - output directory\n");
	print _L("\nExample: %# ./Unpacked\\ Dictionaries/en-fr-simple\n",$0);
	print "\n";
	exit(1);
}

my $silent = $ARGV[2];
$silent ||= 0;
$silent = ($silent =~ /^silent$/i) ? 1 : 0;

my $dName = $ARGV[0];
my $oDir = defined $ARGV[1] ? $ARGV[1] : $dName;
$oDir =~ s/\/+$//s;
my $lastPathComponent = $dName;
$lastPathComponent =~ s/^.*\///gos;
if ($dName =~ /^\.+$/ || !$lastPathComponent || $lastPathComponent =~ /^\.+$/)
{
	print _L("Can't parse properly dictionary path\n");
	exit(2);
}
my ($DICT,$IDX,$EXT,$log) = ("$oDir/$lastPathComponent.dict","$oDir/$lastPathComponent.idx","$oDir/$lastPathComponent.ext","$oDir/pack.log");
print _L("Processing dictionary %# at directory '%#'\n",$lastPathComponent,$dName);
print _L("Outupt files:\n '%#' &\n '%#'\n",$DICT,$IDX);

if (-f $DICT || -f $IDX || -d $EXT)
{
	local $| = 1;
	print _L("Output dictionary files already exists. Remove now [N/yes]? ");
	my $answer = <STDIN>;
	$answer =~ s/\s+$//gos;
	if ($answer !~ /^yes$/i)
	{
		print _L("User canceled (you must type YES to continue)...\n");
		exit(3);
	}
}

my $sDIR = $dName . "/Words";
my $eDIR = $dName . "/Extensions";
my $rDIR = $dName . "/Replacements";
my ($ok,$word,$file,$content,$len);
my $offset = 0;
local * F;
local * DICT;
local * IDX;
local * LOG;
unless (open(LOG,">$log"))
{
	print _L("Can't open log file %# for writing.\n",$log);
	exit(20);
}
unless (open(DICT,">$DICT"))
{
	print _L("Can't open dictionary %# for writing.\n",$DICT);
	exit(21);
}
unless (open(IDX,">$IDX"))
{
	print _L("Can't open index for %# writing.\n",$IDX);
	exit(22);
}
binmode(DICT);
binmode(IDX);
undef $/;
my $count = 0;
local * DIRH;
if (! -d $sDIR )
{
	print _L("Directory not found '%#'\n",$sDIR);
	exit(4);
}
$ok = 1;
opendir(DIRH,"$sDIR") or $ok = 0;
if (!$ok)
{
	print _L("Can't read directory '%#'\n",$sDIR);
	exit(5);
}
my ($ta,$tb);
my @files = readdir(DIRH);

my $fm = NSFileManager->defaultManager();

my %aliases;
if (-d $rDIR)
{
	print _L("Resolving replacements (aliases)\n");
	my ($i,$count) = (0,scalar(@files));
	for ( ; $i < $count; $i++)
	{
	 next if ($files[$i] =~ /^\.{1,2}$/ || $files[$i] eq '.DS_Store');
		my $afile = "$rDIR/$files[$i]";
		if (-f $afile)
		{
			my $safile = $afile;
			$safile =~ s/([$esc])/\\$1/gos;
			my $als = `cat $safile`;
			$als =~ s/\s+$//gos;
			$aliases{$files[$i]} = $fm->fileSystemRepresentationWithPath_(NSString->stringWithUTF8String_($als));
		}
	}
}
closedir(DIRH);
print _L("Processing dictionary...\n");
@files = sort 
{
	if (exists $aliases{$a})
	{
		$ta = $aliases{$a};
	}
	else
	{
		$ta = $a;
		$ta =~ s/(-\d+)?(\.[\w\d]+)?$//gos; 
	}
	if (exists $aliases{$b})
	{
	 $tb = $aliases{$b};
	}
	else
	{
		$tb = $b; 
		$tb =~ s/(-\d+)?(\.[\w\d]+)?$//gos; 
	}
	my $res = lc $ta cmp lc $tb;
	$res = $ta cmp $tb unless ($res);
	$res;
} @files;
foreach $file (@files)
{
	next if (! -f "$sDIR/$file");
	next if ($file =~ /^\.{1,2}$/ || $file eq '.DS_Store');
	if (exists $aliases{$file})
	{
		$word = $aliases{$file};
	}
	else
	{
		$word =  $file;
		$word =~ s/(-\d+)?(\.[\w\d]+)?$//gos;
	}
	print LOG "$word\n";
	$ok = 1;
	open(F,"<$sDIR/$file") or $ok = 0;
	if ($ok)
	{
		binmode(F);
		$content = <F>;
		print DICT "$content";
		print IDX "$word\0";
		print IDX pack('N',$offset);
		$len = length($content);
		print IDX pack('N',$len);
		$offset += $len;
		close(F);
		$count++;
	}
	else
	{
		print _L("File %# not opened for reading.\n","$sDIR/$file");
	}
}
close(DICT);
close(IDX);
close(LOG);
print _L("Done.\nWords processed: %#\n",$count);
if (-d $eDIR && $EXT)
{
	print _L("Multimedia content detected\n");
	print _L("Copying\n '%#' to\n '%#'\n",$eDIR,$EXT);
	$eDIR =~ s/([$esc])/\\$1/gos;
	$EXT =~ s/([$esc])/\\$1/gos;
	system("rm -rf $EXT; cp -r $eDIR $EXT");
}
$oDir =~ s/([$esc])/\\$1/gos;
print _L("Done\n");
system("open $oDir") unless ($silent);

