#!/usr/bin/perl

($katalog = $0) =~ s|/[^/]*$||;

# Konwersja any-test wypisuje tylko oznaczenie rozpoznanego standardu zamiast
# konwersji. Konwersja any-test/all wypisuje tabelk wspczynnikw zgodnoci
# z poszczeglnymi zestawami.
if ($ARGV[0] eq "-test") {shift @ARGV; $test = 1;}

# Szukamy jzyka w argumentach i pliku z jego opisem:
foreach (split " ", $ENV{ARG})
{
	if ($test && $_ eq "all") {$test = 2}
	elsif (!$jest && open JEZYK, "$katalog/../aux/any/$_") {$jest = 1}
}
# Jeli nie znalelimy jzyka, to przepuszczamy tekst bez zmian:
unless ($jest)
{
	if ($test == 1)
	{
		print "-\n";
	}
	elsif ($test == 2)
	{
		print "Unknown or unspecified language\n";
	}
	else
	{
		print while <>;
	}
	exit;
}

# Odczytujemy dane o zestawach znakw w danym jzyku:
while (<JEZYK>)
{
	chomp;
	@znaki = split;
	$zestaw = shift @znaki;
	# '%' zamiast zestawu oznacza czstoci wystpowania znakw:
	if ($zestaw eq '%') {@czestosci = @znaki}
	else
	{
		push @zestawy, {ZESTAW => $zestaw, ZNAKI => [@znaki]};
		# Znaki zliczamy dwoma sposobami:
		# - Poszczeglne bajty zliczamy tak czy siak, nie patrzc na
		#   to, ktre s akurat potrzebne.
		# - Znaki dusze ni jeden bajt musimy zliczy osobno. Dla
		#   szybkoci zapamitujemy je w osobnych tablicach, wzgldem
		#   pierwszego bajtu.
		foreach (@znaki)
		{
			push @{$dlugie[ord]}, $_ if length > 1
		}
	}
}
close JEZYK;

unless ($test)
{
	# Musimy przelecie tekst dwa razy - raz, eby zliczy znaki, i drugi
	# raz, eby go skonwertowa. Podczas pierwszego przebiegu zapamitujemy
	# wic test w tymczasowym pliku:
	open TEMP, "+>/tmp/any-$$";
	unlink "/tmp/any-$$";
}
# Zliczamy wystpienia poszczeglnych bajtw (w @ile) i znakw duszych ni
# jeden bajt (w %ile):
while (<>)
{
	print TEMP $_ unless $test;
	chomp;
	my $i = 0;
	foreach my $znak (split //)
	{
		$ile[ord $znak]++;
		foreach my $znak (@{$dlugie[ord $znak]})
		{
			$ile{$znak}++ if substr ($_, $i, length $znak) eq $znak;
		}
	} continue {$i++}
}

# Wspczynnikiem zgodnoci dla danego zestawu znakw jest suma iloczynw
# zaobserwowanych liczb wystpie i rednich czstoci dla danego jzyka
# odczytanej z pliku z opisem jzyka:
$najlepiej = 0;
$najlepszy = "-";
foreach (@zestawy)
{
	my $pasuje = 0;
	@znaki = @{$$_{ZNAKI}};
	foreach (@czestosci)
	{
		$znak = shift @znaki;
		$pasuje += (length $znak > 1 ? $ile{$znak} : $ile[ord $znak]) * $_
			if $znak ne "-";
	}
	if ($test == 2) {$$_{PASUJE} = $pasuje}
	if ($pasuje > $najlepiej)
	{
		$najlepiej = $pasuje;
		$najlepszy = $$_{ZESTAW};
	}
}

# Jeli to by test, to tylko wypisujemy informacj:
if ($test == 1)
{
	print "$najlepszy\n";
	exit;
}
elsif ($test == 2)
{
	foreach (sort {$$b{PASUJE} <=> $$a{PASUJE}} @zestawy)
	{
		printf "%10d: %s\n", $$_{PASUJE}, $$_{ZESTAW} if $$_{PASUJE};
	}
	exit;
}

seek TEMP, 0, 0;
# Jeli z adnego zestawu nie pasowa aden znak, to przepuszczamy plik bez
# zmian:
if ($najlepiej == 0) {print while <TEMP>; close TEMP; exit;}

($najlepszy = "|$najlepszy-UTF8") =~ s/\|/|$katalog\//g;
open WYNIK, $najlepszy;
while (<TEMP>) {print WYNIK $_}
close TEMP;
close WYNIK;
