#!/usr/bin/perl -w
require 5.6.0;
use utf8;

=head1 Japanese hiragana trainer

This program is a little trainer for Japanese Hiragana characters.
It needs a display that understands UTF-8 output (e.g. the xterm included
in XFree86 4.x, or Emacs shell-mode with the unicode package).

You will probably need such a display to view the source code, too.

=head2 The exercises

In each exercise, you are expected to give an answer. If you give an empty answer,
the exercise will terminate.

=cut

# hiragana tables
%平仮名_char = (
		a =>'あ',i =>'い',u =>'う',e =>'え',o =>'お',
		ka =>'か',ki =>'き',ku =>'く',ke =>'け',ko =>'こ',
		 ga =>'が',gi =>'ぎ',gu =>'ぐ',ge =>'げ',go =>'ご',
		sa =>'さ',si =>'し',su =>'す',se =>'せ',so =>'そ',
		 za =>'ざ',zi =>'じ',zu =>'ず',ze =>'ぜ',zo =>'ぞ',
		ta =>'た',ti =>'ち',tu =>'つ',te =>'て',to =>'と',
		 da =>'だ',di =>'ぢ',du =>'づ',de =>'で',do =>'ど',
		na =>'な',ni =>'に',nu =>'ぬ',ne =>'ね',no =>'の',
		ha =>'は',hi =>'ひ',hu =>'ふ',he =>'へ',ho =>'ほ',
		 ba =>'ば',bi =>'び',bu =>'ぶ',be =>'べ',bo =>'ぼ',
		 pa =>'ぱ',pi =>'ぴ',pu =>'ぷ',pe =>'ぺ',po =>'ぽ',
		ma =>'ま',mi =>'み',mu =>'む',me =>'め',mo =>'も',
		ya =>'や',yu =>'ゆ',yo =>'よ',
		ra =>'ら',ri =>'り',ru =>'る',re =>'れ',ro =>'ろ',
		wa =>'わ',wo =>'を',
		n =>'ん',
	       );

%ろまじ_norm = (
		shi=>'si',
		ji=>'zi',
		chi=>'ti',tsu=>'tu',
		fu=>'hu',
	       );

# normalizes a romanization
sub norm {
  return $ろまじ_norm{$_[0]} if exists $ろまじ_norm{$_[0]};
  return $_[0];
}

# compares two romanizations (OK, just test for true or false, order is the wrong one)
sub rom_cmp {
  my ($a,$b)=@_;
  return norm($a) cmp norm($b);
}

=head2 The first exercise

The first exercise shows a hiragana, and asks the user to write its pronunciation.
It recognizes some romanizations, such as 'chi' for 'ti'. However, you should insert
the Kunrei romanization ('ti', 'si', and so on).

When you make a mistake, it shows you the correct pronunciation, and the hiragana corrisponding
to what you wrote (if any).

=cut

# exercise 1: show a kana, ask for the pronunciation
sub ex1 {
  my @仮名=keys %平仮名_char;
  my $i;my $res;my $old_flush=$|;

  $|=1;

  while (1) {
    $i=int rand @仮名;
    print "How do you pronounce $平仮名_char{$仮名[$i]}? ";
    $res=<STDIN>;chomp $res;
    if (!$res) {last}
    if (!rom_cmp $res,$仮名[$i]) {
      print "Right!\n\n";
    } else {
      print "Wrong, it is '$仮名[$i]'";
      if (exists $平仮名_char{norm $res}) {
	print ", $res is $平仮名_char{norm $res}\n\n";
      } else {
	print ", $res doesn't exist\n\n";
      }
    }
  }
  print "\n";
  $|=$old_flush;
}

=head2 The second exercise

The second exercise shows a pronunciation (Kunrei system) and C<$ANSWERS>
(usually 5) choices of hiragana.

When you make a mistake, it shows you the correct writing, and the pronunciation
of the one you chose.

=cut

# exercise 2: show a pronunciation, ask which kana is the correct one
sub ex2 {
  my $ANSWERS=5;
  my @仮名=keys %平仮名_char;
  my ($i,$j,$k);my $res;
  my @ans;

  while (1) {
    $i=int rand @仮名;
    print "How do you write $仮名[$i]?\n";
    @ans=();
    for ($j=0;$j<$ANSWERS;$j++) {
      $k=-1;
      while ($k<0 || $k==$i) {
	$k=int rand @仮名;
	for (@ans) {if ($_ == $k) {$k=-1;last}}
      }
      push @ans,$k;
    }
    $ans[int rand $ANSWERS]=$i;
    $j=1;for (@ans) { print "$j: $平仮名_char{$仮名[$_]} ";$j++ };print "\n";
    $res=0;
    while (($res<1) or ($res>$ANSWERS)) {
      $res=<STDIN>;chomp $res;
      if (!$res) {last}
      if (($res<1) or ($res>$ANSWERS)) {print "Answer with a number between 1 and $ANSWERS\n"}
    }
    if (!$res) {last}
    if ($ans[$res-1] == $i) {
      print "Right!\n\n";
    } else {
      print "Wrong, it is $平仮名_char{$仮名[$i]}, $平仮名_char{$仮名[$ans[$res-1]]} is $仮名[$ans[$res-1]].\n\n";
    }
  }
}

=head2 Command-line

C<-1> will run only the first exercise.
C<-2> will run only the second exercise.
Default is to run them is sequence.

=cut

ex1() unless $ARGV[0] && $ARGV[0] eq '-2';
ex2() unless $ARGV[0] && $ARGV[0] eq '-1';
