# -*- Mode: perl; tab-width: 4; indent-tabs-mode: nil; -*-
#
# Numbering: The Hebrew Traditional Numbering system,
#            without support for Geresh/Gershayim.
#
# Copyright (c) 2002 by Ian Hickson
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package hebrew;
use strict;
use decimal;

my %digits = (
              100 => [0x05E7],
              10 => [0x05D9],
              1 => [0x05D0],
              200 => [0x05E8],
              20 => [0x05DB],
              2 => [0x05D1],
              300 => [0x05E9],
              30 => [0x05DC],
              3 => [0x05D2],
              400 => [0x05EA],
              40 => [0x05DE],
              4 => [0x05D3],
              500 => [0x05EA, 0x05E7],
              50 => [0x05E0],
              5 => [0x05D4],
              600 => [0x05EA, 0x05E8],
              60 => [0x05E1],
              6 => [0x05D5],
              700 => [0x05EA, 0x05E9],
              70 => [0x05E2],
              7 => [0x05D6],
              800 => [0x05EA, 0x05EA],
              80 => [0x05E4],
              8 => [0x05D7],
              900 => [0x05EA, 0x05EA, 0x05E7],
              90 => [0x05E6],
              9 => [0x05D8],
              );

sub convertToCodepoints {
    my $number = shift;
    if ($number < 0) {
        return decimal::convertToCodepoints($number);
    }
    if ($number == 0) {
        return (0x05D0, 0x05E4, 0x05E1); # zero
    }
    my $regexp = '(.?.?.)';
    if (length($number) > 3) {
        $regexp .= '(...)' x int((length($number)-1) / 3);
    }
    my @groups = map { { 'number' => $_, 'digits' => [] } } ($number =~ m/^$regexp$/s);
    my $lastGroup = undef;
    my $remainingGroups = @groups;
    foreach my $group (@groups) {
        if ($group->{'number'} != 0) {
            my ($hundreds, $tens, $units) = $group->{'number'} =~ m/(?:(.?)(.))?(.)$/os;
            if ($hundreds) { $hundreds *= 100; } else { $hundreds = 0; }
            if ($tens) { $tens *= 10; } else { $tens = 0; }
            if ($units) { $units *= 1; } else { $units = 0; }
            if ($tens == 10 and $3 == 5) {
                $tens = 9;
                $units = 6;
            } elsif ($tens == 10 and $3 == 6) {
                $tens = 9;
                $units = 7;
            }
            push(@{$group->{'digits'}}, @{$digits{$hundreds}}) if $hundreds;
            push(@{$group->{'digits'}}, @{$digits{$tens}}) if $tens;
            push(@{$group->{'digits'}}, @{$digits{$units}}) if $units;           
        } elsif (not defined($lastGroup) or
                 $lastGroup->{'number'} != 0) {
            # zero
            my $notFirst = 0;
            my $addFinal = 1;
            for (1..$remainingGroups) {
                if ($notFirst) {
                    push(@{$group->{'digits'}}, 0x0020);
                } else {
                    $notFirst = 1;
                    if ($lastGroup->{'number'} == 1) {
                        $lastGroup->{'digits'} = [];
                        push(@{$group->{'digits'}}, 0x05D0, 0x05DC, 0x05E3);
                        $addFinal = 0;
                        next;
                    } elsif ($lastGroup->{'number'} == 2 and
                             $remainingGroups == 1) {
                        $lastGroup->{'digits'} = [];
                        push(@{$group->{'digits'}}, 0x05D0, 0x05DC, 0x05E4, 0x05D9, 0x05D9, 0x05DD);
                        $addFinal = 0;
                        next;
                    }
                }
                push(@{$group->{'digits'}}, 0x05D0, 0x05DC, 0x05E4, 0x05D9);
                $addFinal = 1;
            }
            if ($addFinal) {
                push(@{$group->{'digits'}}, 0x05DD);
            }
        }
        $lastGroup = $group;
        $remainingGroups--;
    }
    my @digits;
    foreach my $group (@groups) {
        if (@{$group->{'digits'}}) {
            push(@digits, 0x0020);
            push(@digits, @{$group->{'digits'}});
        }
    }
    shift @digits;
    return @digits;
}

1;
