/usr/local/CPAN/MusicRoom/MusicRoom/STN.pm


# STN a package for handling numbers represented as 
# strings of characters

package MusicRoom::STN;
use strict;
use warnings;

use Carp;

my %stn_digit;
my @stn_digit = ("0","1","2","3","4","5","6","7","8","9",
                  "a","b","c","e","f","g","h","j","k","m",
                  "n","p","q","r","s","t","u","v","w","x",
                  "y","z");

for(my $i=0;$i<=$#stn_digit;$i++)
  {
    $stn_digit{$stn_digit[$i]} = $i;
  }

sub to_num
  {
    my($stn) = @_;

    _init_stn() if(!%stn_digit);
    return 0 if($stn eq "");

    my $digit = $stn_digit{substr($stn,-1)};
    my $rest = stn2num(substr($stn,0,-1));
    return $digit + ($#stn_digit+1)*$rest;
  }

sub num_to
  {
    my($num,$width) = @_;
    _init_stn() if(!%stn_digit);

    my $ret = "";

    for(my $c=0;$c<$width;$c++)
      {
        $ret = $stn_digit[$num % ($#stn_digit+1)] . $ret;
        $num = int($num/($#stn_digit+1));
      }

    return $ret;
  }

sub unique
  {
    # Pick a suitable random id for an item that does not 
    # clash with any already being used
    my($hr,$width) = @_;

    _init_stn() if(!%stn_digit);
    my $range = ($#stn_digit+1)**$width;
    my $ret = "";
    my $max_tries = 1024;
    while($ret eq "" && $max_tries > 0)
      {
        my $val = "";
        for(my$i=0;$i<$width;$i++)
          {
            $val .= $stn_digit[rand($#stn_digit+1)];
          }

        $max_tries--;
        $ret = $val;
        $ret = ""
           if(defined $hr && defined $hr->{$ret});
      }

    if($max_tries <= 0)
      {
        carp("Too many failures in stn_rand");
      }
    return $ret;
  }

1;