#! /usr/local/bin/perl -w

# Convert a decimal number (integer or number of euros) to its literal
# expression in French (or, with the -o option, Swiss French).

use strict;
use warnings;
use Getopt::Std;

my %opts;
getopts("oe", \%opts);

my @units = ( "z\x{E9}ro", "un", "deux", "trois", "quatre",
	      "cinq", "six", "sept", "huit", "neuf" );
my @teens = ( "dix", "onze", "douze", "treize", "quatorze",
	      "quinze", "seize", "dix-sept", "dix-huit", "dix-neuf" );
my @tens = ( "", "dix", "vingt", "trente", "quarante",
	     "cinquante", "soixante", "septante", "huitante", "nonante" );

sub name100 {
    use integer;
    my $n = shift;
    my $oldstyle = shift;
    die "Bad input to name100" unless $n >= 0 && $n < 100 && $n == ($n/10)*10+($n%10);
    if ( $n < 10 ) {
	return $units[$n];
    } elsif ( $n < 20 ) {
	return $teens[$n%10];
    } elsif ( $oldstyle || $n < 70 ) {
	my $s = $tens[$n/10];
	if ( $n%10 == 1 ) {
	    $s .= " et ".$units[$n%10];
	} elsif ( $n%10 >= 2 ) {
	    $s .= "-".$units[$n%10];
	}
	return $s;
    } elsif ( $n < 80 ) {
	my $s = $tens[6];
	if ( $n%10 == 1 ) {
	    $s .= " et ".$teens[$n%10];
	} else {
	    $s .= "-".$teens[$n%10];
	}
	return $s;
    } else {
	my $s = "quatre-vingt";
	if ( $n%20 == 0 ) {
	    $s .= "s";
	} elsif ( $n%20 < 10 ) {
	    $s .= "-".$units[$n%10];
	} else {
	    $s .= "-".$teens[$n%10];
	}
	return $s;
    }
}

sub name1000 {
    use integer;
    my $n = shift;
    my $oldstyle = shift;
    die "Bad input to name1000" unless $n >= 0 && $n < 1000 && $n == ($n/100)*100+($n%100);
    if ( $n < 100 ) {
	return name100($n,$oldstyle);
    } elsif ( $n < 200 ) {
	my $s = "cent";
	$s .= " ".name100($n%100,$oldstyle) if $n%100;
	return $s;
    } else {
	my $s = $units[$n/100] . " cent";
	if ( $n%100 == 0 ) {
	    $s .= "s";
	} else {
	    $s .= " ".name100($n%100,$oldstyle);
	}
	return $s;
    }
}

sub namemillion {
    use integer;
    my $n = shift;
    my $oldstyle = shift;
    die "Bad input to namemillion" unless $n >= 0 && $n < 1000000 && $n == ($n/1000)*1000+($n%1000);
    if ( $n < 1000 ) {
	return name1000($n,$oldstyle);
    } elsif ( $n < 2000 ) {
	my $s = "mille";
	$s .= " et" if $n%1000 == 1;
	$s .= " ".name1000($n%1000,$oldstyle) if $n%1000;
	return $s;
    } else {
	my $s = name1000($n/1000,$oldstyle) . " mille";
	$s .= " ".name1000($n%1000,$oldstyle) if $n%1000;
	return $s;
    }
}

sub namebillion {
    use integer;
    my $n = shift;
    my $oldstyle = shift;
    die "Bad input to namebillion" unless $n >= 0 && $n < 1000000000 && $n == ($n/1000000)*1000000+($n%1000000);
    if ( $n < 1000000 ) {
	return namemillion($n,$oldstyle);
    } else {
	my $s = name1000($n/1000000,$oldstyle) . " million";
	$s .= "s" if $n/1000000 >= 2;
	$s .= " ".namemillion($n%1000000,$oldstyle) if $n%1000000;
	return $s;
    }
}

sub nameeuros {
    my $v = shift;
    my $oldstyle = shift;
    die "Bad input to nameeuros" unless $v >= 0 && $v < 1000000000;
    my $eur = int($v);
    my $frc = int(100*($v-$eur)+0.5);
    if ( $frc == 100 ) {
	$eur++;
	$frc = 0;
    }
    my $s = "";
    if ( $eur || ! $frc ) {
	$s = namebillion($eur,$oldstyle);
	$s .= " ";
	$s .= "d'" if $eur%1000000 == 0 && $eur > 0;
	$s .= "euro";
	$s .= "s" unless $eur == 1;
    }
    if ( $frc ) {
	$s .= " et " if $eur;
	$s .= name100($frc,$oldstyle);
	$s .= " ";
	$s .= "centime";
	$s .= "s" unless $frc == 1;
    }
    return $s;
}

my $oldstyle = $opts{o};
my $euros = $opts{e};
binmode STDOUT, ":utf8";
while ( <> ) {
    chop;
    if ( $euros ) {
	printf "%s\n", nameeuros($_, $oldstyle);
    } else {
	printf "%s\n", namebillion($_, $oldstyle);
    }
}
